/*
* Copyright (c) 2015 EMC Corporation
* All Rights Reserved
*/
package controllers.compute;
import static com.emc.vipr.client.core.util.ResourceUtils.uri;
import static com.emc.vipr.client.core.util.ResourceUtils.uris;
import static controllers.Common.backToReferrer;
import static controllers.Common.flashException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import models.ComputeImageServerListTypes;
import models.ComputeSystemTypes;
import models.RegistrationStatus;
import models.SearchScopes;
import models.VlanListTypes;
import models.datatable.ComputeImageServersDataTable.ComputeImageServerInfo;
import models.datatable.ComputeSystemElementDataTable;
import models.datatable.ComputeSystemElementDataTable.ComputeElementInfo;
import models.datatable.ComputeSystemsDataTable;
import models.datatable.ComputeSystemsDataTable.ComputeSystemsInfo;
import org.apache.commons.lang.StringUtils;
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.ComputeImageServerUtils;
import util.ComputeSystemUtils;
import util.DefaultComputeSystemPortMap;
import util.EnumOption;
import util.MessagesUtils;
import util.StringOption;
import util.datatable.DataTablesSupport;
import util.validation.HostNameOrIpAddressCheck;
import com.emc.storageos.model.compute.ComputeElementRestRep;
import com.emc.storageos.model.compute.ComputeImageServerRestRep;
import com.emc.storageos.model.compute.ComputeSystemCreate;
import com.emc.storageos.model.compute.ComputeSystemRestRep;
import com.emc.storageos.model.compute.ComputeSystemUpdate;
import com.emc.vipr.client.Task;
import com.google.common.collect.Lists;
import controllers.Common;
import controllers.deadbolt.Restrict;
import controllers.deadbolt.Restrictions;
import controllers.util.FlashException;
import controllers.util.ViprResourceController;
@With(Common.class)
@Restrictions({ @Restrict("SYSTEM_ADMIN"), @Restrict("RESTRICTED_SYSTEM_ADMIN") })
public class ComputeSystems extends ViprResourceController {
protected static final String SAVED = "ComputeSystems.saved";
protected static final String UNKNOWN = "ComputeSystems.unknown";
protected static final String MODEL_NAME = "ComputeSystems";
protected static final String DELETED_SUCCESS = "ComputeSystems.deleted.success";
protected static final String DELETED_ERROR = "ComputeSystems.deleted.error";
protected static final String AVAILABLE = "AVAILABLE";
//
// Add reference data so that they can be reference in html template
//
private static void addReferenceData() {
renderArgs.put("computeSystemTypeList",
ComputeSystemTypes.options(ComputeSystemTypes.VALUES));
renderArgs.put("searchScopeTypeList", SearchScopes.options(
SearchScopes.ONELEVEL, SearchScopes.SUBTREE));
List<EnumOption> defaultComputeSystemPortMap = Arrays.asList(EnumOption.options(DefaultComputeSystemPortMap.values()));
renderArgs.put("defaultComputeSystemPortMap", defaultComputeSystemPortMap);
}
public static void list() {
renderArgs.put("dataTable", new ComputeSystemsDataTable());
render();
}
public static void listElements(String computeSystemId) {
ComputeSystemRestRep computeSystem = ComputeSystemUtils
.getComputeSystem(computeSystemId);
ComputeSystemElementDataTable dataTable = new ComputeSystemElementDataTable();
render("@listElements", computeSystem, dataTable);
}
public static void listJson() {
performListJson(ComputeSystemUtils.getComputeSystems(),
new JsonItemOperation());
}
public static void itemsJson(@As(",") String[] ids) {
itemsJson(uris(ids));
}
private static void itemsJson(List<URI> ids) {
performItemsJson(ComputeSystemUtils.getComputeSystems(ids),
new JsonItemOperation());
}
public static void itemDetails(String id) {
ComputeSystemRestRep computeSystem = ComputeSystemUtils
.getComputeSystem(id);
if (computeSystem == null) {
error(MessagesUtils.get(UNKNOWN, id));
}
render(computeSystem);
}
public static void elementDetails(String id) {
ComputeElementRestRep computeElement = ComputeSystemUtils
.getComputeElement(id);
if (computeElement == null) {
error(MessagesUtils.get(UNKNOWN, id));
}
render(computeElement);
}
public static void create() {
addReferenceData();
ComputeSystemForm computeSystems = new ComputeSystemForm();
// put all "initial create only" defaults here rather than field
// initializers
List<ComputeImageServerRestRep> computeImageServersList = ComputeImageServerUtils.getComputeImageServers();
if (computeImageServersList != null) {
List<StringOption> computeImageServerOptions = new ArrayList<StringOption>();
List<String> computeImageServersArrayList = new ArrayList<String>();
computeImageServerOptions.add(ComputeImageServerListTypes.option(ComputeImageServerListTypes.NO_COMPUTE_IMAGE_SERVER_NONE));
for (ComputeImageServerRestRep cisrr : computeImageServersList) {
if (cisrr.getComputeImageServerStatus().equalsIgnoreCase(AVAILABLE)) {
computeImageServersArrayList.add(cisrr.getName());
}
}
for (String imageServerId : computeImageServersArrayList) {
computeImageServerOptions.add(ComputeImageServerListTypes.option(imageServerId));
}
renderArgs.put("availableComputeImageServersList", computeImageServerOptions);
}
computeSystems.portNumber = getDefaultPort(DefaultComputeSystemPortMap.port443);
computeSystems.useSSL = true;
render("@edit", computeSystems);
}
public static void edit(String id) {
try {
addReferenceData();
ComputeSystemRestRep computeSystem = ComputeSystemUtils
.getComputeSystem(id);
if (computeSystem != null) {
if (computeSystem.getVlans() != null) {
List<StringOption> vlanOptions = new ArrayList<StringOption>();
vlanOptions.add(VlanListTypes.option(VlanListTypes.NO_OSINSTALL_NONE));
List<String> vlanList = new ArrayList<String>(Arrays.asList(computeSystem.getVlans().split(",")));
for (String vlan : vlanList) {
vlanOptions.add(VlanListTypes.option(vlan));
}
renderArgs.put("computeSystemVlanList", vlanOptions);
}
List<StringOption> computeImageServerOptions = new ArrayList<StringOption>();
computeImageServerOptions.add(ComputeImageServerListTypes
.option(ComputeImageServerListTypes.NO_COMPUTE_IMAGE_SERVER_NONE));
List<ComputeImageServerRestRep> computeImageServersList = ComputeImageServerUtils.getComputeImageServers();
if (computeImageServersList != null) {
List<String> computeImageServersArrayList = new ArrayList<String>();
for (ComputeImageServerRestRep cisrr : computeImageServersList) {
if (cisrr.getComputeImageServerStatus().equalsIgnoreCase(AVAILABLE)) {
computeImageServersArrayList.add(cisrr.getName());
}
}
for (String imageServerId : computeImageServersArrayList) {
computeImageServerOptions.add(ComputeImageServerListTypes.option(imageServerId));
}
renderArgs.put("availableComputeImageServersList", computeImageServerOptions);
}
ComputeSystemForm computeSystems = new ComputeSystemForm(computeSystem);
render("@edit", computeSystems);
} else {
flash.error(MessagesUtils.get(UNKNOWN, id));
list();
}
} catch (Exception e) {
flashException(e);
list();
}
}
@FlashException(keep = true, referrer = { "create", "edit" })
public static void save(ComputeSystemForm computeSystems) {
computeSystems.validate("computeSystems");
if (Validation.hasErrors()) {
handleError(computeSystems);
}
computeSystems.save();
String name = computeSystems.name;
flash.success(MessagesUtils.get(SAVED, name));
backToReferrer();
list();
}
private static Integer getDefaultPort(DefaultComputeSystemPortMap value) {
String defaultValue = MessagesUtils
.get(DefaultComputeSystemPortMap.class.getSimpleName() + "."
+ value.name());
return Integer.valueOf(StringUtils.defaultIfBlank(defaultValue, "0"));
}
private static void handleError(ComputeSystemForm computeSystems) {
// Clear password/confirm before flashing params
params.remove("computeSystems.password");
params.remove("computeSystems.passwordConfirm");
params.flash();
Validation.keep();
if (computeSystems.isNew()) {
create();
}
else {
edit(computeSystems.id);
}
}
@FlashException("list")
public static void delete(@As(",") String[] ids) {
delete(uris(ids));
}
private static void delete(List<URI> ids) {
performSuccessFail(ids, new DeleteOperation(), DELETED_SUCCESS, DELETED_ERROR);
list();
}
@FlashException("list")
public static void introspect(@As(",") String[] ids) {
introspect(uris(ids));
}
private static void introspect(List<URI> ids) {
performSuccess(ids, new DiscoveryOperation(), DISCOVERY_STARTED);
list();
}
@FlashException("list")
public static void deregisterComputes(@As(",") String[] ids) {
deregisterComputes(uris(ids));
}
private static void deregisterComputes(List<URI> ids) {
performSuccessFail(ids, new DeregisterOperation(), DEREGISTER_SUCCESS,
DEREGISTER_ERROR);
list();
}
@FlashException("list")
public static void registerComputes(@As(",") String[] ids) {
registerComputes(uris(ids));
}
private static void registerComputes(List<URI> ids) {
performSuccessFail(ids, new RegisterOperation(), REGISTER_SUCCESS,
REGISTER_ERROR);
list();
}
@FlashException(referrer = { "listElements" })
public static void deregisterElements(@As(",") String[] ids,
String computeSystemId) {
deregisterElements(uris(ids), computeSystemId);
}
private static void deregisterElements(List<URI> ids, String computeSystemId) {
performSuccessFail(ids, new DeregisterElementOperation(),
DEREGISTER_SUCCESS, DEREGISTER_ERROR);
listElements(computeSystemId);
}
@FlashException(referrer = { "listElements" })
public static void registerElements(@As(",") String[] ids,
String computeSystemId) {
registerElements(uris(ids), computeSystemId);
}
private static void registerElements(List<URI> ids, String computeSystemId) {
performSuccessFail(ids, new RegisterElementOperation(computeSystemId),
REGISTER_SUCCESS, REGISTER_ERROR);
listElements(computeSystemId);
}
public static void elements(String id) {
addReferenceData();
ComputeSystemRestRep computeSystem = ComputeSystemUtils
.getComputeSystem(id);
ComputeSystemElementDataTable dataTable = new ComputeSystemElementDataTable();
render("@listElements", computeSystem, dataTable);
}
public static void computeElementsJson(String id) {
List<ComputeElementInfo> results = Lists.newArrayList();
List<ComputeElementRestRep> computeElements = ComputeSystemUtils
.getComputeElements(id);
String computeSystemName = ComputeSystemUtils.getComputeSystem(id)
.getName();
for (ComputeElementRestRep computeElement : computeElements) {
results.add(new ComputeElementInfo(computeElement,
computeSystemName));
}
renderJSON(DataTablesSupport.createJSON(results, params));
}
public static void computeImageServersJson() {
List<ComputeImageServerInfo> results = Lists.newArrayList();
List<ComputeImageServerRestRep> computeImageServers = ComputeImageServerUtils.getComputeImageServers();
for (ComputeImageServerRestRep computeImageServerRR : computeImageServers) {
ComputeImageServerInfo computeImageServer = new ComputeImageServerInfo(computeImageServerRR);
results.add(computeImageServer);
}
renderJSON(DataTablesSupport.createJSON(results, params));
}
public static class ComputeSystemForm {
public String id;
@MaxSize(128)
@MinSize(2)
@Required
public String name;
@MaxSize(2048)
public String ipAddress;
public Boolean useSSL;
@Required
public Integer portNumber;
public String systemType;
public String osInstallNetwork;
@MaxSize(2048)
@Required
public String userName;
@MaxSize(2048)
public String password = "";// NOSONAR ("Suppressing Sonar violation of Password Hardcoded. Password is not hardcoded here.")
@MaxSize(2048)
public String confirmPassword = "";// NOSONAR ("Suppressing Sonar violation of Password Hardcoded. Password is not hardcoded here.")
public String vlanList;
public List<String> computeImageServerOptions = Lists.newArrayList();;
public String computeImageServer;
public ComputeSystemForm() {
}
public boolean unregistered;
public ComputeSystemForm(ComputeSystemRestRep computeSystem) {
this.id = computeSystem.getId().toString();
this.name = computeSystem.getName();
this.ipAddress = computeSystem.getIpAddress();
this.systemType = computeSystem.getSystemType();
this.useSSL = computeSystem.getUseSSL();
this.portNumber = computeSystem.getPortNumber();
this.osInstallNetwork = computeSystem.getOsInstallNetwork();
this.vlanList = computeSystem.getOsInstallNetwork();
this.userName = computeSystem.getUsername();
this.password = ""; // the platform will never return the real password //NOSONAR
// ("Suppressing Sonar violation of Password Hardcoded. Password is not hardcoded here.")
this.unregistered = RegistrationStatus.isUnregistered(computeSystem.getRegistrationStatus());
if (computeSystem.getComputeImageServer().equalsIgnoreCase("null")) {
this.computeImageServer = ComputeImageServerListTypes.NO_COMPUTE_IMAGE_SERVER_NONE;
} else {
ComputeImageServerRestRep cisrr = ComputeImageServerUtils.getComputeImageServer(computeSystem.getComputeImageServer());
this.computeImageServer = cisrr.getName();
}
}
public boolean isNew() {
return StringUtils.isBlank(this.id);
}
public void validate(String fieldName) {
Validation.valid(fieldName, this);
if (isNew()) {
Validation.required(fieldName + ".ipAddress", this.ipAddress);
Validation.required(fieldName + ".password", this.password);
Validation.required(fieldName + ".confirmPassword",
this.confirmPassword);
if (!HostNameOrIpAddressCheck.isValidIp(ipAddress)) {
Validation.addError(fieldName + ".ipAddress",
MessagesUtils.get("computeSystem.invalid.ipAddress"));
}
}
if (!StringUtils.equals(StringUtils.trim(password),
StringUtils.trim(confirmPassword))) {
Validation
.addError(fieldName + ".confirmPassword", MessagesUtils
.get("computeSystem.confirmPassword.not.match"));
}
if (!StringUtils.isEmpty(osInstallNetwork) && StringUtils.isNumeric(osInstallNetwork)) {
try {
int osInstall = Integer.parseInt(osInstallNetwork);
if (osInstall < 1 || osInstall > 4093) {
Validation.addError(fieldName + ".osInstallNetwork",
MessagesUtils.get("computeSystem.invalid.osInstallNetwork"));
}
} catch (NumberFormatException e) {
Validation.addError(fieldName + ".osInstallNetwork",
MessagesUtils.get("computeSystem.invalid.osInstallNetwork"));
}
} else if (!StringUtils.isEmpty(osInstallNetwork)) {
Validation.addError(fieldName + ".osInstallNetwork",
MessagesUtils.get("computeSystem.invalid.osInstallNetwork"));
}
}
public Task<ComputeSystemRestRep> save() {
if (isNew()) {
return create();
} else {
return update();
}
}
private Task<ComputeSystemRestRep> create() {
ComputeSystemCreate createParam = new ComputeSystemCreate();
createParam.setName(this.name);
createParam.setIpAddress(this.ipAddress);
createParam.setPassword(this.password);
createParam.setPortNumber(this.portNumber);
createParam.setSystemType(this.systemType);
createParam.setUserName(this.userName);
createParam.setUseSSL(this.useSSL);
if (!this.osInstallNetwork.isEmpty()) {
createParam.setOsInstallNetwork(this.osInstallNetwork);
}
if (this.computeImageServer != null) {
if (this.computeImageServer.equalsIgnoreCase(ComputeImageServerListTypes.NO_COMPUTE_IMAGE_SERVER_NONE)) {
URI computeImageServerUrl = null;
try {
computeImageServerUrl = new URI("");
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
createParam.setComputeImageServer(computeImageServerUrl);
} else {
ComputeImageServerRestRep cisrr = ComputeImageServerUtils.getComputeImageServerByName(this.computeImageServer);
createParam.setComputeImageServer(cisrr.getId());
}
}
return ComputeSystemUtils.create(createParam);
}
private Task<ComputeSystemRestRep> update() {
ComputeSystemUpdate updateParam = new ComputeSystemUpdate();
ComputeSystemRestRep origCS = ComputeSystemUtils.getComputeSystem(this.id);
updateParam.setName(this.name);
// password is optional on update - but setting "" to update param gives an error
if (this.password != null && this.password.length() > 0) {
updateParam.setPassword(this.password);
}
updateParam.setPortNumber(this.portNumber);
if (!this.osInstallNetwork.isEmpty()) {
updateParam.setOsInstallNetwork(this.osInstallNetwork);
}
else if (origCS.getOsInstallNetwork() != null) {
updateParam.setOsInstallNetwork(" ");
}
if (this.vlanList != null && !this.vlanList.isEmpty()) {
if (vlanList.equalsIgnoreCase(VlanListTypes.NO_OSINSTALL_NONE)) {
updateParam.setOsInstallNetwork(" ");
}
else {
updateParam.setOsInstallNetwork(this.vlanList);
}
}
if (this.computeImageServer != null) {
if (this.computeImageServer.equalsIgnoreCase(ComputeImageServerListTypes.NO_COMPUTE_IMAGE_SERVER_NONE)) {
URI computeImageServerUrl = null;
try {
computeImageServerUrl = new URI("");
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
updateParam.setComputeImageServer(computeImageServerUrl);
} else {
ComputeImageServerRestRep cisrr = ComputeImageServerUtils.getComputeImageServerByName(this.computeImageServer);
updateParam.setComputeImageServer(cisrr.getId());
}
}
updateParam.setUserName(this.userName);
updateParam.setUseSSL(this.useSSL);
return ComputeSystemUtils.update(id, updateParam);
}
}
protected static class JsonItemOperation implements
ResourceValueOperation<ComputeSystemsInfo, ComputeSystemRestRep> {
@Override
public ComputeSystemsInfo performOperation(
ComputeSystemRestRep computeSystem) throws Exception {
return new ComputeSystemsInfo(computeSystem);
}
}
protected static class DeleteOperation implements ResourceIdOperation<Task<ComputeSystemRestRep>> {
@Override
public Task<ComputeSystemRestRep> performOperation(URI id) throws Exception {
Task<ComputeSystemRestRep> task = ComputeSystemUtils.deactivate(id);
return task;
}
}
protected static class DiscoverOperation implements
ResourceIdOperation<Task<ComputeSystemRestRep>> {
@Override
public Task<ComputeSystemRestRep> performOperation(URI id)
throws Exception {
Task<ComputeSystemRestRep> task = ComputeSystemUtils.discover(id);
return task;
}
}
protected static class DiscoveryOperation implements
ResourceIdOperation<Task<ComputeSystemRestRep>> {
@Override
public Task<ComputeSystemRestRep> performOperation(URI id)
throws Exception {
Task<ComputeSystemRestRep> task = ComputeSystemUtils.discover(id);
return task;
}
}
protected static class DeregisterOperation implements
ResourceIdOperation<ComputeSystemRestRep> {
@Override
public ComputeSystemRestRep performOperation(URI id) throws Exception {
return ComputeSystemUtils.deregister(id);
}
}
protected static class RegisterOperation implements
ResourceIdOperation<ComputeSystemRestRep> {
@Override
public ComputeSystemRestRep performOperation(URI id) throws Exception {
return ComputeSystemUtils.register(id);
}
}
protected static class RediscoverElementOperation implements
ResourceIdOperation<ComputeElementRestRep> {
@Override
public ComputeElementRestRep performOperation(URI id) throws Exception {
return ComputeSystemUtils.rediscoverElement(id);
}
}
protected static class DeregisterElementOperation implements
ResourceIdOperation<ComputeElementRestRep> {
@Override
public ComputeElementRestRep performOperation(URI id) throws Exception {
return ComputeSystemUtils.deregisterElement(id);
}
}
protected static class RegisterElementOperation implements
ResourceIdOperation<ComputeElementRestRep> {
private URI computeSystemId;
public RegisterElementOperation(String computeSystemId) {
this.computeSystemId = uri(computeSystemId);
}
@Override
public ComputeElementRestRep performOperation(URI id) throws Exception {
return ComputeSystemUtils.registerElement(id);
}
}
}