diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/AccessPolicy.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/AccessPolicy.java deleted file mode 100644 index ee64d5ae0929..000000000000 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/AccessPolicy.java +++ /dev/null @@ -1,152 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package org.apache.hadoop.ozone.om.multitenant; - -import java.io.IOException; -import java.security.Principal; -import java.util.HashSet; -import java.util.List; - -import org.apache.hadoop.hdds.annotation.InterfaceAudience; -import org.apache.hadoop.hdds.annotation.InterfaceStability; -import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType; -import org.apache.hadoop.ozone.security.acl.OzoneObj; -import com.google.gson.JsonObject; - -/** - * AccessPolicy interface for Ozone Multi-Tenancy. - */ -@InterfaceAudience.LimitedPrivate({"HDFS", "Yarn", "Ranger", "Hive", "HBase"}) -@InterfaceStability.Evolving -public interface AccessPolicy { - - /** - * Ozone could support different authorization engines e.g. - * native-authorization, Ranger Authorization, - * any-other-external-authorization. This interface is an in memory - * version of a generic access policy. Any Ozone policy can be uniquely - * identified by its policy-ID. Ozone can choose to persist this policy-ID - * in its internal database. A remote/native authorizer can retrieve/update - * an access policy associated with its Policy-ID ID. - * - */ - enum AccessPolicyType { NATIVE_ACL, RANGER_POLICY, AWS_POLICY, OTHER }; - - /** - * Allow or deny. - */ - enum AccessGrantType { ALLOW, DENY }; - - /** - * Defines an access policy entry. - */ - class AccessPolicyElem { - private OzoneObj object; - private Principal principal; - private ACLType aclType; - private AccessGrantType grantType; - - public AccessPolicyElem(OzoneObj obj, Principal id, - ACLType acl, AccessGrantType grant) { - object = obj; - principal = id; - aclType = acl; - grantType = grant; - } - - public OzoneObj getObject() { - return object; - } - - public Principal getPrincipal() { - return principal; - } - - public ACLType getAclType() { - return aclType; - } - - public AccessGrantType getAccessGrantType() { - return grantType; - } - } - - /** - * @param id This would be policy-ID that an external/native authorizer - * could return. - */ - void setPolicyName(String id); - - String getPolicyID(); - - /** - * @return unique policy-name for this policy. - */ - String getPolicyName(); - - /** - * - * @return Policy in a Json string format. Individual implementation can - * choose different AccessPolicyType e.g. Ranger-Compatible-Json-Policy, - * AWS-Compatible-Json-policy etc. It could be an Opaque data to the caller - * and they can directly send it to an authorizer (e.g. Ranger). - * All Authorizer policy engines are supposed to provide an implementation - * of AccessPolicy interface. - */ - String serializePolicyToJsonString() throws IOException; - - /** - * Given a serialized accessPolicy in a Json format, deserializes and - * constructs a valid access Policy. - * @return - * @throws IOException - */ - String deserializePolicyFromJsonString(JsonObject jsonObject) - throws IOException; - - /** - * @return AccessPolicyType (Native or otherwise). - */ - AccessPolicyType getAccessPolicyType(); - - void addAccessPolicyElem(OzoneObj object, - Principal principal, ACLType acl, - AccessGrantType grant) throws IOException; - - void removeAccessPolicyElem(OzoneObj object, - Principal principal, - ACLType acl, AccessGrantType grant) - throws IOException; - - List getAccessPolicyElem(); - - /** - * Sets the last update time to mtime. - * @param mtime Time in epoch milliseconds - */ - void setPolicyLastUpdateTime(long mtime); - - /** - * Returns the last update time of Ranger policies. - */ - long getPolicyLastUpdateTime(); - - /** - * @return list of roles associated with this policy - */ - HashSet getRoleList(); -} diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/RangerAccessPolicy.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/RangerAccessPolicy.java deleted file mode 100644 index cebb540ba6d4..000000000000 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/RangerAccessPolicy.java +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.hadoop.ozone.om.multitenant; - -import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType; -import org.apache.hadoop.ozone.security.acl.OzoneObj; - -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; - -import java.io.IOException; -import java.security.Principal; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import static org.apache.hadoop.ozone.OzoneConsts.OZONE_TENANT_RANGER_POLICY_LABEL; -import static org.apache.hadoop.ozone.om.multitenant.AccessPolicy.AccessPolicyType.RANGER_POLICY; - -/** - * This is used for Ozone tenant access policy control. - */ -public class RangerAccessPolicy implements AccessPolicy { - - // For now RangerAccessPolicy supports only one object per policy - private OzoneObj accessObject; - private final Map> policyMap; - private final HashSet roleList; - private String policyID; - private String policyJsonString; - private String policyName; - private long lastPolicyUpdateTimeEpochMillis; - - public RangerAccessPolicy(String name) { - policyMap = new ConcurrentHashMap<>(); - policyName = name; - roleList = new HashSet<>(); - } - - public void setPolicyName(String id) { - policyID = id; - } - - public String getPolicyID() { - return policyID; - } - - public String getPolicyName() { - return policyName; - } - - public HashSet getRoleList() { - return roleList; - } - - @Override - public void setPolicyLastUpdateTime(long mtime) { - lastPolicyUpdateTimeEpochMillis = mtime; - } - - @Override - public long getPolicyLastUpdateTime() { - return lastPolicyUpdateTimeEpochMillis; - } - - @Override - public String serializePolicyToJsonString() throws IOException { - updatePolicyJsonString(); - return policyJsonString; - } - - @Override - public String deserializePolicyFromJsonString(JsonObject jsonObject) { - setPolicyName(jsonObject.get("id").getAsString()); - try { - JsonArray policyItems = jsonObject - .getAsJsonArray("policyItems"); - for (int j = 0; j < policyItems.size(); ++j) { - JsonObject policy = policyItems.get(j).getAsJsonObject(); - JsonArray roles = policy.getAsJsonArray("roles"); - for (int k = 0; k < roles.size(); ++k) { - if (!roleList.contains(roles.get(k).getAsString())) { - // We only get the role name here. We need to query and populate it. - roleList.add(roles.get(k).getAsString()); - } - } - } - } catch (Exception e) { - // Ignore Exception here. - } - // TODO : retrieve other policy fields as well. - try { - setPolicyLastUpdateTime(jsonObject.get("updateTime").getAsLong()); - } catch (Exception e) { - // lets ignore the exception in case the field is not set. - } - return null; - } - - @Override - public AccessPolicyType getAccessPolicyType() { - return RANGER_POLICY; - } - - @Override - public void addAccessPolicyElem(OzoneObj object, - Principal principal, - ACLType acl, AccessGrantType grant) - throws IOException { - if (accessObject == null) { - accessObject = object; - } else if (!object.toString().equals(accessObject.toString())) { - throw new IOException( - "RangerAccessPolicy supports only one object per" + " policy"); - } - AccessPolicyElem elem = new AccessPolicyElem(object, principal, acl, grant); - if (!policyMap.containsKey(principal.getName())) { - List elemList = new ArrayList<>(); - elemList.add(elem); - policyMap.put(principal.getName(), elemList); - return; - } - List elemList = policyMap.get(principal.getName()); - for (AccessPolicyElem e : elemList) { - if (e.getAclType() == acl) { - throw new IOException( - "RangerAccessPolicy: Principal " + principal.getName() - + " already exists with access " + acl); - } - } - elemList.add(elem); - } - - @Override - public List getAccessPolicyElem() { - List list = new ArrayList<>(); - for (Map.Entry> entry : policyMap - .entrySet()) { - list.addAll(entry.getValue()); - } - return list; - } - - @Override - public void removeAccessPolicyElem(OzoneObj object, - Principal principal, ACLType acl, - AccessGrantType grant) - throws IOException { - if (accessObject == null) { - throw new IOException("removeAccessPolicyElem: Invalid Arguments."); - } else if (!object.toString().equals(accessObject.toString())) { - throw new IOException( - "removeAccessPolicyElem: Object not found." + object.toString()); - } - if (!policyMap.containsKey(principal.getName())) { - throw new IOException( - "removeAccessPolicyElem: Principal not found." + object.toString()); - } - List elemList = policyMap.get(principal.getName()); - for (AccessPolicyElem e : elemList) { - if (e.getAclType() == acl) { - elemList.remove(e); - } - } - if (elemList.isEmpty()) { - policyMap.remove(principal.toString()); - } - throw new IOException( - "removeAccessPolicyElem: aclType not found." + object.toString()); - } - - private String createRangerResourceItems() { - StringBuilder resourceItems = new StringBuilder(); - resourceItems.append("\"resources\":{" + - "\"volume\":{" + - "\"values\":[\""); - resourceItems.append(accessObject.getVolumeName()); - resourceItems.append("\"]," + - "\"isRecursive\":false," + - "\"isExcludes\":false" + - "}"); - if ((accessObject.getResourceType() == OzoneObj.ResourceType.BUCKET) || - (accessObject.getResourceType() == OzoneObj.ResourceType.KEY)) { - resourceItems.append( - ",\"bucket\":{" + - "\"values\":[\""); - resourceItems.append(accessObject.getBucketName()); - resourceItems.append("\"]," + - "\"isRecursive\":false," + - "\"isExcludes\":false" + - "}"); - } - if (accessObject.getResourceType() == OzoneObj.ResourceType.KEY) { - resourceItems.append(",\"key\":{" + - "\"values\":[\""); - resourceItems.append(accessObject.getKeyName()); - resourceItems.append("\"]," + - "\"isRecursive\":true," + - "\"isExcludes\":false" + - "}"); - } - resourceItems.append("},"); - return resourceItems.toString(); - } - - private String createRangerPolicyItems() throws IOException { - StringBuilder policyItems = new StringBuilder(); - policyItems.append("\"policyItems\":["); - int mapRemainingSize = policyMap.size(); - for (Map.Entry> mapElem : policyMap - .entrySet()) { - mapRemainingSize--; - List list = mapElem.getValue(); - if (list.isEmpty()) { - continue; - } - policyItems.append("{"); - if (list.get(0).getPrincipal() instanceof OzoneTenantRolePrincipal) { - policyItems.append("\"roles\":[\"" + mapElem.getKey() + "\"],"); - } else { - policyItems.append("\"users\":[\"" + mapElem.getKey() + "\"],"); - } - policyItems.append("\"accesses\":["); - Iterator iter = list.iterator(); - while (iter.hasNext()) { - AccessPolicyElem elem = iter.next(); - policyItems.append("{"); - policyItems.append("\"type\":\""); - policyItems.append(getRangerAclString(elem.getAclType())); - policyItems.append("\","); - if (elem.getAccessGrantType() == AccessGrantType.ALLOW) { - policyItems.append("\"isAllowed\":true"); - } else { - policyItems.append("\"isDenied\":true"); - } - policyItems.append("}"); - if (iter.hasNext()) { - policyItems.append(","); - } - } - policyItems.append("]"); - policyItems.append("}"); - if (mapRemainingSize > 0) { - policyItems.append(","); - } - } - policyItems.append("],"); - return policyItems.toString(); - } - - private String getRangerAclString(ACLType aclType) throws IOException { - switch (aclType) { - case ALL: - return "All"; - case LIST: - return "List"; - case READ: - return "Read"; - case WRITE: - return "Write"; - case CREATE: - return "Create"; - case DELETE: - return "Delete"; - case READ_ACL: - return "Read_ACL"; - case WRITE_ACL: - return "Write_ACL"; - case NONE: - return ""; - default: - throw new IOException("Unknown ACLType"); - } - } - - private void updatePolicyJsonString() throws IOException { - policyJsonString = - "{\"policyType\":\"0\"," + "\"name\":\"" + policyName + "\"," - + "\"isEnabled\":true," + "\"policyPriority\":0," - + "\"description\":\"Policy created by Ozone for Multi-Tenancy\"," - + "\"policyLabels\":[\"" + OZONE_TENANT_RANGER_POLICY_LABEL + "\"]," - + "\"description\":\"\"," - + "\"isAuditEnabled\":true," + createRangerResourceItems() - + "\"isDenyAllElse\":false," + createRangerPolicyItems() - + "\"allowExceptions\":[]," + "\"denyPolicyItems\":[]," - + "\"denyExceptions\":[]," + "\"service\":\"cm_ozone\"" + "}"; - } - - @Override - public String toString() { - return "RangerAccessPolicy{" + "accessObject=" + accessObject - + ", policyMap=" + policyMap + ", roleList=" + roleList + ", policyID='" - + policyID + '\'' + ", policyJsonString='" + policyJsonString + '\'' - + ", policyName='" + policyName + '\'' - + ", lastPolicyUpdateTimeEpochMillis=" + lastPolicyUpdateTimeEpochMillis - + '}'; - } -} diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManagerImpl.java index 731f7fb37b4e..1d25a49fc562 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManagerImpl.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManagerImpl.java @@ -25,10 +25,6 @@ import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.INVALID_ACCESS_ID; import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.TENANT_AUTHORIZER_ERROR; import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.TENANT_NOT_FOUND; -import static org.apache.hadoop.ozone.om.multitenant.AccessPolicy.AccessGrantType.ALLOW; -import static org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType.ALL; -import static org.apache.hadoop.ozone.security.acl.OzoneObj.ResourceType.KEY; -import static org.apache.hadoop.ozone.security.acl.OzoneObj.StoreType.OZONE; import java.io.IOException; import java.util.ArrayList; @@ -54,7 +50,6 @@ import org.apache.hadoop.ozone.om.helpers.OmDBTenantState; import org.apache.hadoop.ozone.om.helpers.OmDBUserPrincipalInfo; import org.apache.hadoop.ozone.om.helpers.TenantUserList; -import org.apache.hadoop.ozone.om.multitenant.AccessPolicy; import org.apache.hadoop.ozone.om.multitenant.AuthorizerLock; import org.apache.hadoop.ozone.om.multitenant.AuthorizerLockImpl; import org.apache.hadoop.ozone.om.multitenant.BucketNameSpace; @@ -65,14 +60,11 @@ import org.apache.hadoop.ozone.om.multitenant.MultiTenantAccessController.Policy; import org.apache.hadoop.ozone.om.multitenant.MultiTenantAccessController.Role; import org.apache.hadoop.ozone.om.service.OMRangerBGSyncService; -import org.apache.hadoop.ozone.om.multitenant.OzoneOwnerPrincipal; import org.apache.hadoop.ozone.om.multitenant.OzoneTenant; -import org.apache.hadoop.ozone.om.multitenant.RangerAccessPolicy; import org.apache.hadoop.ozone.om.multitenant.RangerClientMultiTenantAccessController; import org.apache.hadoop.ozone.om.multitenant.Tenant; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.UserAccessIdInfo; import org.apache.hadoop.ozone.security.acl.OzoneObj; -import org.apache.hadoop.ozone.security.acl.OzoneObjInfo; import org.apache.hadoop.security.UserGroupInformation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -851,24 +843,6 @@ private String getTenantForAccessIDThrowIfNotFound(String accessId) return optionalTenant.get(); } - // TODO: This policy doesn't seem necessary as the bucket-level policy has - // already granted the key-level access. - // Not sure if that is the intended behavior in Ranger though. - // Still, could add this KeyAccess policy as well in Ranger, doesn't hurt. - private AccessPolicy newDefaultKeyAccessPolicy(String volumeName, - String bucketName) throws IOException { - AccessPolicy policy = new RangerAccessPolicy( - // principal already contains volume name - volumeName + "-KeyAccess"); - - OzoneObjInfo obj = OzoneObjInfo.Builder.newBuilder() - .setResType(KEY).setStoreType(OZONE).setVolumeName(volumeName) - .setBucketName("*").setKeyName("*").build(); - // Bucket owners should have ALL permission on their keys - policy.addAccessPolicyElem(obj, new OzoneOwnerPrincipal(), ALL, ALLOW); - return policy; - } - public OzoneConfiguration getConf() { return conf; }