/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package controllers.infra; import static com.emc.vipr.client.core.util.ResourceUtils.refIds; import static com.emc.vipr.client.core.util.ResourceUtils.uri; import static com.emc.vipr.client.core.util.ResourceUtils.uris; import java.io.ByteArrayInputStream; import java.io.File; import java.io.UnsupportedEncodingException; import java.net.URI; import java.util.Arrays; import java.util.List; import models.datatable.VirtualDataCentersDataTable; import models.datatable.VirtualDataCentersDataTable.VirtualDataCenter; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import play.cache.Cache; import play.data.binding.As; import play.data.validation.MaxSize; import play.data.validation.MinSize; import play.data.validation.Required; import play.data.validation.Validation; import play.mvc.With; import util.BourneUtil; import util.MessagesUtils; import util.TaskUtils; import util.VirtualDataCenterUtils; import util.datatable.DataTablesSupport; import util.validation.HostNameOrIpAddress; import util.validation.HostNameOrIpAddressCheck; import com.emc.storageos.model.TaskResourceRep; import com.emc.storageos.model.vdc.VirtualDataCenterAddParam; import com.emc.storageos.model.vdc.VirtualDataCenterModifyParam; import com.emc.storageos.model.vdc.VirtualDataCenterRestRep; import com.emc.storageos.model.vdc.VirtualDataCenterSecretKeyRestRep; import com.emc.vipr.client.Task; import com.emc.vipr.client.Tasks; import com.emc.vipr.model.keystore.CertificateChain; import com.google.common.collect.Lists; import controllers.Common; import controllers.deadbolt.Restrict; import controllers.deadbolt.Restrictions; import controllers.security.Security; import controllers.util.FlashException; import controllers.util.ViprResourceController; @With(Common.class) @Restrictions({ @Restrict("SYSTEM_ADMIN"), @Restrict("SECURITY_ADMIN"), @Restrict("RESTRICTED_SECURITY_ADMIN"), @Restrict("SYSTEM_MONITOR") }) public class VirtualDataCenters extends ViprResourceController { private static final int DATASTORE_NOT_CONFIGURED = 40013; protected static final String UNKNOWN = "vdcs.unknown"; public static void list() { VirtualDataCentersDataTable dataTable = new VirtualDataCentersDataTable(); String secretKey = ""; if (Security.isSecurityAdminOrRestrictedSecurityAdmin()) { secretKey = secretKey(); } String inProgressTask = flash.get("inProgressTask"); // handle page refresh that empties the flash scope if (inProgressTask == null || inProgressTask.isEmpty()) { inProgressTask = getPendingVDCTask(); } Common.angularRenderArgs().put("taskId", inProgressTask); render(dataTable, secretKey); } private static String getPendingVDCTask() { List<URI> viprVDCs = refIds(VirtualDataCenterUtils.list()); for (URI vdc : viprVDCs) { List<TaskResourceRep> tasks = TaskUtils.getTasks(vdc); for (TaskResourceRep task : tasks) { if ("pending".equalsIgnoreCase(task.getState())) { return task.getId().toString(); } } } return null; } @FlashException(value = "list", keep = true) public static void listJson() { List<VirtualDataCenterRestRep> viprVDCs = VirtualDataCenterUtils.listByIds(refIds(VirtualDataCenterUtils.list())); List<VirtualDataCentersDataTable.VirtualDataCenter> vdcs = Lists.newArrayList(); for (VirtualDataCenterRestRep vdc : viprVDCs) { if (Security.isSystemAdminOrRestrictedSystemAdmin() || Security.isSecurityAdminOrRestrictedSecurityAdmin() || Security.isSystemMonitor()) { vdcs.add(new VirtualDataCentersDataTable.VirtualDataCenter(vdc)); } } renderJSON(DataTablesSupport.createJSON(vdcs, params)); } public static void itemsJson(@As(",") String[] ids) { itemsJson(uris(ids)); } public static void itemDetails(String id) { VirtualDataCenterRestRep vdc = VirtualDataCenterUtils.get(id); if (vdc == null) { error(MessagesUtils.get(UNKNOWN, id)); } Tasks<VirtualDataCenterRestRep> vdcTasks = VirtualDataCenterUtils.getTasks(uri(id)); Task<VirtualDataCenterRestRep> latestTask = null; if (vdcTasks != null) { latestTask = vdcTasks.latestFinishedTask(); } render(vdc, latestTask); } private static void itemsJson(List<URI> ids) { performItemsJson(VirtualDataCenterUtils.listByIds(ids), new JsonItemOperation()); } @FlashException(value = "list", keep = true) @Restrictions({ @Restrict("SYSTEM_ADMIN"), @Restrict("SECURITY_ADMIN") }) public static void create() { VirtualDataCenterForm vdc = new VirtualDataCenterForm(); addRenderArgs(); render("@edit", vdc); } private static String secretKey() { String secretKey = null; VirtualDataCenterSecretKeyRestRep keyResp = VirtualDataCenterUtils.getSecretKey(); if (keyResp != null) { secretKey = keyResp.getSecretKey(); } return secretKey; } @FlashException(value = "list", keep = true) @Restrictions({ @Restrict("SYSTEM_ADMIN"), @Restrict("SECURITY_ADMIN"), @Restrict("RESTRICTED_SECURITY_ADMIN") }) public static void edit(String id) { VirtualDataCenterRestRep viprVDC = VirtualDataCenterUtils.get(id); if (viprVDC != null) { VirtualDataCenterForm vdc = new VirtualDataCenterForm().from(viprVDC); addRenderArgs(); render(vdc); } else { flash.error(MessagesUtils.get("vdcs.unknown", id)); list(); } } @FlashException(keep = true, referrer = { "create", "edit" }) @Restrictions({ @Restrict("SYSTEM_ADMIN"), @Restrict("SECURITY_ADMIN"), @Restrict("RESTRICTED_SECURITY_ADMIN") }) public static void save(VirtualDataCenterForm vdc) { vdc.validate("vdc"); if (Validation.hasErrors()) { Common.handleError(); } if (vdc.isNew()) { VirtualDataCenterAddParam vdcToAdd = new VirtualDataCenterAddParam(); vdcToAdd.setName(vdc.name); vdcToAdd.setApiEndpoint(vdc.apiEndpoint); vdcToAdd.setDescription(vdc.description); vdcToAdd.setSecretKey(vdc.secretKey); try { vdcToAdd.setCertificateChain(FileUtils.readFileToString(vdc.certChain)); } catch (Exception e) { flash.error(MessagesUtils.get("vdc.certChain.invalid.error")); Common.handleError(); } Task<VirtualDataCenterRestRep> task = VirtualDataCenterUtils.create(vdcToAdd); flash.put("inProgressTask", task.getTaskResource().getId()); } else { VirtualDataCenterRestRep currentVDC = VirtualDataCenterUtils.get(vdc.id); if (currentVDC != null) { VirtualDataCenterModifyParam vdcToUpdate = new VirtualDataCenterModifyParam(); vdcToUpdate.setName(vdc.name); vdcToUpdate.setDescription(vdc.description); Task<VirtualDataCenterRestRep> task = VirtualDataCenterUtils.update(uri(vdc.id), vdcToUpdate); flash.put("inProgressTask", task.getTaskResource().getId()); } } Cache.delete(Common.VDCS); if (StringUtils.isNotBlank(vdc.referrerUrl)) { redirect(vdc.referrerUrl); } else { list(); } } @FlashException("list") @Restrictions({ @Restrict("SYSTEM_ADMIN"), @Restrict("SECURITY_ADMIN") }) public static void delete(@As(",") String[] ids) { delete(uris(ids)); list(); } private static void delete(List<URI> ids) { if (!ids.isEmpty()) { // UI only support single selection, ignore any additional IDs URI id = ids.get(0); Task<VirtualDataCenterRestRep> task = VirtualDataCenterUtils.delete(id); flash.put("inProgressTask", task.getTaskResource().getId()); Cache.delete(Common.VDCS); } } @FlashException("list") @Restrictions({ @Restrict("SYSTEM_ADMIN"), @Restrict("SECURITY_ADMIN") }) public static void disconnect(@As(",") String[] ids) { disconnect(uris(ids)); list(); } private static void disconnect(List<URI> ids) { if (!ids.isEmpty()) { // UI only support single selection, ignore any additional IDs URI id = ids.get(0); Task<VirtualDataCenterRestRep> task = VirtualDataCenterUtils.disconnect(id); flash.put("inProgressTask", task.getTaskResource().getId()); } } @FlashException("list") @Restrictions({ @Restrict("SYSTEM_ADMIN"), @Restrict("SECURITY_ADMIN") }) public static void reconnect(@As(",") String[] ids) { reconnect(uris(ids)); list(); } private static void reconnect(List<URI> ids) { if (!ids.isEmpty()) { // UI only support single selection, ignore any additional IDs URI id = ids.get(0); Task<VirtualDataCenterRestRep> task = VirtualDataCenterUtils.reconnect(id); flash.put("inProgressTask", task.getTaskResource().getId()); } } public static void downloadCertificateChain() throws UnsupportedEncodingException { CertificateChain cert = BourneUtil.getViprClient().vdc().getCertificateChain(); if (cert == null || cert.getChain() == null || cert.getChain().isEmpty()) { flash.error(MessagesUtils.get("vdc.certChain.empty.error")); } String chain = cert.getChain(); ByteArrayInputStream is = new ByteArrayInputStream(chain.getBytes("UTF-8")); renderBinary(is, "vdc_certificate", "text/plain", false); } private static void addRenderArgs() { } public static class VirtualDataCenterForm { public String id; @Required @MaxSize(128) @MinSize(2) public String name; public String shortId; @HostNameOrIpAddress public String apiEndpoint; public String description; public String secretKey; public String referrerUrl; public boolean local; public boolean rotate; public File certChain; public File certKey; public VirtualDataCenterForm from(VirtualDataCenterRestRep from) { this.id = from.getId().toString(); this.name = from.getName(); this.apiEndpoint = from.getApiEndpoint(); this.description = from.getDescription(); this.shortId = from.getShortId(); this.local = from.isLocal(); return this; } public boolean isNew() { return StringUtils.isBlank(id); } public void validate(String formName) { Validation.valid(formName, this); if (isNew()) { Validation.required(String.format("%s.name", formName), this.name); Validation.required(String.format("%s.description", formName), this.description); Validation.required(String.format("%s.apiEndpoint", formName), this.apiEndpoint); Validation.required(String.format("%s.secretKey", formName), this.secretKey); Validation.required(String.format("%s.certChain", formName), this.certChain); } else { Validation.required(String.format("%s.name", formName), this.name); Validation.required(String.format("%s.description", formName), this.description); } } } private static boolean validateEndpoints(String endpoints) { if (endpoints != null && !endpoints.isEmpty()) { List<String> endpointsToValidate = Arrays.asList(endpoints.split(",")); for (String endpoint : endpointsToValidate) { if (!HostNameOrIpAddressCheck.hasValidPort(endpoint)) { return false; } endpoint = HostNameOrIpAddressCheck.trimPortFromEndpoint(endpoint); if (!HostNameOrIpAddressCheck.isValidHostNameOrIp( StringUtils.deleteWhitespace(endpoint))) { return false; } } } return true; } protected static class JsonItemOperation implements ResourceValueOperation<VirtualDataCenter, VirtualDataCenterRestRep> { @Override public VirtualDataCenter performOperation(VirtualDataCenterRestRep vdc) throws Exception { VirtualDataCenterRestRep vdcRestRep = VirtualDataCenterUtils.get(vdc.getId().toString()); return new VirtualDataCenter(vdcRestRep); } } }