-
Notifications
You must be signed in to change notification settings - Fork 335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#4698] feat(auth-ranger): Extended Ranger authorization by rules #4744
Conversation
@lw-yang Please help me review this PR, thanks. |
LGTM. |
...ons/authorization-ranger/src/test/resources/authorization-defs/authorization-hive.properties
Outdated
Show resolved
Hide resolved
...tion-ranger/src/main/java/org/apache/gravitino/authorization/ranger/AuthorizationConfig.java
Outdated
Show resolved
Hide resolved
...tion-ranger/src/main/java/org/apache/gravitino/authorization/ranger/AuthorizationConfig.java
Outdated
Show resolved
Hide resolved
@yuqi1129 I fixed all comments. Please help me review again, Thanks! |
* Initial Ranger policy search key defines. <br> | ||
* Initial precise filter key defines. <br> | ||
*/ | ||
private void initAuthorizationConfig(AuthorizationConfig authorizationConfig) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we provide default values as before, it's too complicated to set the mapping for most users and only those users that have special requirement will configure this value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, I improved it, Please help me review this PR, again.
LGTM, @jerqi @jerryshao Would you like to take a look? |
Sorry for late response, I will take a look at this today. |
I'm a little confused about the changes here made, can you describe more clearly about the scenarios and how users will use this feature? It's really not easy to understand. |
In Gravitino, we specify that each Gravitino Privilege maps multiple Privileges on the underlying system(Ranger), but there are some users whose environments have different privilege mappings than ours, so we allow users to configure their own to meet their own personalized needs, in addition to using our default Privilege mappings. |
@jerryshao This feature allows for custom configuration of the mapping relationship between Gravitino Privileges and Ranger Privileges. If the default mapping relationship in Gravitino does not meet our scenario, we can customize it. For example, by default, Gravitino's MODIFY_TABLE maps to Ranger's RangerHivePrivilege.UPDATE, RangerHivePrivilege.ALTER, RangerHivePrivilege.WRITE. In our scenario, we need to add RangerHivePrivilege.DROP, so we can customize this mapping relationship. |
import org.apache.gravitino.config.ConfigEntry; | ||
|
||
public class AuthorizationConfig extends Config { | ||
public static final ConfigEntry<List<String>> AUTHORIZATION_OWNER_PRIVILEGES = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these generic authorization configs or ranger authorization only configs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are generic authorization configs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If these are generic configs, they should be put into the code module, not Ranger module. Also I'm curious how other plugins like JDBC, IAM can leverage these configurations later on. From my understanding, they're quite Ranger specific.
AuthorizationConfig authorizationConfig = new AuthorizationConfig(); | ||
boolean testEnv = System.getenv("GRAVITINO_TEST") != null; | ||
String propertyFilePath = | ||
String.format("authorization-defs/authorization-%s.properties", providerName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can directly put this file into the conf, not so necessary to add another "authorization-defs" folder, WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I moved it to distribution/package/authorizations/ranger/conf/authorization-hive.properties
.
# Format: authorization.privilege.mapping.<GRAVITINO-PRIVILEGE> = <RANGER-PRIVILEGE>,<RANGER-PRIVILEGE>,... | ||
# gravitino.authorization.privilege.mapping.CREATE_SCHEMA = create | ||
# gravitino.authorization.privilege.mapping.CREATE_TABLE = create | ||
# gravitino.authorization.privilege.mapping.SELECT_TABLE = read,select |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we handle the scenarios like having prefix and trailing whitespace in between policies for the conf value? like:
gravitino.authorization.privilege.mapping.CREATE_TABLE = create, aaa, xxx, aaa
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I have test case to cover these scenarios.
authorizations/authorization-ranger/src/test/resources/authorization-defs/authorization-hive-nonstandard.properties
|
||
Gravitino privileges defined in the `api/src/main/java/org/apache/gravitino/authorization/Privilege.java` | ||
Format: authorization.privilege.mapping.<GRAVITINO-PRIVILEGE> = <RANGER-PRIVILEGE>,<RANGER-PRIVILEGE>,... | ||
::: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the document here is not enough. You should clearly describe how to configure, what is the meaning, and give an example here.
Also, do we only support 4 privileges for mapping, how do we support more privileges to map easily?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the document here is not enough. You should clearly describe how to configure, what is the meaning, and give an example here.
OK, I added example in the docs.
Also, do we only support 4 privileges for mapping, how do we support more privileges to map easily?
No, We can support all Gravitino privileges to configurations.
Because I use
Privilege.Name gravitinoPrivilege =
Privilege.Name.valueOf(key.trim().toUpperCase());
These codes can convert any String to a Gravitino Privilege enum value.
import org.apache.gravitino.config.ConfigEntry; | ||
|
||
public class AuthorizationConfig extends Config { | ||
public static final ConfigEntry<List<String>> AUTHORIZATION_OWNER_PRIVILEGES = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are generic authorization configs.
# Format: authorization.privilege.mapping.<GRAVITINO-PRIVILEGE> = <RANGER-PRIVILEGE>,<RANGER-PRIVILEGE>,... | ||
# gravitino.authorization.privilege.mapping.CREATE_SCHEMA = create | ||
# gravitino.authorization.privilege.mapping.CREATE_TABLE = create | ||
# gravitino.authorization.privilege.mapping.SELECT_TABLE = read,select |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I have test case to cover these scenarios.
authorizations/authorization-ranger/src/test/resources/authorization-defs/authorization-hive-nonstandard.properties
AuthorizationConfig authorizationConfig = new AuthorizationConfig(); | ||
boolean testEnv = System.getenv("GRAVITINO_TEST") != null; | ||
String propertyFilePath = | ||
String.format("authorization-defs/authorization-%s.properties", providerName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I moved it to distribution/package/authorizations/ranger/conf/authorization-hive.properties
.
Privilege.Name gravitinoPrivilege = | ||
Privilege.Name.valueOf(key.trim().toUpperCase()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hi @jerryshao
These codes can convert any String to a Gravitino Privilege enum value.
|
||
Gravitino privileges defined in the `api/src/main/java/org/apache/gravitino/authorization/Privilege.java` | ||
Format: authorization.privilege.mapping.<GRAVITINO-PRIVILEGE> = <RANGER-PRIVILEGE>,<RANGER-PRIVILEGE>,... | ||
::: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the document here is not enough. You should clearly describe how to configure, what is the meaning, and give an example here.
OK, I added example in the docs.
Also, do we only support 4 privileges for mapping, how do we support more privileges to map easily?
No, We can support all Gravitino privileges to configurations.
Because I use
Privilege.Name gravitinoPrivilege =
Privilege.Name.valueOf(key.trim().toUpperCase());
These codes can convert any String to a Gravitino Privilege enum value.
@jerryshao I updated this PR, Please help me review it again, thanks. |
This is just a discussion instead of review suggestion. What's the difference between users and developers. This feature should be used by developers instead of users. So I prefer extracting an interface Configuration has less restriction than the interface. The interface can help us define better behaviour. This is just my cent, not a strong suggestion. |
@jerryshao I removed the use properties file to overwrite the default authorization configuration. |
import org.apache.gravitino.authorization.Privilege; | ||
|
||
/** | ||
* Ranger authorization use this configuration to mapping Gravitino privilege to the Ranger |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to think a bit on this, my initial feeling is that This RangerAuthorizationConfig
may not be easy for people to use.
Most of the interfaces like initializePrivilegesMappingConfig()
is hard to people to understand from the definition. People doesn't know what should be implemented, what is the input, output and side-effect of this interface. Without knowing this, it is hard for the developers to extend or implement this interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's OK for internal use. But if we want to expose to the developers to extend, seems the definition is not self-explanatory. The concept of xxxConfig
makes people hard to understand without context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can change class name fromRangerAuthorizationConfig
to PrivilegeMappingRules
?
and change the function name from
initializePrivilegesMappingConfig()
->setPrivilegesMappingRule()
initializeOwnerPrivilegesConfig()
->setOwnerPrivilegesRule()
initializePolicyResourceDefinesConfig()
->setPolicyResourceDefinesRule()
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typically, it is hard to design an interface for like "initializeXXX" or "setXXX", because it is hard for developers to know how to correctly implement a code about "initializeXXX" or "setXXX". Instead, I would suggest like:
interface RangerPrivilegesMappingProvider {
Map<GravitinoPrivilege, Set<RangerPrivileges>> privilegesMappingRule()
Map<GravitinoPrivilege, Set<RangerPrivileges>> ownerMappingRule()
...
}
Just for your reference, please take a look, thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I accept your suggestion.
public interface RangerPrivilege { | ||
String toString(); | ||
|
||
boolean equals(String value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the interface name equals
is conflicted with Java's built-in equals
method name, also for toString
, it is better to have another name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, change equals()
to isEquals()
.
REPLADMIN("repladmin"), | ||
SERVICEADMIN("serviceadmin"); | ||
|
||
private final String string; // Access a type in the Ranger policy item |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is better to have a different name for this class variable, not similar to the reserved word.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DONE.
449d564
to
be618e8
Compare
@jerryshao I accept your suggestion and modify the code, please help me review again, thanks. |
void ownerMappingRule(); | ||
|
||
/** Set the policy resource defines rule. */ | ||
void policyResourceDefinesRule(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think that you should have the return value for the method you defined here. Otherwise, it is hard for others to implement a such interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea.
return ImmutableList.of( | ||
PolicyResource.DATABASE.getName(), | ||
PolicyResource.TABLE.getName(), | ||
PolicyResource.COLUMN.getName()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like all these methods return immutable map or list, if so, I would suggest make them singletons, so that we don't have to create maps or lists for each call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to singleton.
private Map<Privilege.Name, Set<RangerPrivilege>> privilegesMapping; | ||
/** The owner privileges, the owner can do anything on the metadata object configuration */ | ||
private Set<RangerPrivilege> ownerPrivileges; | ||
/** The Ranger policy resource defines configuration. */ | ||
private List<String> policyResourceDefines; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please make these variables final
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also for other class variables.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DONE.
// Initialize privilegesMapping and ownerPrivileges | ||
ownerPrivileges = ownerMappingRule(); | ||
privilegesMapping = privilegesMappingRule(); | ||
policyResourceDefines = policyResourceDefinesRule(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also please change the style to this.xxx = xxx
for class variable assignment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DONE.
} | ||
|
||
public final List<String> getPolicyResourceDefines() { | ||
return policyResourceDefines; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also do you still need these methods? I think you can directly call privilegesMappingRule
, ownerMappingRule
, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DONE
public interface RangerPrivilege { | ||
String getName(); | ||
|
||
boolean isEquals(String value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"isEquals" is not correct for grammar, can you please change to equalsTo(xxxx)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DONE
@@ -38,7 +38,7 @@ public class RangerContainer extends BaseContainer { | |||
public static final String DEFAULT_IMAGE = System.getenv("GRAVITINO_CI_RANGER_DOCKER_IMAGE"); | |||
public static final String HOST_NAME = "gravitino-ci-ranger"; | |||
public static final int RANGER_SERVER_PORT = 6080; | |||
public RangerClient rangerClient; | |||
public RangerClientExtend rangerClient; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please change this class name "RangerClientExtend" to "RangerExtendedClient" or "RangerClientExtension", the name "xxxExtend" is a verb not a noun.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to RangerClientExtension
.
@xunliu , can you please also update the PR title and description to reflect what you did currently. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jerryshao I refactoring the code, Please help me review again.
private Map<Privilege.Name, Set<RangerPrivilege>> privilegesMapping; | ||
/** The owner privileges, the owner can do anything on the metadata object configuration */ | ||
private Set<RangerPrivilege> ownerPrivileges; | ||
/** The Ranger policy resource defines configuration. */ | ||
private List<String> policyResourceDefines; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DONE.
// Initialize privilegesMapping and ownerPrivileges | ||
ownerPrivileges = ownerMappingRule(); | ||
privilegesMapping = privilegesMappingRule(); | ||
policyResourceDefines = policyResourceDefinesRule(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DONE.
} | ||
|
||
public final List<String> getPolicyResourceDefines() { | ||
return policyResourceDefines; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DONE
public interface RangerPrivilege { | ||
String getName(); | ||
|
||
boolean isEquals(String value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DONE
@@ -38,7 +38,7 @@ public class RangerContainer extends BaseContainer { | |||
public static final String DEFAULT_IMAGE = System.getenv("GRAVITINO_CI_RANGER_DOCKER_IMAGE"); | |||
public static final String HOST_NAME = "gravitino-ci-ranger"; | |||
public static final int RANGER_SERVER_PORT = 6080; | |||
public RangerClient rangerClient; | |||
public RangerClientExtend rangerClient; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to RangerClientExtension
.
return ImmutableList.of( | ||
PolicyResource.DATABASE.getName(), | ||
PolicyResource.TABLE.getName(), | ||
PolicyResource.COLUMN.getName()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to singleton.
What changes were proposed in this pull request?
RangerPrivilegesMappingProvider
, we can use it to map Gravitino privileges to the Ranger privileges.RangerAuthorizationPlugin
, we can use it to extend another Ranger authorization plugin.Why are the changes needed?
Fix: #4698
Does this PR introduce any user-facing change?
NA
How was this patch tested?
CI Passed.