-
Notifications
You must be signed in to change notification settings - Fork 382
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
[#4993] feat(iceberg): integrate credential framework to iceberg REST server #5134
Conversation
0a5f592
to
81f620e
Compare
@jerryshao , it's ready for review now, please help to review when you are free, thanks |
public static final String CREDENTIAL_TYPE = "credential-type"; | ||
|
||
private CredentialConstants() {} | ||
} |
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 remembered that we already defined this in Credential
, we don't have to define this again here.
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 not the same, one is the credential type in Credential
, this is the credential type in catalog properties. They are happen to the same 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.
Why can't you use a different 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.
use credential-provider-type
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 it is a catalog property, it is better to define in catalog-common, so other engines can also use it.
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 property already defined in catalog-common
@@ -110,7 +110,7 @@ public void initialize( | |||
resultConf.put("catalog_uuid", info.id().toString()); | |||
IcebergConfig icebergConfig = new IcebergConfig(resultConf); | |||
|
|||
this.icebergCatalogWrapper = new IcebergCatalogWrapper(icebergConfig); | |||
this.icebergCatalogWrapper = new IcebergCatalogWrapper(icebergConfig, false); |
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 add a comment here to explain the reason why we hard code the false
here?
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
// todo: transform specific credential to iceberg properties | ||
return credential.toProperties(); | ||
} | ||
} |
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.
Why do we add this Iceberg specific method in common module, can it be in iceberg-common module?
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.
This will also be used in client or spark to transform Credential properties to the properties used for Iceberg. so I place it in common.
public IcebergCatalogWrapper() { | ||
this(new IcebergConfig(Collections.emptyMap())); |
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.
We can still maintain this default constructor like:
public IcebergCatalogWrapper() {
this(xxxx, false)
}
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.
it's used to test only, seems useless to maintain the default constructor
// todo(fanng): check user privilege. | ||
PathBasedCredentialContext pathBasedCredentialContext = | ||
new PathBasedCredentialContext( | ||
PrincipalUtils.getCurrentUserName(), ImmutableSet.of(location), ImmutableSet.of()); |
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 you need to set write path?
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, because we don't know user will write or read after loading table. We have to give the write privilege to the user .After we supporting ACL, we could grant write privilege to the user only with write privilege.
return catalogConfigToClients; | ||
} | ||
|
||
private Map<String, String> vendCredentials(String location) { | ||
// ifPresentOrElse is not supported in Java8 | ||
if (credentialProvider.isPresent()) { |
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.
You can change to simplify your code here:
if (!xx.isPresent) {
throw new XXXException();
}
....
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
@@ -75,7 +75,7 @@ public IcebergCatalogWrapper getIcebergTableOps(String catalogName) { | |||
LOG.warn(errorMsg); | |||
throw new RuntimeException(errorMsg); | |||
} | |||
return new IcebergCatalogWrapper(icebergConfig); | |||
return new IcebergCatalogWrapper(icebergConfig, true); |
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.
Why do we need to have a boolean to control whether to use credential vending or not, is there any better way?
Also, I saw there're lot of hard-code value in this PR, if it is enabled by default, maybe we can figure out a better way other than hard-coded boolean.
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.
removed credential vending logic from IcebergCatalogWrapper
, do credential vending after related operation is finished outside.
LOG.info( | ||
"Create Iceberg table, namespace: {}, create table request: {}", | ||
"Create Iceberg table, namespace: {}, create table request: {}, accessDelegation: {}, isCredentialVending:{}", |
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.
Add space before {}
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
} | ||
|
||
@Test | ||
void testCreateTableWithCredentialVending() { |
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.
add credential vending test here
@jerryshao please help to review again |
public static Map<String, String> toIcebergProperties(Credential credential) { | ||
// todo: transform specific credential to iceberg properties | ||
return credential.toProperties(); |
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.
This two lines code is not worthy to create a new class here, why can't you put this in iceberg package?
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 like a placeholder function to support more credential properties transform logic, this function will be used in client side and Iceberg REST server side, so I place it in common module.
|
||
public void registerCredentialProvider( | ||
String catalogName, CredentialProvider credentialProvider) { | ||
CredentialProvider current = credentialProviders.putIfAbsent(catalogName, credentialProvider); |
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 support one catalog with multiple credential vendors? If so, seems this map cannot support it.
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.
Not in current PR, I prefer to support it later in integrate Credential vending to Gravitino server to have a better overall design.
@@ -40,11 +39,12 @@ | |||
* gravitino.iceberg-rest.catalog.hive_proxy.catalog-backend = hive | |||
* gravitino.iceberg-rest.catalog.hive_proxy.uri = thrift://{host}:{port} ... | |||
*/ | |||
public class ConfigBasedIcebergCatalogWrapperProvider implements IcebergCatalogWrapperProvider { | |||
public class ConfigBasedIcebergCatalogConfigProvider implements IcebergCatalogConfigProvider { |
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 class name is a little tricky, is there a better name for it?
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.
FileBasedIcebergCatalogConfigProvider
or StaticIcebergCatalogConfigProvider
?
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.
FileBasedXXX and CatalogBasedXXX, how about this?
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.
CatalogBasedCatalogConfigProvider
seems a little odd
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.
use StaticCatalogConfigProvider
and DynamicCatalogConfigProvider
, cc @theoryxu
@HeaderParam(X_ICEBERG_ACCESS_DELEGATION) String accessDelegation) { | ||
boolean isCredentialVending = isCredentialVending(accessDelegation); | ||
LOG.info( | ||
"Load iceberg table, namespace: {}, table: {}, accessDelegation: {}, is credential vending: {}", |
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.
access delegation: {}..., credential vending: {}
Preconditions.checkState( | ||
!credentialProvider.equals(current), | ||
String.format( | ||
"Should not register multi times to CredentialProviderManager, catalog:%s, credential provider:%s", |
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.
"multiple times to..."
X_ICEBERG_ACCESS_DELEGATION | ||
+ ": " | ||
+ accessDelegation | ||
+ " is illegal, Iceberg REST spec supports:[vended-credentials,remote-signing], Gravitino Iceberg REST server supports: vended-credentials"); |
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.
This line is too long, it should be no longer than 100 chars.
X_ICEBERG_ACCESS_DELEGATION | ||
+ ": " | ||
+ accessDelegation | ||
+ " is illegal, Iceberg REST spec supports:[vended-credentials,remote-signing], Gravitino Iceberg REST server supports: vended-credentials"); |
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 (xxx.isBlank) {
return false;
}
if (xxx.equals...) {
return true;
}
if (xxx.equals...) {
throw xxx;
}
throw xxx;
}
Please fix the build issue here. |
updated, please help to review again |
…g REST server (apache#5134) ### What changes were proposed in this pull request? integrate credential framework to iceberg REST server ### Why are the changes needed? Fix: apache#4993 ### Does this PR introduce _any_ user-facing change? No ### How was this patch tested? set up a local environment to request credential with the configuration `spark.sql.catalog.rest.header.X-Iceberg-Access-Delegation=vended-credentials`
What changes were proposed in this pull request?
integrate credential framework to iceberg REST server
Why are the changes needed?
Fix: #4993
Does this PR introduce any user-facing change?
No
How was this patch tested?
set up a local environment to request credential with the configuration
spark.sql.catalog.rest.header.X-Iceberg-Access-Delegation=vended-credentials