You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2016/05/27 17:45:16 UTC
ambari git commit: AMBARI-16851. Cluster operator and cluster admin
not allowed to install ambari agent (rlevas)
Repository: ambari
Updated Branches:
refs/heads/trunk 4eab7d053 -> 055b63150
AMBARI-16851. Cluster operator and cluster admin not allowed to install ambari agent (rlevas)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/055b6315
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/055b6315
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/055b6315
Branch: refs/heads/trunk
Commit: 055b63150cb934c11986c70850638064103ff7b0
Parents: 4eab7d0
Author: Robert Levas <rl...@hortonworks.com>
Authored: Fri May 27 13:44:56 2016 -0400
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Fri May 27 13:45:03 2016 -0400
----------------------------------------------------------------------
.../internal/RequestResourceProvider.java | 31 ++++++-
.../server/customactions/ActionDefinition.java | 16 +++-
.../customactions/ActionDefinitionManager.java | 37 ++++++++-
.../customactions/ActionDefinitionSpec.java | 10 +++
.../AmbariAuthorizationFilter.java | 87 +++++++++++---------
.../server/upgrade/UpgradeCatalog240.java | 13 +++
.../main/resources/Ambari-DDL-Derby-CREATE.sql | 1 +
.../main/resources/Ambari-DDL-MySQL-CREATE.sql | 1 +
.../main/resources/Ambari-DDL-Oracle-CREATE.sql | 1 +
.../resources/Ambari-DDL-Postgres-CREATE.sql | 1 +
.../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql | 1 +
.../resources/Ambari-DDL-SQLAnywhere-CREATE.sql | 1 +
.../resources/Ambari-DDL-SQLServer-CREATE.sql | 1 +
.../system_action_definitions.xml | 1 +
.../AmbariManagementControllerTest.java | 18 ++--
.../internal/ActionResourceProviderTest.java | 8 +-
.../internal/RequestResourceProviderTest.java | 74 ++++++++++++++---
.../ActionDefinitionManagerTest.java | 29 ++++++-
.../security/TestAuthenticationFactory.java | 57 +++++++++++++
.../server/upgrade/UpgradeCatalog240Test.java | 3 +
.../cust_action_definitions1.xml | 9 ++
21 files changed, 333 insertions(+), 67 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
index 5b318af..d38234f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java
@@ -56,6 +56,7 @@ import org.apache.ambari.server.controller.spi.SystemException;
import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
import org.apache.ambari.server.controller.utilities.PredicateBuilder;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.customactions.ActionDefinition;
import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
import org.apache.ambari.server.orm.dao.HostRoleCommandStatusSummaryDTO;
import org.apache.ambari.server.orm.dao.RequestDAO;
@@ -71,6 +72,7 @@ import org.apache.ambari.server.topology.TopologyManager;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
+import org.apache.commons.lang.StringUtils;
/**
* Resource provider for request resources.
@@ -185,8 +187,33 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider
String clusterName = actionRequest.getClusterName();
if(clusterName == null) {
- // This must be an administrative action?
- // TODO: Perform authorization check for this?
+ String actionName = actionRequest.getActionName();
+
+ // Ensure that the actionName is not null or empty. A null actionName will result in
+ // a NPE at when getting the action definition. The string "_unknown_action_" should not
+ // result in a valid action definition and should be easy to understand in any error message
+ // that gets displayed or logged due to an authorization issue.
+ if(StringUtils.isEmpty(actionName)) {
+ actionName = "_unknown_action_";
+ }
+
+ ActionDefinition actionDefinition = getManagementController().getAmbariMetaInfo().getActionDefinition(actionName);
+ Set<RoleAuthorization> permissions = (actionDefinition == null) ? null : actionDefinition.getPermissions();
+
+ if(permissions == null) {
+ if (!AuthorizationHelper.isAuthorized(ResourceType.AMBARI, null, RoleAuthorization.SERVICE_RUN_CUSTOM_COMMAND)) {
+ throw new AuthorizationException(String.format("The authenticated user is not authorized to execute the '%s'command.", actionName));
+ }
+ }
+ else {
+ // Since we cannot tell whether the action is to be exectued for the system or a
+ // non-disclosed cluster, specify that the resource is a CLUSTER with no resource id.
+ // This should ensure that a user with a role for any cluster with the appropriate
+ // permissions or an Ambari administrator can execute the command.
+ if (!AuthorizationHelper.isAuthorized(ResourceType.CLUSTER, null, permissions)) {
+ throw new AuthorizationException(String.format("The authenticated user is not authorized to execute the '%s'command.", actionName));
+ }
+ }
}
else if(actionRequest.isCommand()) {
if (!AuthorizationHelper.isAuthorized(ResourceType.CLUSTER,
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinition.java
index 1f189a3..02c469f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinition.java
@@ -21,6 +21,9 @@ package org.apache.ambari.server.customactions;
import org.apache.ambari.server.actionmanager.ActionType;
import org.apache.ambari.server.actionmanager.TargetHostType;
import org.apache.ambari.server.controller.ActionResponse;
+import org.apache.ambari.server.security.authorization.RoleAuthorization;
+
+import java.util.Set;
/**
* The resource describing the definition of an action
@@ -34,6 +37,7 @@ public class ActionDefinition {
private String description;
private TargetHostType targetType;
private Short defaultTimeout;
+ private Set<RoleAuthorization> permissions;
/**
* Create an instance of ActionDefinition
@@ -46,10 +50,11 @@ public class ActionDefinition {
* @param description Short description of the action
* @param targetType Selection criteria for target hosts
* @param defaultTimeout The timeout value for this action when executed
+ * @param permissions A set of permissions to use when verifiying authorization to execute this action
*/
public ActionDefinition(String actionName, ActionType actionType, String inputs,
String targetService, String targetComponent, String description,
- TargetHostType targetType, Short defaultTimeout) {
+ TargetHostType targetType, Short defaultTimeout, Set<RoleAuthorization> permissions) {
setActionName(actionName);
setActionType(actionType);
setInputs(inputs);
@@ -58,6 +63,7 @@ public class ActionDefinition {
setDescription(description);
setTargetType(targetType);
setDefaultTimeout(defaultTimeout);
+ setPermissions(permissions);
}
public String getActionName() {
@@ -124,6 +130,14 @@ public class ActionDefinition {
this.defaultTimeout = defaultTimeout;
}
+ public void setPermissions(Set<RoleAuthorization> permissions) {
+ this.permissions = permissions;
+ }
+
+ public Set<RoleAuthorization> getPermissions() {
+ return permissions;
+ }
+
public ActionResponse convertToResponse() {
return new ActionResponse(getActionName(), getActionType().name(), getInputs(),
getTargetService(), getTargetComponent(), getDescription(), getTargetType().name(),
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java b/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java
index 97aa8a0..637471f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java
@@ -21,6 +21,8 @@ import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.actionmanager.ActionType;
import org.apache.ambari.server.actionmanager.TargetHostType;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.security.authorization.RoleAuthorization;
+import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -30,9 +32,12 @@ import javax.xml.bind.UnmarshalException;
import javax.xml.bind.Unmarshaller;
import java.io.File;
import java.util.ArrayList;
+import java.util.EnumSet;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Manages Action definitions read from XML files
@@ -120,7 +125,8 @@ public class ActionDefinitionManager {
}
actionDefinitionMap.put(ad.getActionName(), new ActionDefinition(ad.getActionName(), actionType,
- ad.getInputs(), ad.getTargetService(), ad.getTargetComponent(), ad.getDescription(), targetType, defaultTimeout));
+ ad.getInputs(), ad.getTargetService(), ad.getTargetComponent(), ad.getDescription(), targetType, defaultTimeout,
+ translatePermissions(ad.getPermissions())));
LOG.info("Added custom action definition for " + ad.getActionName());
} else {
LOG.warn(errorReason.toString());
@@ -199,4 +205,33 @@ public class ActionDefinitionManager {
}
return true;
}
+
+ /**
+ * Given a comma-delimited list of permission names, translates into a {@link Set} of
+ * {@link RoleAuthorization}s.
+ * <p>
+ * <code>null</code> is returned if the permission string is null or empty, or if none of the
+ * permissions in the string translate to a {@link RoleAuthorization}. Permissions that do not
+ * translate to a {@link RoleAuthorization} will yield a {@link IllegalArgumentException}.
+ *
+ * @param permissions a comma-delimited string of permission names
+ * @return a set of {@link RoleAuthorization}s; or null if no permissions are specified
+ */
+ private Set<RoleAuthorization> translatePermissions(String permissions) {
+ if (StringUtils.isEmpty(permissions)) {
+ return null;
+ } else {
+ Set<RoleAuthorization> authorizations = new HashSet<RoleAuthorization>();
+ String[] parts = permissions.split(",");
+
+ for (String permission : parts) {
+ RoleAuthorization authorization = RoleAuthorization.translate(permission);
+ if (authorization != null) {
+ authorizations.add(authorization);
+ }
+ }
+
+ return (authorizations.isEmpty()) ? null : EnumSet.copyOf(authorizations);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionSpec.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionSpec.java b/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionSpec.java
index 2dfa1f2..f789691 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionSpec.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionSpec.java
@@ -27,6 +27,7 @@ public class ActionDefinitionSpec {
private String description;
private String targetType;
private String defaultTimeout;
+ private String permissions;
public String getTargetComponent() {
return targetComponent;
@@ -92,6 +93,14 @@ public class ActionDefinitionSpec {
this.targetService = targetService;
}
+ public String getPermissions() {
+ return permissions;
+ }
+
+ public void setPermissions(String permissions) {
+ this.permissions = permissions;
+ }
+
@Override
public int hashCode() {
final int prime = 31;
@@ -134,6 +143,7 @@ public class ActionDefinitionSpec {
.append(" targetComponent: ").append(targetComponent)
.append(" defaultTimeout: ").append(defaultTimeout)
.append(" targetType: ").append(targetType)
+ .append(" permissions: ").append(permissions)
.toString();
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java
index 5c74f07..eeb1a8b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariAuthorizationFilter.java
@@ -47,6 +47,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Principal;
+import java.util.EnumSet;
import java.util.regex.Pattern;
public class AmbariAuthorizationFilter implements Filter {
@@ -77,9 +78,12 @@ public class AmbariAuthorizationFilter implements Filter {
private static final String API_CLUSTER_SERVICES_ALL_PATTERN = API_VERSION_PREFIX + "/clusters/.*?/services.*";
private static final String API_CLUSTER_ALERT_ALL_PATTERN = API_VERSION_PREFIX + "/clusters/.*?/alert.*";
private static final String API_CLUSTER_HOSTS_ALL_PATTERN = API_VERSION_PREFIX + "/clusters/.*?/hosts.*";
+ private static final String API_CLUSTER_HOST_COMPONENTS_ALL_PATTERN = API_VERSION_PREFIX + "/clusters/.*?/host_components.*";
private static final String API_STACK_VERSIONS_PATTERN = API_VERSION_PREFIX + "/stacks/.*?/versions/.*";
private static final String API_HOSTS_ALL_PATTERN = API_VERSION_PREFIX + "/hosts.*";
private static final String API_ALERT_TARGETS_ALL_PATTERN = API_VERSION_PREFIX + "/alert_targets.*";
+ private static final String API_BOOTSTRAP_PATTERN_ALL = API_VERSION_PREFIX + "/bootstrap.*";
+ private static final String API_REQUESTS_ALL_PATTERN = API_VERSION_PREFIX + "/requests.*";
protected static final String LOGIN_REDIRECT_BASE = "/#/login?targetURI=";
@@ -161,55 +165,62 @@ public class AmbariAuthorizationFilter implements Filter {
} else if (!authorizationPerformedInternally(requestURI)) {
boolean authorized = false;
- for (GrantedAuthority grantedAuthority : authentication.getAuthorities()) {
- if (grantedAuthority instanceof AmbariGrantedAuthority) {
-
- AmbariGrantedAuthority ambariGrantedAuthority = (AmbariGrantedAuthority) grantedAuthority;
+ if (requestURI.matches(API_BOOTSTRAP_PATTERN_ALL)) {
+ authorized = AuthorizationHelper.isAuthorized(authentication,
+ ResourceType.CLUSTER,
+ null,
+ EnumSet.of(RoleAuthorization.HOST_ADD_DELETE_HOSTS));
+ }
+ else {
+ for (GrantedAuthority grantedAuthority : authentication.getAuthorities()) {
+ if (grantedAuthority instanceof AmbariGrantedAuthority) {
- PrivilegeEntity privilegeEntity = ambariGrantedAuthority.getPrivilegeEntity();
- Integer permissionId = privilegeEntity.getPermission().getId();
+ AmbariGrantedAuthority ambariGrantedAuthority = (AmbariGrantedAuthority) grantedAuthority;
- // admin has full access
- if (permissionId.equals(PermissionEntity.AMBARI_ADMINISTRATOR_PERMISSION)) {
- authorized = true;
- break;
- }
+ PrivilegeEntity privilegeEntity = ambariGrantedAuthority.getPrivilegeEntity();
+ Integer permissionId = privilegeEntity.getPermission().getId();
- // clusters require permission
- if (!"GET".equalsIgnoreCase(httpRequest.getMethod()) && requestURI.matches(API_CREDENTIALS_AMBARI_PATTERN)) {
- // Only the administrator can operate on credentials where the alias starts with "ambari."
+ // admin has full access
if (permissionId.equals(PermissionEntity.AMBARI_ADMINISTRATOR_PERMISSION)) {
authorized = true;
break;
}
- } else if (requestURI.matches(API_CLUSTERS_ALL_PATTERN)) {
- if (permissionId.equals(PermissionEntity.CLUSTER_USER_PERMISSION) ||
- permissionId.equals(PermissionEntity.CLUSTER_ADMINISTRATOR_PERMISSION)) {
- authorized = true;
- break;
- }
- } else if (STACK_ADVISOR_REGEX.matcher(requestURI).matches()) {
- //TODO permissions model doesn't manage stacks api, but we need access to stack advisor to save configs
- if (permissionId.equals(PermissionEntity.CLUSTER_USER_PERMISSION) ||
- permissionId.equals(PermissionEntity.CLUSTER_ADMINISTRATOR_PERMISSION)) {
- authorized = true;
- break;
- }
- } else if (requestURI.matches(API_VIEWS_ALL_PATTERN)) {
- // views require permission
- if (permissionId.equals(PermissionEntity.VIEW_USER_PERMISSION)) {
- authorized = true;
- break;
+
+ // clusters require permission
+ if (!"GET".equalsIgnoreCase(httpRequest.getMethod()) && requestURI.matches(API_CREDENTIALS_AMBARI_PATTERN)) {
+ // Only the administrator can operate on credentials where the alias starts with "ambari."
+ if (permissionId.equals(PermissionEntity.AMBARI_ADMINISTRATOR_PERMISSION)) {
+ authorized = true;
+ break;
+ }
+ } else if (requestURI.matches(API_CLUSTERS_ALL_PATTERN)) {
+ if (permissionId.equals(PermissionEntity.CLUSTER_USER_PERMISSION) ||
+ permissionId.equals(PermissionEntity.CLUSTER_ADMINISTRATOR_PERMISSION)) {
+ authorized = true;
+ break;
+ }
+ } else if (STACK_ADVISOR_REGEX.matcher(requestURI).matches()) {
+ //TODO permissions model doesn't manage stacks api, but we need access to stack advisor to save configs
+ if (permissionId.equals(PermissionEntity.CLUSTER_USER_PERMISSION) ||
+ permissionId.equals(PermissionEntity.CLUSTER_ADMINISTRATOR_PERMISSION)) {
+ authorized = true;
+ break;
+ }
+ } else if (requestURI.matches(API_VIEWS_ALL_PATTERN)) {
+ // views require permission
+ if (permissionId.equals(PermissionEntity.VIEW_USER_PERMISSION)) {
+ authorized = true;
+ break;
+ }
}
}
}
- }
- // allow GET for everything except /views, /api/v1/users, /api/v1/groups, /api/v1/ldap_sync_events
- if (!authorized &&
- (!httpRequest.getMethod().equals("GET")
- || requestURI.matches(API_LDAP_SYNC_EVENTS_ALL_PATTERN))) {
+ // Allow all GETs that are not LDAP sync events...
+ authorized = authorized || (httpRequest.getMethod().equals("GET") && !requestURI.matches(API_LDAP_SYNC_EVENTS_ALL_PATTERN));
+ }
+ if (!authorized) {
if(auditLogger.isEnabled()) {
auditEvent = AccessUnauthorizedAuditEvent.builder()
.withHttpMethodName(httpRequest.getMethod())
@@ -283,6 +294,7 @@ public class AmbariAuthorizationFilter implements Filter {
*/
private boolean authorizationPerformedInternally(String requestURI) {
return requestURI.matches(API_USERS_ALL_PATTERN) ||
+ requestURI.matches(API_REQUESTS_ALL_PATTERN) ||
requestURI.matches(API_GROUPS_ALL_PATTERN) ||
requestURI.matches(API_CREDENTIALS_ALL_PATTERN) ||
requestURI.matches(API_PRIVILEGES_ALL_PATTERN) ||
@@ -295,6 +307,7 @@ public class AmbariAuthorizationFilter implements Filter {
requestURI.matches(VIEWS_CONTEXT_PATH_PATTERN) ||
requestURI.matches(API_WIDGET_LAYOUTS_PATTERN) ||
requestURI.matches(API_CLUSTER_HOSTS_ALL_PATTERN) ||
+ requestURI.matches(API_CLUSTER_HOST_COMPONENTS_ALL_PATTERN) ||
requestURI.matches(API_HOSTS_ALL_PATTERN) ||
requestURI.matches(API_ALERT_TARGETS_ALL_PATTERN) ||
requestURI.matches(API_PRIVILEGES_ALL_PATTERN) ||
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
index 0deba5d..dbbf477 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
@@ -329,6 +329,7 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog {
setRoleSortOrder();
addSettingPermission();
addManageUserPersistedDataPermission();
+ allowClusterOperatorToManageCredentials();
updateHDFSConfigs();
updateHIVEConfigs();
updateAMSConfigs();
@@ -513,6 +514,18 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog {
}
+ /**
+ * Adds <code>CLUSTER.MANAGE_CREDENTIALS</code> to the set of authorizations a <code>CLUSTER.OPERATOR</code> can perform.
+ *
+ * @throws SQLException
+ */
+ protected void allowClusterOperatorToManageCredentials() throws SQLException {
+ String permissionId = permissionDAO.findPermissionByNameAndType("CLUSTER.OPERATOR",
+ resourceTypeDAO.findByName("CLUSTER")).getId().toString();
+ dbAccessor.insertRowIfMissing("permission_roleauthorization", new String[]{"permission_id", "authorization_id" },
+ new String[]{"'" + permissionId + "'", "'CLUSTER.MANAGE_CREDENTIALS'" }, false);
+ }
+
protected void removeHiveOozieDBConnectionConfigs() throws AmbariException {
AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class);
Map<String, Cluster> clusterMap = getCheckedClusterMap(ambariManagementController.getClusters());
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
index 2c2d743..e6d1e16 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
@@ -1341,6 +1341,7 @@ INSERT INTO permission_roleauthorization(permission_id, authorization_id)
SELECT permission_id, 'CLUSTER.VIEW_STACK_DETAILS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.MANAGE_CONFIG_GROUPS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.VIEW_ALERTS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
+ SELECT permission_id, 'CLUSTER.MANAGE_CREDENTIALS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.MANAGE_USER_PERSISTED_DATA' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR';
-- Set authorizations for Cluster Administrator role
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
index ee87cc5..38300b0 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -1274,6 +1274,7 @@ INSERT INTO permission_roleauthorization(permission_id, authorization_id)
SELECT permission_id, 'CLUSTER.VIEW_STACK_DETAILS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.MANAGE_CONFIG_GROUPS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.VIEW_ALERTS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
+ SELECT permission_id, 'CLUSTER.MANAGE_CREDENTIALS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.MANAGE_USER_PERSISTED_DATA' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR';
-- Set authorizations for Cluster Administrator role
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
index edc46f7..a017388 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -1293,6 +1293,7 @@ INSERT INTO permission_roleauthorization(permission_id, authorization_id)
SELECT permission_id, 'CLUSTER.VIEW_STACK_DETAILS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.MANAGE_CONFIG_GROUPS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.VIEW_ALERTS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
+ SELECT permission_id, 'CLUSTER.MANAGE_CREDENTIALS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.MANAGE_USER_PERSISTED_DATA' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR';
-- Set authorizations for Cluster Administrator role
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
index 6f38ec8..7667a6b 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -1265,6 +1265,7 @@ INSERT INTO permission_roleauthorization(permission_id, authorization_id)
SELECT permission_id, 'CLUSTER.VIEW_STACK_DETAILS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.MANAGE_CONFIG_GROUPS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.VIEW_ALERTS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
+ SELECT permission_id, 'CLUSTER.MANAGE_CREDENTIALS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.MANAGE_USER_PERSISTED_DATA' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR';
-- Set authorizations for Cluster Administrator role
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
index ca57de5..9663d56 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
@@ -1427,6 +1427,7 @@ INSERT INTO ambari.permission_roleauthorization(permission_id, authorization_id)
SELECT permission_id, 'CLUSTER.VIEW_STACK_DETAILS' FROM ambari.adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.MANAGE_CONFIG_GROUPS' FROM ambari.adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.VIEW_ALERTS' FROM ambari.adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
+ SELECT permission_id, 'CLUSTER.MANAGE_CREDENTIALS' FROM ambari.adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.MANAGE_USER_PERSISTED_DATA' FROM ambari.adminpermission WHERE permission_name='CLUSTER.OPERATOR';
-- Set authorizations for Cluster Administrator role
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
index 61aadf0..d35dab3 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
@@ -1290,6 +1290,7 @@ insert into adminpermission(permission_id, permission_name, resource_type_id, pe
SELECT permission_id, 'CLUSTER.VIEW_STACK_DETAILS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.MANAGE_CONFIG_GROUPS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.VIEW_ALERTS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
+ SELECT permission_id, 'CLUSTER.MANAGE_CREDENTIALS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.MANAGE_USER_PERSISTED_DATA' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR';
-- Set authorizations for Cluster Administrator role
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
index 9269b13..23ba2db 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -1293,6 +1293,7 @@ BEGIN TRANSACTION
SELECT permission_id, 'CLUSTER.VIEW_STACK_DETAILS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.MANAGE_CONFIG_GROUPS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.VIEW_ALERTS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
+ SELECT permission_id, 'CLUSTER.MANAGE_CREDENTIALS' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR' UNION ALL
SELECT permission_id, 'CLUSTER.MANAGE_USER_PERSISTED_DATA' FROM adminpermission WHERE permission_name='CLUSTER.OPERATOR';
-- Set authorizations for Cluster Administrator role
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/main/resources/custom_action_definitions/system_action_definitions.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/custom_action_definitions/system_action_definitions.xml b/ambari-server/src/main/resources/custom_action_definitions/system_action_definitions.xml
index 6304baf..bc1c271 100644
--- a/ambari-server/src/main/resources/custom_action_definitions/system_action_definitions.xml
+++ b/ambari-server/src/main/resources/custom_action_definitions/system_action_definitions.xml
@@ -28,6 +28,7 @@
<defaultTimeout>60</defaultTimeout>
<description>General check for host</description>
<targetType>ANY</targetType>
+ <permissions>HOST.ADD_DELETE_HOSTS</permissions>
</actionDefinition>
<actionDefinition>
<actionName>update_repo</actionName>
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
index 3ec9cb3..42d62c8 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
@@ -4314,11 +4314,11 @@ public class AmbariManagementControllerTest {
ActionDefinition a1 = new ActionDefinition(actionDef1, ActionType.SYSTEM,
- "test,[optional1]", "", "", "Does file exist", TargetHostType.SPECIFIC, Short.valueOf("100"));
+ "test,[optional1]", "", "", "Does file exist", TargetHostType.SPECIFIC, Short.valueOf("100"), null);
controller.getAmbariMetaInfo().addActionDefinition(a1);
controller.getAmbariMetaInfo().addActionDefinition(new ActionDefinition(
actionDef2, ActionType.SYSTEM, "", "HDFS", "DATANODE", "Does file exist",
- TargetHostType.ALL, Short.valueOf("1000")));
+ TargetHostType.ALL, Short.valueOf("1000"), null));
Map<String, String> params = new HashMap<String, String>() {{
put("test", "test");
@@ -4700,23 +4700,23 @@ public class AmbariManagementControllerTest {
controller.getAmbariMetaInfo().addActionDefinition(new ActionDefinition(
actionDef1, ActionType.SYSTEM, "test,dirName", "", "", "Does file exist",
- TargetHostType.SPECIFIC, Short.valueOf("100")));
+ TargetHostType.SPECIFIC, Short.valueOf("100"), null));
controller.getAmbariMetaInfo().addActionDefinition(new ActionDefinition(
actionDef2, ActionType.SYSTEM, "", "HDFS", "DATANODE", "Does file exist",
- TargetHostType.ANY, Short.valueOf("100")));
+ TargetHostType.ANY, Short.valueOf("100"), null));
controller.getAmbariMetaInfo().addActionDefinition(new ActionDefinition(
"update_repo", ActionType.SYSTEM, "", "HDFS", "DATANODE", "Does file exist",
- TargetHostType.ANY, Short.valueOf("100")));
+ TargetHostType.ANY, Short.valueOf("100"), null));
controller.getAmbariMetaInfo().addActionDefinition(new ActionDefinition(
actionDef3, ActionType.SYSTEM, "", "MAPREDUCE", "MAPREDUCE_CLIENT", "Does file exist",
- TargetHostType.ANY, Short.valueOf("100")));
+ TargetHostType.ANY, Short.valueOf("100"), null));
controller.getAmbariMetaInfo().addActionDefinition(new ActionDefinition(
actionDef4, ActionType.SYSTEM, "", "HIVE", "", "Does file exist",
- TargetHostType.ANY, Short.valueOf("100")));
+ TargetHostType.ANY, Short.valueOf("100"), null));
actionRequest = new ExecuteActionRequest(cluster1, null, actionDef1, null, null, null, false);
expectActionCreationErrorWithMessage(actionRequest, requestProperties,
@@ -6560,7 +6560,7 @@ public class AmbariManagementControllerTest {
controller.getAmbariMetaInfo().addActionDefinition(new ActionDefinition(
action1, ActionType.SYSTEM, "", "HDFS", "", "Some custom action.",
- TargetHostType.ALL, Short.valueOf("10010")));
+ TargetHostType.ALL, Short.valueOf("10010"), null));
Map<String, String> params = new HashMap<String, String>() {{
put("test", "test");
@@ -10601,7 +10601,7 @@ public class AmbariManagementControllerTest {
ambariMetaInfo.addActionDefinition(new ActionDefinition(action1, ActionType.SYSTEM,
"", "", "", "action def description", TargetHostType.ANY,
- Short.valueOf("60")));
+ Short.valueOf("60"), null));
Map<String, String> requestProperties = new HashMap<String, String>();
requestProperties.put(REQUEST_CONTEXT_PROPERTY, "Called from a test");
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ActionResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ActionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ActionResourceProviderTest.java
index 96995b4..c581ff4 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ActionResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ActionResourceProviderTest.java
@@ -97,13 +97,13 @@ public class ActionResourceProviderTest {
List<ActionDefinition> allDefinition = new ArrayList<ActionDefinition>();
allDefinition.add(new ActionDefinition(
"a1", ActionType.SYSTEM, "fileName", "HDFS", "DATANODE", "Does file exist", TargetHostType.ANY,
- Short.valueOf("100")));
+ Short.valueOf("100"), null));
allDefinition.add(new ActionDefinition(
"a2", ActionType.SYSTEM, "fileName", "HDFS", "DATANODE", "Does file exist", TargetHostType.ANY,
- Short.valueOf("100")));
+ Short.valueOf("100"), null));
allDefinition.add(new ActionDefinition(
"a3", ActionType.SYSTEM, "fileName", "HDFS", "DATANODE", "Does file exist", TargetHostType.ANY,
- Short.valueOf("100")));
+ Short.valueOf("100"), null));
Set<ActionResponse> allResponse = new HashSet<ActionResponse>();
for (ActionDefinition definition : allDefinition) {
@@ -112,7 +112,7 @@ public class ActionResourceProviderTest {
ActionDefinition namedDefinition = new ActionDefinition(
"a1", ActionType.SYSTEM, "fileName", "HDFS", "DATANODE", "Does file exist", TargetHostType.ANY,
- Short.valueOf("100"));
+ Short.valueOf("100"), null);
Set<ActionResponse> nameResponse = new HashSet<ActionResponse>();
nameResponse.add(namedDefinition.convertToResponse());
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java
index 65efc63..4444714 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java
@@ -22,19 +22,20 @@ package org.apache.ambari.server.controller.internal;
import static org.apache.ambari.server.controller.internal.HostComponentResourceProvider.HOST_COMPONENT_STALE_CONFIGS_PROPERTY_ID;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.capture;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.newCapture;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.reset;
-import static org.easymock.EasyMock.verify;
+import static org.powermock.api.easymock.PowerMock.createMock;
+import static org.powermock.api.easymock.PowerMock.createNiceMock;
+import static org.powermock.api.easymock.PowerMock.replay;
+import static org.powermock.api.easymock.PowerMock.reset;
+import static org.powermock.api.easymock.PowerMock.verify;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
@@ -49,6 +50,7 @@ import org.apache.ambari.server.actionmanager.ActionManager;
import org.apache.ambari.server.actionmanager.HostRoleCommand;
import org.apache.ambari.server.actionmanager.HostRoleStatus;
import org.apache.ambari.server.actionmanager.Stage;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.api.services.BaseRequest;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.AmbariServer;
@@ -63,6 +65,7 @@ import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
import org.apache.ambari.server.controller.utilities.PredicateBuilder;
import org.apache.ambari.server.controller.utilities.PredicateHelper;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.customactions.ActionDefinition;
import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
import org.apache.ambari.server.orm.dao.HostRoleCommandStatusSummaryDTO;
import org.apache.ambari.server.orm.dao.RequestDAO;
@@ -70,6 +73,7 @@ import org.apache.ambari.server.orm.entities.RequestEntity;
import org.apache.ambari.server.security.TestAuthenticationFactory;
import org.apache.ambari.server.security.authorization.AuthorizationException;
import org.apache.ambari.server.security.authorization.AuthorizationHelperInitializer;
+import org.apache.ambari.server.security.authorization.RoleAuthorization;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.topology.ClusterTopology;
@@ -1307,21 +1311,69 @@ public class RequestResourceProviderTest {
}
@Test
- public void testCreateResourcesForNonCluster() throws Exception {
+ public void testCreateResourcesCheckHostForNonClusterAsAdministrator() throws Exception {
+ testCreateResourcesForNonCluster(TestAuthenticationFactory.createAdministrator(), "check_host",
+ EnumSet.of(RoleAuthorization.HOST_ADD_DELETE_HOSTS));
+ }
+
+ @Test
+ public void testCreateResourcesCheckHostForNonClusterAsClusterAdministrator() throws Exception {
+ testCreateResourcesForNonCluster(TestAuthenticationFactory.createClusterAdministrator(), "check_host",
+ EnumSet.of(RoleAuthorization.HOST_ADD_DELETE_HOSTS));
+ }
+
+ @Test
+ public void testCreateResourcesCheckHostForNonClusterAsClusterOperator() throws Exception {
+ testCreateResourcesForNonCluster(TestAuthenticationFactory.createClusterOperator(), "check_host",
+ EnumSet.of(RoleAuthorization.HOST_ADD_DELETE_HOSTS));
+ }
+
+ @Test(expected = AuthorizationException.class)
+ public void testCreateResourcesCheckHostForNonClusterAsServiceAdministrator() throws Exception {
+ testCreateResourcesForNonCluster(TestAuthenticationFactory.createServiceAdministrator(), "check_host",
+ EnumSet.of(RoleAuthorization.HOST_ADD_DELETE_HOSTS));
+ }
+
+ @Test
+ public void testCreateResourcesCheckJavaForNonClusterAsAdministrator() throws Exception {
+ testCreateResourcesForNonCluster(TestAuthenticationFactory.createAdministrator(), "check_java", null);
+ }
+
+ @Test(expected = AuthorizationException.class)
+ public void testCreateResourcesCheckJavaForNonClusterAsClusterAdministrator() throws Exception {
+ testCreateResourcesForNonCluster(TestAuthenticationFactory.createClusterAdministrator(), "check_java", null);
+ }
+
+ @Test(expected = AuthorizationException.class)
+ public void testCreateResourcesCheckJavaForNonClusterAsClusterOperator() throws Exception {
+ testCreateResourcesForNonCluster(TestAuthenticationFactory.createClusterOperator(), "check_java", null);
+ }
+
+ @Test(expected = AuthorizationException.class)
+ public void testCreateResourcesForNonClusterAsServiceAdministrator() throws Exception {
+ testCreateResourcesForNonCluster(TestAuthenticationFactory.createServiceAdministrator(), "check_java", null);
+ }
+
+ private void testCreateResourcesForNonCluster(Authentication authentication, String actionName, Set<RoleAuthorization> permissions) throws Exception {
Resource.Type type = Resource.Type.Request;
Capture<ExecuteActionRequest> actionRequest = newCapture();
Capture<HashMap<String, String>> propertyMap = newCapture();
AmbariManagementController managementController = createMock(AmbariManagementController.class);
+ AmbariMetaInfo metaInfo = createMock(AmbariMetaInfo.class);
+ ActionDefinition actionDefinition = createMock(ActionDefinition.class);
RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
expect(managementController.createAction(capture(actionRequest), capture(propertyMap)))
.andReturn(response).anyTimes();
+ expect(managementController.getAmbariMetaInfo()).andReturn(metaInfo).anyTimes();
+ expect(metaInfo.getActionDefinition(actionName)).andReturn(actionDefinition).anyTimes();
+ expect(actionDefinition.getPermissions()).andReturn(permissions).anyTimes();
expect(response.getMessage()).andReturn("Message").anyTimes();
// replay
- replay(managementController, response);
+ replay(managementController, metaInfo, actionDefinition, response);
// add the property map to a set for the request. add more maps for multiple creates
Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
@@ -1338,7 +1390,9 @@ public class RequestResourceProviderTest {
propertySet.add(properties);
Map<String, String> requestInfoProperties = new HashMap<String, String>();
- requestInfoProperties.put(RequestResourceProvider.ACTION_ID, "check_java");
+ requestInfoProperties.put(RequestResourceProvider.ACTION_ID, actionName);
+
+ SecurityContextHolder.getContext().setAuthentication(authentication);
// create the request
Request request = PropertyHelper.getCreateRequest(propertySet, requestInfoProperties);
@@ -1352,7 +1406,7 @@ public class RequestResourceProviderTest {
Assert.assertTrue(actionRequest.hasCaptured());
Assert.assertFalse("expected an action", capturedRequest.isCommand());
- Assert.assertEquals("check_java", capturedRequest.getActionName());
+ Assert.assertEquals(actionName, capturedRequest.getActionName());
Assert.assertEquals(null, capturedRequest.getCommandName());
Assert.assertNotNull(capturedRequest.getResourceFilters());
Assert.assertEquals(1, capturedRequest.getResourceFilters().size());
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/test/java/org/apache/ambari/server/customactions/ActionDefinitionManagerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/customactions/ActionDefinitionManagerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/customactions/ActionDefinitionManagerTest.java
index ec84922..f7808d1 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/customactions/ActionDefinitionManagerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/customactions/ActionDefinitionManagerTest.java
@@ -19,22 +19,25 @@
package org.apache.ambari.server.customactions;
import java.io.File;
+import java.util.EnumSet;
import junit.framework.Assert;
import org.apache.ambari.server.actionmanager.ActionType;
import org.apache.ambari.server.actionmanager.TargetHostType;
+import org.apache.ambari.server.security.authorization.RoleAuthorization;
import org.junit.Test;
public class ActionDefinitionManagerTest {
- private final String customActionDefinitionRoot = "./src/test/resources/custom_action_definitions/";
+ private static final String CUSTOM_ACTION_DEFINITION_ROOT = "./src/test/resources/custom_action_definitions/";
+ private static final String CUSTOM_ACTION_DEFINITION_INVALID_ROOT = "./src/test/resources/custom_action_definitions_invalid/";
@Test
public void testReadCustomActionDefinitions() throws Exception {
ActionDefinitionManager manager = new ActionDefinitionManager();
- manager.readCustomActionDefinitions(new File(customActionDefinitionRoot));
+ manager.readCustomActionDefinitions(new File(CUSTOM_ACTION_DEFINITION_ROOT));
- Assert.assertEquals(2, manager.getAllActionDefinition().size());
+ Assert.assertEquals(3, manager.getAllActionDefinition().size());
ActionDefinition ad = manager.getActionDefinition("customAction1");
Assert.assertNotNull(ad);
Assert.assertEquals("customAction1", ad.getActionName());
@@ -45,6 +48,7 @@ public class ActionDefinitionManagerTest {
Assert.assertEquals(60, (int)ad.getDefaultTimeout());
Assert.assertEquals(TargetHostType.ALL, ad.getTargetType());
Assert.assertEquals(ActionType.USER, ad.getActionType());
+ Assert.assertEquals(EnumSet.of(RoleAuthorization.HOST_ADD_DELETE_COMPONENTS, RoleAuthorization.HOST_ADD_DELETE_HOSTS), ad.getPermissions());
ad = manager.getActionDefinition("customAction2");
Assert.assertNotNull(ad);
@@ -56,6 +60,25 @@ public class ActionDefinitionManagerTest {
Assert.assertEquals(60, (int)ad.getDefaultTimeout());
Assert.assertEquals(null, ad.getTargetType());
Assert.assertEquals(ActionType.USER, ad.getActionType());
+ Assert.assertEquals(EnumSet.of(RoleAuthorization.HOST_ADD_DELETE_COMPONENTS, RoleAuthorization.HOST_ADD_DELETE_HOSTS), ad.getPermissions());
+
+ ad = manager.getActionDefinition("customAction3");
+ Assert.assertNotNull(ad);
+ Assert.assertEquals("customAction3", ad.getActionName());
+ Assert.assertEquals("A random test", ad.getDescription());
+ Assert.assertEquals(null, ad.getInputs());
+ Assert.assertEquals("TASKTRACKER", ad.getTargetComponent());
+ Assert.assertEquals("MAPREDUCE", ad.getTargetService());
+ Assert.assertEquals(60, (int)ad.getDefaultTimeout());
+ Assert.assertEquals(null, ad.getTargetType());
+ Assert.assertEquals(ActionType.USER, ad.getActionType());
+ Assert.assertNull(ad.getPermissions());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testReadInvalidCustomActionDefinitions() throws Exception {
+ ActionDefinitionManager manager = new ActionDefinitionManager();
+ manager.readCustomActionDefinitions(new File(CUSTOM_ACTION_DEFINITION_INVALID_ROOT));
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/test/java/org/apache/ambari/server/security/TestAuthenticationFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/TestAuthenticationFactory.java b/ambari-server/src/test/java/org/apache/ambari/server/security/TestAuthenticationFactory.java
index 69b4b08..4301bf8 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/security/TestAuthenticationFactory.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/security/TestAuthenticationFactory.java
@@ -48,10 +48,18 @@ public class TestAuthenticationFactory {
return createClusterAdministrator("clusterAdmin", 4L);
}
+ public static Authentication createClusterOperator() {
+ return createClusterOperator("clusterOp", 4L);
+ }
+
public static Authentication createClusterAdministrator(String name, Long clusterResourceId) {
return new TestAuthorization(name, Collections.singleton(createClusterAdministratorGrantedAuthority(clusterResourceId)));
}
+ public static Authentication createClusterOperator(String name, Long clusterResourceId) {
+ return new TestAuthorization(name, Collections.singleton(createClusterOperatorGrantedAuthority(clusterResourceId)));
+ }
+
public static Authentication createServiceAdministrator() {
return createServiceAdministrator("serviceAdmin", 4L);
}
@@ -92,6 +100,10 @@ public class TestAuthenticationFactory {
return new AmbariGrantedAuthority(createClusterAdministratorPrivilegeEntity(clusterResourceId));
}
+ private static GrantedAuthority createClusterOperatorGrantedAuthority(Long clusterResourceId) {
+ return new AmbariGrantedAuthority(createClusterOperatorPrivilegeEntity(clusterResourceId));
+ }
+
private static GrantedAuthority createServiceAdministratorGrantedAuthority(Long clusterResourceId) {
return new AmbariGrantedAuthority(createServiceAdministratorPrivilegeEntity(clusterResourceId));
}
@@ -122,6 +134,13 @@ public class TestAuthenticationFactory {
return privilegeEntity;
}
+ private static PrivilegeEntity createClusterOperatorPrivilegeEntity(Long clusterResourceId) {
+ PrivilegeEntity privilegeEntity = new PrivilegeEntity();
+ privilegeEntity.setResource(createClusterResourceEntity(clusterResourceId));
+ privilegeEntity.setPermission(createClusterOperatorPermission());
+ return privilegeEntity;
+ }
+
private static PrivilegeEntity createServiceAdministratorPrivilegeEntity(Long clusterResourceId) {
PrivilegeEntity privilegeEntity = new PrivilegeEntity();
privilegeEntity.setResource(createClusterResourceEntity(clusterResourceId));
@@ -200,6 +219,44 @@ public class TestAuthenticationFactory {
return permissionEntity;
}
+ private static PermissionEntity createClusterOperatorPermission() {
+ PermissionEntity permissionEntity = new PermissionEntity();
+ permissionEntity.setId(5);
+ permissionEntity.setResourceType(createResourceTypeEntity(ResourceType.CLUSTER));
+ permissionEntity.setAuthorizations(createAuthorizations(EnumSet.of(
+ RoleAuthorization.HOST_VIEW_CONFIGS,
+ RoleAuthorization.HOST_ADD_DELETE_COMPONENTS,
+ RoleAuthorization.HOST_VIEW_METRICS,
+ RoleAuthorization.SERVICE_DECOMMISSION_RECOMMISSION,
+ RoleAuthorization.CLUSTER_VIEW_CONFIGS,
+ RoleAuthorization.SERVICE_MANAGE_ALERTS,
+ RoleAuthorization.SERVICE_ENABLE_HA,
+ RoleAuthorization.SERVICE_VIEW_METRICS,
+ RoleAuthorization.SERVICE_RUN_CUSTOM_COMMAND,
+ RoleAuthorization.HOST_VIEW_STATUS_INFO,
+ RoleAuthorization.CLUSTER_VIEW_METRICS,
+ RoleAuthorization.SERVICE_VIEW_STATUS_INFO,
+ RoleAuthorization.CLUSTER_VIEW_STACK_DETAILS,
+ RoleAuthorization.SERVICE_COMPARE_CONFIGS,
+ RoleAuthorization.SERVICE_VIEW_ALERTS,
+ RoleAuthorization.CLUSTER_MANAGE_CONFIG_GROUPS,
+ RoleAuthorization.SERVICE_TOGGLE_ALERTS,
+ RoleAuthorization.SERVICE_MOVE,
+ RoleAuthorization.SERVICE_RUN_SERVICE_CHECK,
+ RoleAuthorization.SERVICE_MODIFY_CONFIGS,
+ RoleAuthorization.CLUSTER_VIEW_STATUS_INFO,
+ RoleAuthorization.SERVICE_VIEW_CONFIGS,
+ RoleAuthorization.HOST_ADD_DELETE_HOSTS,
+ RoleAuthorization.SERVICE_START_STOP,
+ RoleAuthorization.CLUSTER_VIEW_ALERTS,
+ RoleAuthorization.HOST_TOGGLE_MAINTENANCE,
+ RoleAuthorization.SERVICE_TOGGLE_MAINTENANCE,
+ RoleAuthorization.SERVICE_MANAGE_CONFIG_GROUPS,
+ RoleAuthorization.CLUSTER_MANAGE_USER_PERSISTED_DATA,
+ RoleAuthorization.CLUSTER_MANAGE_CREDENTIALS)));
+ return permissionEntity;
+ }
+
private static PermissionEntity createServiceAdministratorPermission() {
PermissionEntity permissionEntity = new PermissionEntity();
permissionEntity.setId(5);
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java
index 4dedc98..2490851 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java
@@ -464,6 +464,7 @@ public class UpgradeCatalog240Test {
Method addNewConfigurationsFromXml = AbstractUpgradeCatalog.class.getDeclaredMethod("addNewConfigurationsFromXml");
Method updateAlerts = UpgradeCatalog240.class.getDeclaredMethod("updateAlerts");
Method addManageUserPersistedDataPermission = UpgradeCatalog240.class.getDeclaredMethod("addManageUserPersistedDataPermission");
+ Method allowClusterOperatorToManageCredentials = UpgradeCatalog240.class.getDeclaredMethod("allowClusterOperatorToManageCredentials");
Method addSettingPermission = UpgradeCatalog240.class.getDeclaredMethod("addSettingPermission");
Method updateHDFSConfigs = UpgradeCatalog240.class.getDeclaredMethod("updateHDFSConfigs");
Method updateHIVEConfigs = UpgradeCatalog240.class.getDeclaredMethod("updateHIVEConfigs");
@@ -495,6 +496,7 @@ public class UpgradeCatalog240Test {
.addMockedMethod(updateAlerts)
.addMockedMethod(addSettingPermission)
.addMockedMethod(addManageUserPersistedDataPermission)
+ .addMockedMethod(allowClusterOperatorToManageCredentials)
.addMockedMethod(updateHDFSConfigs)
.addMockedMethod(updateHIVEConfigs)
.addMockedMethod(updateAmsConfigs)
@@ -520,6 +522,7 @@ public class UpgradeCatalog240Test {
upgradeCatalog240.updateAlerts();
upgradeCatalog240.addSettingPermission();
upgradeCatalog240.addManageUserPersistedDataPermission();
+ upgradeCatalog240.allowClusterOperatorToManageCredentials();
upgradeCatalog240.updateHDFSConfigs();
upgradeCatalog240.updateHIVEConfigs();
upgradeCatalog240.updateAMSConfigs();
http://git-wip-us.apache.org/repos/asf/ambari/blob/055b6315/ambari-server/src/test/resources/custom_action_definitions/cust_action_definitions1.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/custom_action_definitions/cust_action_definitions1.xml b/ambari-server/src/test/resources/custom_action_definitions/cust_action_definitions1.xml
index 9cee575..e8e6bc8 100644
--- a/ambari-server/src/test/resources/custom_action_definitions/cust_action_definitions1.xml
+++ b/ambari-server/src/test/resources/custom_action_definitions/cust_action_definitions1.xml
@@ -27,6 +27,7 @@
<targetComponent>TASKTRACKER</targetComponent>
<description>A random test</description>
<targetType>ALL</targetType>
+ <permissions>HOST.ADD_DELETE_HOSTS,HOST.ADD_DELETE_COMPONENTS</permissions>
</actionDefinition>
<actionDefinition>
<actionName>customAction2</actionName>
@@ -34,9 +35,17 @@
<targetService>MAPREDUCE</targetService>
<targetComponent>TASKTRACKER</targetComponent>
<description>A random test</description>
+ <permissions> HOST.ADD_DELETE_HOSTS , HOST.ADD_DELETE_COMPONENTS </permissions> <!-- Note the spaces -->
</actionDefinition>
<actionDefinition>
<actionName>customAction3</actionName>
+ <actionType>USER</actionType>
+ <targetService>MAPREDUCE</targetService>
+ <targetComponent>TASKTRACKER</targetComponent>
+ <description>A random test</description>
+ </actionDefinition>
+ <actionDefinition>
+ <actionName>customAction4</actionName>
<actionType>USERS_OWN</actionType>
<targetService>MAPREDUCE</targetService>
<targetComponent>TASKTRACKER</targetComponent>