Skip to content

Commit

Permalink
[#5196] improve(auth-ranger): Refactor RangerSecurableObject class (#…
Browse files Browse the repository at this point in the history
…5222)

### What changes were proposed in this pull request?

1. Add `RangerMetadataObject` class.

### Why are the changes needed?

Currently, RangerSecurableObject extends MetadataObject, but Ranger
managers meta types different with Gravitino, for example, Ranger
doesn't have `METALAKE`, `ROLE`, So we need to Refactor
RangerSecurableObject class.

Fix: #5196

### Does this PR introduce _any_ user-facing change?

N/A

### How was this patch tested?

CI Passed.
  • Loading branch information
xunliu authored Oct 23, 2024
1 parent 44a47d0 commit bea3934
Show file tree
Hide file tree
Showing 12 changed files with 431 additions and 138 deletions.
5 changes: 3 additions & 2 deletions api/src/main/java/org/apache/gravitino/MetadataObjects.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ public static MetadataObject of(String parent, String name, MetadataObject.Type
Preconditions.checkArgument(name != null, "Cannot create a metadata object with null name");
Preconditions.checkArgument(type != null, "Cannot create a metadata object with no type");

return new MetadataObjectImpl(parent, name, type);
String fullName = parent == null ? name : DOT_JOINER.join(parent, name);
return parse(fullName, type);
}

/**
Expand Down Expand Up @@ -159,7 +160,7 @@ public static MetadataObject parse(String fullName, MetadataObject.Type type) {
* @param names The names of the metadata object
* @return The parent full name if it exists, otherwise null
*/
public static String getParentFullName(List<String> names) {
private static String getParentFullName(List<String> names) {
if (names.size() <= 1) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,35 @@ public static synchronized RangerAuthorizationHivePlugin getInstance(Map<String,
return instance;
}

/** Validate different Ranger metadata object */
@Override
public void validateRangerMetadataObject(List<String> names, RangerMetadataObject.Type type)
throws IllegalArgumentException {
Preconditions.checkArgument(
names != null && !names.isEmpty(), "Cannot create a Ranger metadata object with no names");
Preconditions.checkArgument(
names.size() <= 3,
"Cannot create a Ranger metadata object with the name length which is greater than 3");
Preconditions.checkArgument(
type != null, "Cannot create a Ranger metadata object with no type");

Preconditions.checkArgument(
names.size() != 1 || type == RangerMetadataObject.Type.SCHEMA,
"If the length of names is 1, it must be the SCHEMA type");

Preconditions.checkArgument(
names.size() != 2 || type == RangerMetadataObject.Type.TABLE,
"If the length of names is 2, it must be the TABLE type");

Preconditions.checkArgument(
names.size() != 3 || type == RangerMetadataObject.Type.COLUMN,
"If the length of names is 3, it must be COLUMN");

for (String name : names) {
RangerMetadataObjects.checkName(name);
}
}

@Override
/** Set the default mapping Gravitino privilege name to the Ranger rule */
public Map<Privilege.Name, Set<RangerPrivilege>> privilegesMappingRule() {
Expand Down Expand Up @@ -110,78 +139,79 @@ public Set<Privilege.Name> allowPrivilegesRule() {
}

/** Translate the Gravitino securable object to the Ranger owner securable object. */
public List<RangerSecurableObject> translateOwner(MetadataObject metadataObject) {
public List<RangerSecurableObject> translateOwner(MetadataObject gravitinoMetadataObject) {
List<RangerSecurableObject> rangerSecurableObjects = new ArrayList<>();

switch (metadataObject.type()) {
switch (gravitinoMetadataObject.type()) {
case METALAKE:
case CATALOG:
// Add `*` for the SCHEMA permission
rangerSecurableObjects.add(
RangerSecurableObjects.of(
generateRangerSecurableObject(
ImmutableList.of(RangerHelper.RESOURCE_ALL),
MetadataObject.Type.SCHEMA,
RangerMetadataObject.Type.SCHEMA,
ownerMappingRule()));
// Add `*.*` for the TABLE permission
rangerSecurableObjects.add(
RangerSecurableObjects.of(
generateRangerSecurableObject(
ImmutableList.of(RangerHelper.RESOURCE_ALL, RangerHelper.RESOURCE_ALL),
MetadataObject.Type.TABLE,
RangerMetadataObject.Type.TABLE,
ownerMappingRule()));
// Add `*.*.*` for the COLUMN permission
rangerSecurableObjects.add(
RangerSecurableObjects.of(
generateRangerSecurableObject(
ImmutableList.of(
RangerHelper.RESOURCE_ALL,
RangerHelper.RESOURCE_ALL,
RangerHelper.RESOURCE_ALL),
MetadataObject.Type.COLUMN,
RangerMetadataObject.Type.COLUMN,
ownerMappingRule()));
break;
case SCHEMA:
// Add `{schema}` for the SCHEMA permission
rangerSecurableObjects.add(
RangerSecurableObjects.of(
ImmutableList.of(metadataObject.name() /*Schema name*/),
MetadataObject.Type.SCHEMA,
generateRangerSecurableObject(
ImmutableList.of(gravitinoMetadataObject.name() /*Schema name*/),
RangerMetadataObject.Type.SCHEMA,
ownerMappingRule()));
// Add `{schema}.*` for the TABLE permission
rangerSecurableObjects.add(
RangerSecurableObjects.of(
ImmutableList.of(metadataObject.name() /*Schema name*/, RangerHelper.RESOURCE_ALL),
MetadataObject.Type.TABLE,
generateRangerSecurableObject(
ImmutableList.of(
gravitinoMetadataObject.name() /*Schema name*/, RangerHelper.RESOURCE_ALL),
RangerMetadataObject.Type.TABLE,
ownerMappingRule()));
// Add `{schema}.*.*` for the COLUMN permission
rangerSecurableObjects.add(
RangerSecurableObjects.of(
generateRangerSecurableObject(
ImmutableList.of(
metadataObject.name() /*Schema name*/,
gravitinoMetadataObject.name() /*Schema name*/,
RangerHelper.RESOURCE_ALL,
RangerHelper.RESOURCE_ALL),
MetadataObject.Type.COLUMN,
RangerMetadataObject.Type.COLUMN,
ownerMappingRule()));
break;
case TABLE:
// Add `{schema}.{table}` for the TABLE permission
rangerSecurableObjects.add(
RangerSecurableObjects.of(
convertToRangerMetadataObject(metadataObject),
MetadataObject.Type.TABLE,
generateRangerSecurableObject(
convertToRangerMetadataObject(gravitinoMetadataObject),
RangerMetadataObject.Type.TABLE,
ownerMappingRule()));
// Add `{schema}.{table}.*` for the COLUMN permission
rangerSecurableObjects.add(
RangerSecurableObjects.of(
generateRangerSecurableObject(
Stream.concat(
convertToRangerMetadataObject(metadataObject).stream(),
convertToRangerMetadataObject(gravitinoMetadataObject).stream(),
Stream.of(RangerHelper.RESOURCE_ALL))
.collect(Collectors.toList()),
MetadataObject.Type.COLUMN,
RangerMetadataObject.Type.COLUMN,
ownerMappingRule()));
break;
default:
throw new AuthorizationPluginException(
"The owner privilege is not supported for the securable object: %s",
metadataObject.type());
gravitinoMetadataObject.type());
}

return rangerSecurableObjects;
Expand Down Expand Up @@ -214,9 +244,9 @@ public List<RangerSecurableObject> translatePrivilege(SecurableObject securableO
case CATALOG:
// Add Ranger privilege(`SELECT`) to SCHEMA(`*`)
rangerSecurableObjects.add(
RangerSecurableObjects.of(
generateRangerSecurableObject(
ImmutableList.of(RangerHelper.RESOURCE_ALL),
MetadataObject.Type.SCHEMA,
RangerMetadataObject.Type.SCHEMA,
rangerPrivileges));
break;
default:
Expand All @@ -231,9 +261,9 @@ public List<RangerSecurableObject> translatePrivilege(SecurableObject securableO
case CATALOG:
// Add Ranger privilege(`CREATE`) to SCHEMA(`*`)
rangerSecurableObjects.add(
RangerSecurableObjects.of(
generateRangerSecurableObject(
ImmutableList.of(RangerHelper.RESOURCE_ALL),
MetadataObject.Type.SCHEMA,
RangerMetadataObject.Type.SCHEMA,
rangerPrivileges));
break;
default:
Expand All @@ -248,17 +278,17 @@ public List<RangerSecurableObject> translatePrivilege(SecurableObject securableO
case CATALOG:
// Add Ranger privilege(`SELECT`) to SCHEMA(`*`)
rangerSecurableObjects.add(
RangerSecurableObjects.of(
generateRangerSecurableObject(
ImmutableList.of(RangerHelper.RESOURCE_ALL),
MetadataObject.Type.SCHEMA,
RangerMetadataObject.Type.SCHEMA,
rangerPrivileges));
break;
case SCHEMA:
// Add Ranger privilege(`SELECT`) to SCHEMA(`{schema}`)
rangerSecurableObjects.add(
RangerSecurableObjects.of(
generateRangerSecurableObject(
ImmutableList.of(securableObject.name() /*Schema name*/),
MetadataObject.Type.SCHEMA,
RangerMetadataObject.Type.SCHEMA,
rangerPrivileges));
break;
default:
Expand All @@ -275,38 +305,38 @@ public List<RangerSecurableObject> translatePrivilege(SecurableObject securableO
case CATALOG:
// Add `*.*` for the TABLE permission
rangerSecurableObjects.add(
RangerSecurableObjects.of(
generateRangerSecurableObject(
ImmutableList.of(
RangerHelper.RESOURCE_ALL, RangerHelper.RESOURCE_ALL),
MetadataObject.Type.TABLE,
RangerMetadataObject.Type.TABLE,
rangerPrivileges));
// Add `*.*.*` for the COLUMN permission
rangerSecurableObjects.add(
RangerSecurableObjects.of(
generateRangerSecurableObject(
ImmutableList.of(
RangerHelper.RESOURCE_ALL,
RangerHelper.RESOURCE_ALL,
RangerHelper.RESOURCE_ALL),
MetadataObject.Type.COLUMN,
RangerMetadataObject.Type.COLUMN,
rangerPrivileges));
break;
case SCHEMA:
// Add `{schema}.*` for the TABLE permission
rangerSecurableObjects.add(
RangerSecurableObjects.of(
generateRangerSecurableObject(
ImmutableList.of(
securableObject.name() /*Schema name*/,
RangerHelper.RESOURCE_ALL),
MetadataObject.Type.TABLE,
RangerMetadataObject.Type.TABLE,
rangerPrivileges));
// Add `{schema}.*.*` for the COLUMN permission
rangerSecurableObjects.add(
RangerSecurableObjects.of(
generateRangerSecurableObject(
ImmutableList.of(
securableObject.name() /*Schema name*/,
RangerHelper.RESOURCE_ALL,
RangerHelper.RESOURCE_ALL),
MetadataObject.Type.COLUMN,
RangerMetadataObject.Type.COLUMN,
rangerPrivileges));
break;
case TABLE:
Expand All @@ -317,18 +347,18 @@ public List<RangerSecurableObject> translatePrivilege(SecurableObject securableO
} else {
// Add `{schema}.{table}` for the TABLE permission
rangerSecurableObjects.add(
RangerSecurableObjects.of(
generateRangerSecurableObject(
convertToRangerMetadataObject(securableObject),
MetadataObject.Type.TABLE,
RangerMetadataObject.Type.TABLE,
rangerPrivileges));
// Add `{schema}.{table}.*` for the COLUMN permission
rangerSecurableObjects.add(
RangerSecurableObjects.of(
generateRangerSecurableObject(
Stream.concat(
convertToRangerMetadataObject(securableObject).stream(),
Stream.of(RangerHelper.RESOURCE_ALL))
.collect(Collectors.toList()),
MetadataObject.Type.COLUMN,
RangerMetadataObject.Type.COLUMN,
rangerPrivileges));
}
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
* implement Gravitino Owner concept. <br>
*/
public abstract class RangerAuthorizationPlugin
implements AuthorizationPlugin, RangerPrivilegesMappingProvider {
implements AuthorizationPlugin, RangerPrivilegesMappingProvider, RangerMetadataObjectRule {
private static final Logger LOG = LoggerFactory.getLogger(RangerAuthorizationPlugin.class);

protected final String rangerServiceName;
Expand Down Expand Up @@ -660,7 +660,20 @@ private boolean doRemoveSecurableObject(
@Override
public void close() throws IOException {}

boolean validAuthorizationOperation(List<SecurableObject> securableObjects) {
/** Generate different Ranger securable object */
public RangerSecurableObject generateRangerSecurableObject(
List<String> names, RangerMetadataObject.Type type, Set<RangerPrivilege> privileges) {
validateRangerMetadataObject(names, type);
RangerMetadataObject metadataObject =
new RangerMetadataObjects.RangerMetadataObjectImpl(
RangerMetadataObjects.getParentFullName(names),
RangerMetadataObjects.getLastName(names),
type);
return new RangerSecurableObjects.RangerSecurableObjectImpl(
metadataObject.parent(), metadataObject.name(), metadataObject.type(), privileges);
}

public boolean validAuthorizationOperation(List<SecurableObject> securableObjects) {
return securableObjects.stream()
.allMatch(
securableObject -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.apache.gravitino.MetadataObject;
import org.apache.gravitino.authorization.Owner;
import org.apache.gravitino.authorization.Privilege;
import org.apache.gravitino.authorization.SecurableObjects;
import org.apache.gravitino.exceptions.AuthorizationPluginException;
import org.apache.ranger.RangerClient;
import org.apache.ranger.RangerServiceException;
Expand Down Expand Up @@ -192,12 +190,12 @@ void removePolicyItem(
/**
* Find the managed policy for the ranger securable object.
*
* @param rangerSecurableObject The ranger securable object to find the managed policy.
* @param rangerMetadataObject The ranger securable object to find the managed policy.
* @return The managed policy for the metadata object.
*/
public RangerPolicy findManagedPolicy(RangerSecurableObject rangerSecurableObject)
public RangerPolicy findManagedPolicy(RangerMetadataObject rangerMetadataObject)
throws AuthorizationPluginException {
List<String> nsMetadataObj = getMetadataObjectNames(rangerSecurableObject);
List<String> nsMetadataObj = rangerMetadataObject.names();

Map<String, String> searchFilters = new HashMap<>();
Map<String, String> preciseFilters = new HashMap<>();
Expand Down Expand Up @@ -395,23 +393,13 @@ protected void updatePolicyOwner(RangerPolicy policy, Owner preOwner, Owner newO
});
}

private static List<String> getMetadataObjectNames(MetadataObject metadataObject) {
List<String> nsMetadataObject =
Lists.newArrayList(SecurableObjects.DOT_SPLITTER.splitToList(metadataObject.fullName()));
if (nsMetadataObject.size() > 4) {
// The max level of the securable object is `catalog.db.table.column`
throw new RuntimeException("The length of the securable object should not be greater than 4");
}
return nsMetadataObject;
}

protected RangerPolicy createPolicyAddResources(MetadataObject metadataObject) {
protected RangerPolicy createPolicyAddResources(RangerMetadataObject metadataObject) {
RangerPolicy policy = new RangerPolicy();
policy.setService(rangerServiceName);
policy.setName(metadataObject.fullName());
policy.setPolicyLabels(Lists.newArrayList(RangerHelper.MANAGED_BY_GRAVITINO));

List<String> nsMetadataObject = getMetadataObjectNames(metadataObject);
List<String> nsMetadataObject = metadataObject.names();

for (int i = 0; i < nsMetadataObject.size(); i++) {
RangerPolicy.RangerPolicyResource policyResource =
Expand All @@ -421,7 +409,7 @@ protected RangerPolicy createPolicyAddResources(MetadataObject metadataObject) {
return policy;
}

protected RangerPolicy addOwnerToNewPolicy(MetadataObject metadataObject, Owner newOwner) {
protected RangerPolicy addOwnerToNewPolicy(RangerMetadataObject metadataObject, Owner newOwner) {
RangerPolicy policy = createPolicyAddResources(metadataObject);

ownerPrivileges.forEach(
Expand All @@ -444,7 +432,7 @@ protected RangerPolicy addOwnerToNewPolicy(MetadataObject metadataObject, Owner
}

protected RangerPolicy addOwnerRoleToNewPolicy(
MetadataObject metadataObject, String ownerRoleName) {
RangerMetadataObject metadataObject, String ownerRoleName) {
RangerPolicy policy = createPolicyAddResources(metadataObject);

ownerPrivileges.forEach(
Expand Down
Loading

0 comments on commit bea3934

Please sign in to comment.