/** * Copyright (c) 2013 SUSE LLC * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.redhat.rhn.frontend.action.ssm; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringEscapeUtils; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionMessages; import org.apache.struts.action.DynaActionForm; import com.redhat.rhn.common.localization.LocalizationService; import com.redhat.rhn.common.util.DatePicker; import com.redhat.rhn.common.util.StringUtil; import com.redhat.rhn.domain.action.ActionChain; import com.redhat.rhn.domain.action.script.ScriptActionDetails; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.frontend.dto.SystemOverview; import com.redhat.rhn.frontend.struts.ActionChainHelper; import com.redhat.rhn.frontend.struts.RequestContext; import com.redhat.rhn.frontend.struts.RhnAction; import com.redhat.rhn.frontend.struts.RhnHelper; import com.redhat.rhn.frontend.taglibs.list.helper.ListHelper; import com.redhat.rhn.frontend.taglibs.list.helper.Listable; import com.redhat.rhn.manager.action.ActionChainManager; import com.redhat.rhn.manager.action.ActionManager; import com.redhat.rhn.manager.entitlement.EntitlementManager; import com.redhat.rhn.manager.rhnset.RhnSetDecl; import com.redhat.rhn.manager.system.SystemManager; /** * Remote command for the SSM provisioning. * * @author Bo Maryniuk */ public class ProvisioningRemoteCommand extends RhnAction implements Listable<SystemOverview> { private static final String[] FORM_FIELD_IDS = { "uid", "gid", "script_body", }; /** * Form values bean to keep values if form failed. */ public static class FormValues { private String script; private String uid; private String gid; private Long timeout; private String label; /** * Get script body. * @return string Contains script body. */ public String getScript() { return script; } /** * Set script body. * @param formScript Body of the script * @return FormValues returns self. */ public FormValues setScript(String formScript) { this.script = formScript; return this; } /** * Get group id (GID) * @return String Returns group ID. */ public String getGid() { return gid; } /** * Set group ID (GID) * @param formGID GID * @return FormValues returns self. */ public FormValues setGid(String formGID) { this.gid = formGID; return this; } /** * Returns command label. * @return String command label. */ public String getLabel() { return label; } /** * Set command label. * @param formLabel optional label of the command * @return FormValues returns self. */ public FormValues setLabel(String formLabel) { this.label = formLabel; return this; } /** * Get script timeout. * @return Long returns script timeout. */ public Long getTimeout() { return timeout; } /** * Set script timeout. * @param formTimeout timeout in seconds * @return FormValues returns self. */ public FormValues setTimeout(Long formTimeout) { this.timeout = formTimeout; return this; } /** * Get user ID (UID). * @return String get user ID. */ public String getUid() { return uid; } /** * Set user ID (UID). * @param formUID User ID * @return FormValues returns self. */ public FormValues setUid(String formUID) { this.uid = formUID; return this; } } /** * {@inheritDoc} */ @Override public ActionForward execute(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception { RequestContext context = new RequestContext(request); DynaActionForm form = (DynaActionForm) actionForm; ActionErrors errorMessages = new ActionErrors(); ActionMessages infoMessages = new ActionMessages(); FormValues formValues = new FormValues(); if (form.get("submitted") != null) { User user = new RequestContext(request).getCurrentUser(); Date scheduleDate = this.getStrutsDelegate() .readDatePicker(form, "date", DatePicker.YEAR_RANGE_POSITIVE); ActionChain actionChain = ActionChainHelper.readActionChain(form, user); boolean formValid = true; for (String fid : ProvisioningRemoteCommand.FORM_FIELD_IDS) { if (form.getString(fid) == null || form.getString(fid).isEmpty()) { if (formValid) { formValid = false; } errorMessages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(String.format( "ssm.operations.provisioning.remotecommand.form.%s.missing", fid))); } } // Check if script seems legit :) if (formValid) { StringUtil.ScriptCheckResult result = StringUtil.scriptPrematureCheck( form.getString("script_body")); if (result != null) { formValid = false; errorMessages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(result.getMessageKey())); } } if (formValid) { ScriptActionDetails scriptActionDetails = ActionManager.createScript( form.getString("uid"), form.getString("gid"), form.get("timeout") == null ? 300 : (Long) form.get("timeout"), form.getString("script_body").trim()); List<SystemOverview> servers = getResult(context); List<Long> serverIds = new ArrayList<Long>(); for (SystemOverview system : servers) { serverIds.add(system.getId()); } String label = StringUtil.nullIfEmpty(form.getString("lbl")); label = label != null ? label.trim() : this.generateLabel(servers, request.getLocale(), form.getString("script_body")); ActionChainManager.scheduleScriptRuns(user, serverIds, label, scriptActionDetails, scheduleDate, actionChain); if (actionChain == null) { infoMessages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage( "ssm.operations.provisioning.remotecommand.form.schedule.succeed", label, LocalizationService.getInstance().formatDate(scheduleDate))); } else { infoMessages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage( "ssm.operations.provisioning.remotecommand.form.queue.succeed", label, actionChain.getLabel())); } } else { formValues.setUid(form.getString("uid")) .setGid(form.getString("gid")) .setTimeout((Long) form.get("timeout")) .setLabel(form.getString("lbl")) .setScript(form.getString("script_body")); } form.getMap().clear(); } request.setAttribute("fv", formValues); request.setAttribute( "date", this.getStrutsDelegate().prepopulateDatePicker( request, form, "date", DatePicker.YEAR_RANGE_POSITIVE)); ActionChainHelper.prepopulateActionChains(request); ListHelper helper = new ListHelper(this, request); helper.setListName("systemList"); helper.setDataSetName(RequestContext.PAGE_LIST); helper.execute(); // Add messages to the screen this.getStrutsDelegate().saveMessages(request, errorMessages); this.getStrutsDelegate().saveMessages(request, infoMessages); return mapping.findForward(RhnHelper.DEFAULT_FORWARD); } /** * Generate label for the task. * * @param servers * @param locale * @return */ private String generateLabel(List<SystemOverview> servers, Locale locale, String script) { String body = LocalizationService.getInstance().getMessage( "ssm.operations.provisioning.remotecommand" + ".form.script_label.title.default.body"); String sngl = LocalizationService.getInstance().getMessage( "ssm.operations.provisioning.remotecommand" + ".form.script_label.title.default.client_single"); String plrl = LocalizationService.getInstance().getMessage( "ssm.operations.provisioning.remotecommand" + ".form.script_label.title.default.client_plural"); String[] scriptShellTokens = script.trim().split("\n").clone()[0].split("/"); String scriptType = scriptShellTokens[scriptShellTokens.length - 1]; scriptType = scriptType.length() > 1 ? (scriptType.substring(0, 1).toUpperCase() + scriptType.substring(1).toLowerCase()) : scriptType.toUpperCase(); StringBuilder summary = new StringBuilder(); for (int i = 0; i < servers.size(); i++) { if (i > 0) { summary.append(" "); } if (i < 4) { summary.append(servers.get(i).getName()); } else { break; } } if (servers.size() > 3) { summary.append("..."); } return MessageFormat.format(body, scriptType, servers.size(), servers.size() > 1 ? plrl : sngl, StringEscapeUtils.escapeXml(summary.toString())); } /** * {@inheritDoc} */ public List<SystemOverview> getResult(RequestContext context) { List<SystemOverview> dataset = new ArrayList<SystemOverview>(); List<SystemOverview> sysOvr = SystemManager.inSet(context.getCurrentUser(), RhnSetDecl.SYSTEMS.getLabel(), true); for (int i = 0; i < sysOvr.size(); i++) { if (SystemManager.hasEntitlement(sysOvr.get(i).getId(), EntitlementManager.MANAGEMENT) && SystemManager.clientCapable(sysOvr.get(i).getId(), "script.run")) { dataset.add(sysOvr.get(i)); } } context.getRequest().setAttribute("affectedSystemsCount", dataset.size()); return dataset; } }