/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package controllers.resources; import static com.emc.sa.util.ResourceType.BUCKET; import static com.emc.vipr.client.core.util.ResourceUtils.uri; import static com.emc.vipr.client.core.util.ResourceUtils.uris; import java.net.URI; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import models.datatable.BucketACLDataTable; import models.datatable.ObjectBucketsDataTable; import org.apache.commons.lang.StringUtils; import play.data.binding.As; import play.data.validation.Required; import play.data.validation.Validation; import play.i18n.Messages; import play.mvc.Util; import play.mvc.With; import util.BourneUtil; import util.MessagesUtils; import util.StringOption; import util.VirtualArrayUtils; import util.VirtualPoolUtils; import util.datatable.DataTablesSupport; import com.emc.sa.util.ResourceType; import com.emc.storageos.model.object.BucketACE; import com.emc.storageos.model.object.BucketACL; import com.emc.storageos.model.object.BucketDeleteParam; import com.emc.storageos.model.object.BucketRestRep; import com.emc.storageos.model.object.ObjectBucketACLUpdateParams; import com.emc.vipr.client.Task; import com.emc.vipr.client.Tasks; import com.emc.vipr.client.ViPRCoreClient; import com.emc.vipr.client.exceptions.ViPRHttpException; import com.google.common.collect.Lists; import controllers.Common; import controllers.util.FlashException; @With(Common.class) public class ObjectBuckets extends ResourceController { private static final String UNKNOWN = "resources.buckets.unknown"; protected static final String DELETED = "resources.buckets.acl.deleted"; protected static final String ADDED = "resources.buckets.acl.added"; protected static final String USER = "User"; protected static final String GROUP = "Group"; protected static final String CUSTOMGROUP = "Customgroup"; private static ObjectBucketsDataTable objectbucketsDataTable = new ObjectBucketsDataTable(); public static void buckets(String projectId) { setActiveProjectId(projectId); renderArgs.put("dataTable", objectbucketsDataTable); addReferenceData(); render(); } public static void bucketsJson(String projectId) { if (StringUtils.isNotBlank(projectId)) { setActiveProjectId(projectId); } else { projectId = getActiveProjectId(); } List<ObjectBucketsDataTable.Bucket> buckets = ObjectBucketsDataTable.fetch(uri(projectId)); renderJSON(DataTablesSupport.createJSON(buckets, params)); } public static void bucket(String bucketId) { ViPRCoreClient client = BourneUtil.getViprClient(); BucketRestRep bucket = null; if (isBucketId(bucketId)) { try { bucket = client.objectBuckets().get(uri(bucketId)); } catch (ViPRHttpException e) { if (e.getHttpCode() == 404) { flash.error(MessagesUtils.get(UNKNOWN, bucketId)); buckets(null); } throw e; } } if (bucket == null) { notFound(Messages.get("resources.bucket.notfound")); } if (bucket.getVirtualArray() != null) { // NOSONAR // ("Suppressing Sonar violation of Possible null pointer dereference of volume. When volume is null, the previous if condition handles with throw") renderArgs.put("virtualArray", VirtualArrayUtils.getVirtualArrayRef(bucket.getVirtualArray())); } if (bucket.getVirtualPool() != null) { renderArgs.put("virtualPool", VirtualPoolUtils.getObjectVirtualPoolRef(bucket.getVirtualPool())); } Tasks<BucketRestRep> tasksResponse = client.objectBuckets().getTasks(bucket.getId()); List<Task<BucketRestRep>> tasks = tasksResponse.getTasks(); renderArgs.put("tasks", tasks); render(bucket); } @FlashException(referrer = { "bucket" }) public static void deleteBucket(String bucketId, String deleteType) { if (StringUtils.isNotBlank(bucketId)) { ViPRCoreClient client = BourneUtil.getViprClient(); boolean forceDelete = false; Task<BucketRestRep> task = client.objectBuckets().deactivate(uri(bucketId), new BucketDeleteParam(forceDelete, deleteType)); flash.put("info", MessagesUtils.get("resources.bucket.deactivate")); } bucket(bucketId); } @FlashException(value = "buckets") public static void delete(@As(",") String[] ids, String deleteType) { delete(uris(ids), deleteType); } private static void delete(List<URI> ids, String deleteType) { if (ids != null) { ViPRCoreClient client = BourneUtil.getViprClient(); List<Task<BucketRestRep>> tasks = Lists.newArrayList(); for (URI id : ids) { boolean forceDelete = false; Task<BucketRestRep> task = client.objectBuckets().deactivate(id, new BucketDeleteParam(forceDelete, deleteType)); tasks.add(task); } if (!tasks.isEmpty()) { flash.put("info", MessagesUtils.get("resources.buckets.deactivate", tasks.size())); } } buckets(null); } @Util private static boolean isBucketId(String id) { return ResourceType.isType(BUCKET, id); } public static void listBucketACL(String id) { renderArgs.put("dataTable", new BucketACLDataTable()); renderArgs.put("bucketId", uri(id)); ViPRCoreClient client = BourneUtil.getViprClient(); BucketRestRep bucket = client.objectBuckets().get(uri(id)); renderArgs.put("bucketName", bucket.getName()); BucketACLForm bucketACL = new BucketACLForm(); render(bucketACL); } public static void listBucketACLJson(String id) { ViPRCoreClient client = BourneUtil.getViprClient(); List<BucketACE> bucketAcl = client.objectBuckets().getBucketACL(uri(id)); List<BucketACLDataTable.AclInfo> acl = Lists.newArrayList(); for (BucketACE ace : bucketAcl) { String userOrGroupOrCustomgroup = ace.getUser(); String type = USER; if (ace.getGroup() != null && !ace.getGroup().isEmpty()) { type = GROUP; userOrGroupOrCustomgroup = ace.getGroup(); } else if (ace.getCustomGroup() != null && !ace.getCustomGroup().isEmpty()) { type = CUSTOMGROUP; userOrGroupOrCustomgroup = ace.getCustomGroup(); } acl.add(new BucketACLDataTable.AclInfo(userOrGroupOrCustomgroup, type, ace.getPermissions(), id, ace.getDomain())); } renderJSON(DataTablesSupport.createJSON(acl, params)); } /** * This method called When user selects ACLs and hit delete button. * * @param aclURL * URL of the file system share. * @param ids * ids of the selected ACL */ @FlashException(value = "buckets") public static void deleteAcl(String bucketId, @As(",") String[] ids) { BucketACL aclsToDelete = new BucketACL(); List<BucketACE> bucketAcl = Lists.newArrayList(); if (ids != null && ids.length > 0) { for (String id : ids) { String type = BucketACLForm.extractTypeFromId(id); String name = BucketACLForm.extractNameFromId(id); String domain = BucketACLForm.extractDomainFromId(id); BucketACE ace = new BucketACE(); if (GROUP.equalsIgnoreCase(type)) { ace.setGroup(name); } else if (CUSTOMGROUP.equalsIgnoreCase(type)) { ace.setCustomGroup(name); } else { ace.setUser(name); } if (domain != null && !"".equals(domain) && !"null".equals(domain)) { ace.setDomain(domain); } bucketAcl.add(ace); } aclsToDelete.setBucketACL(bucketAcl); ObjectBucketACLUpdateParams input = new ObjectBucketACLUpdateParams(); input.setAclToDelete(aclsToDelete); ViPRCoreClient client = BourneUtil.getViprClient(); client.objectBuckets().updateBucketACL(uri(bucketId), input); } flash.success(MessagesUtils.get(DELETED)); listBucketACL(bucketId); } public static void editBucketAce(@Required String id) { String type = BucketACLForm.extractTypeFromId(id); String name = BucketACLForm.extractNameFromId(id); String domain = BucketACLForm.extractDomainFromId(id); String bucketId = BucketACLForm.extractBucketFromId(id); String permissions = BucketACLForm.extractPermissionsFromId(id); if ("null".equals(domain)) { domain = ""; } BucketACLForm bucketACL = new BucketACLForm(); bucketACL.type = type; bucketACL.domain = domain; bucketACL.name = name; String[] strPerm = permissions.split("\\|"); bucketACL.permissions = new HashSet<String>(Arrays.asList(strPerm)); List<StringOption> permissionOptions = BucketACLForm.getPermissionOptions(); renderArgs.put("permissionOptions", permissionOptions); renderArgs.put("bucketId", bucketId); ViPRCoreClient client = BourneUtil.getViprClient(); BucketRestRep restRep = client.objectBuckets().get(uri(bucketId)); renderArgs.put("bucketName", restRep.getName()); renderArgs.put("TYPE", type.toUpperCase()); render(bucketACL); } @FlashException(keep = true, referrer = { "editBucketAce" }) public static void saveBucketAce(BucketACLForm bucketACL) { String name = params.get("name"); String type = params.get("type"); String domain = params.get("domain"); String bucketId = params.get("bucketId"); Set<String> permissions = bucketACL.permissions; String strPer = ""; for (String permission : permissions) { strPer = strPer + permission + "|"; } if (strPer.length() > 0) { strPer = strPer.substring(0, strPer.length() - 1); } List<BucketACE> acl = Lists.newArrayList(); BucketACE ace = new BucketACE(); BucketACL aclToModify = new BucketACL(); if (GROUP.equalsIgnoreCase(type)) { ace.setGroup(name); } else if (CUSTOMGROUP.equalsIgnoreCase(type)) { ace.setCustomGroup(name); } else { ace.setUser(name); } ace.setPermissions(strPer); if (domain != null && !domain.isEmpty()) { ace.setDomain(domain); } acl.add(ace); aclToModify.setBucketACL(acl); ObjectBucketACLUpdateParams updateParam = new ObjectBucketACLUpdateParams(); updateParam.setAclToModify(aclToModify); ViPRCoreClient client = BourneUtil.getViprClient(); client.objectBuckets().updateBucketACL(uri(bucketId), updateParam); listBucketACL(bucketId); } public static void addBucketAcl(String bucketId, BucketACLForm bucketACL, String formAccessControlList) { if (formAccessControlList == null || formAccessControlList.isEmpty()) { flash.error(MessagesUtils .get("resources.bucket.acl.invalid.settings")); listBucketACL(bucketId); } ObjectBucketACLUpdateParams updateParam = createObjectBucketACLUpdateParams(formAccessControlList); ViPRCoreClient client = BourneUtil.getViprClient(); try { client.objectBuckets().updateBucketACL(uri(bucketId), updateParam); } catch (Exception e) { flash.error(e.getMessage(), null); listBucketACL(bucketId); } flash.success(MessagesUtils.get(ADDED)); listBucketACL(bucketId); } private static ObjectBucketACLUpdateParams createObjectBucketACLUpdateParams(String formData) { String[] uiAcls = formData.split(","); List<BucketACE> aces = Lists.newArrayList(); for (String uiAce : uiAcls) { String[] uiData = uiAce.split("~~~"); String uiType = uiData[0]; String uiName = uiData[1]; String uiDomain = uiData[2]; String uiPermissions = uiData[3]; BucketACE bucketAce = new BucketACE(); if (uiDomain != null && !uiDomain.isEmpty() && !"null".equals(uiDomain)) { bucketAce.setDomain(uiDomain); } if (GROUP.equalsIgnoreCase(uiType.trim())) { bucketAce.setGroup(uiName.trim()); }else if (CUSTOMGROUP.equalsIgnoreCase(uiType.trim())) { bucketAce.setCustomGroup(uiName.trim()); } else { bucketAce.setUser(uiName.trim()); } if (uiPermissions != null && !"".equals(uiPermissions) && !"null".equals(uiPermissions)) { bucketAce.setPermissions(uiPermissions); } aces.add(bucketAce); } BucketACL aclToAdd = new BucketACL(); aclToAdd.setBucketACL(aces); ObjectBucketACLUpdateParams input = new ObjectBucketACLUpdateParams(); input.setAclToAdd(aclToAdd); return input; } /** * This static class holds the form data for the Bucket ACL page. */ public static class BucketACLForm { private static final String ID_DELIMITER = "~~~~"; public String domain; public String id; @Required public String name; @Required public String type = "USER"; @Required public Set<String> permissions; public void validate(String formName) { Validation.valid(formName, this); Validation.required(formName + ".name", name); Validation.required(formName + ".type", type); Validation.required(formName + ".permissions", permissions); if (name == null || "".equals(name)) { Validation.addError(formName + ".name", "resources.filesystem.share.acl.invalid.name"); } } public static String createId(String name, String type, String bucketId, String domain, String permissions) { return name + ID_DELIMITER + type + ID_DELIMITER + bucketId + ID_DELIMITER + domain + ID_DELIMITER + permissions; } public static String extractNameFromId(String id) { if (StringUtils.isNotBlank(id)) { String[] parts = id.split(ID_DELIMITER); if (parts.length == 5) { return parts[0]; } else { return id; } } return null; } public static String extractTypeFromId(String id) { if (StringUtils.isNotBlank(id)) { String[] parts = id.split(ID_DELIMITER); if (parts.length == 5) { return parts[1]; } else { return id; } } return null; } public static String extractBucketFromId(String id) { if (StringUtils.isNotBlank(id)) { String[] parts = id.split(ID_DELIMITER); if (parts.length == 5) { return parts[2]; } else { return id; } } return null; } public static String extractDomainFromId(String id) { if (StringUtils.isNotBlank(id)) { String[] parts = id.split(ID_DELIMITER); if (parts.length == 5) { return parts[3]; } else { return id; } } return null; } public static String extractPermissionsFromId(String id) { if (StringUtils.isNotBlank(id)) { String[] parts = id.split(ID_DELIMITER); if (parts.length == 5) { return parts[4]; } else { return id; } } return null; } public static List<StringOption> getPermissionOptions() { List<StringOption> permissionOptions = Lists.newArrayList(); permissionOptions.add(new StringOption("read", "Read")); permissionOptions.add(new StringOption("write", "Write")); permissionOptions.add(new StringOption("execute", "Execute")); permissionOptions.add(new StringOption("full_control", "Full Control")); permissionOptions.add(new StringOption("delete", "Delete")); permissionOptions.add(new StringOption("none", "None")); permissionOptions.add(new StringOption("privileged_write", "Privileged Write")); permissionOptions.add(new StringOption("read_acl", "Read Acl")); permissionOptions.add(new StringOption("write_acl", "Write Acl")); return permissionOptions; } } }