Skip to content
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

Add a flag to control whether credentials are printed during bootstrapping #461

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -206,4 +206,11 @@ public static <T> Builder<T> builder() {
"If set to true, allows tables to be dropped with the purge parameter set to true.")
.defaultValue(true)
.build();

public static final PolarisConfiguration<Boolean> BOOTSTRAP_PRINT_CREDENTIALS =
PolarisConfiguration.<Boolean>builder()
.key("BOOTSTRAP_PRINT_CREDENTIALS")
.description("If set to true, credentials are printed to stdout by the bootstrap command")
.defaultValue(true)
.build();
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.Map;
import java.util.function.Supplier;
import org.apache.polaris.core.PolarisCallContext;
import org.apache.polaris.core.PolarisConfiguration;
import org.apache.polaris.core.PolarisDefaultDiagServiceImpl;
import org.apache.polaris.core.PolarisDiagnostics;
import org.apache.polaris.core.auth.PolarisSecretsManager.PrincipalSecretsResult;
Expand Down Expand Up @@ -76,17 +77,34 @@ private void initializeForRealm(RealmContext realmContext) {
}

@Override
public synchronized Map<String, PrincipalSecretsResult> bootstrapRealms(List<String> realms) {
public final synchronized Map<String, PrincipalSecretsResult> bootstrapRealms(
List<String> realms) {
Map<String, PrincipalSecretsResult> results = new HashMap<>();

for (String realm : realms) {
RealmContext realmContext = () -> realm;
if (!metaStoreManagerMap.containsKey(realmContext.getRealmIdentifier())) {
initializeForRealm(realmContext);
// While bootstrapping we need to act as a fake privileged context since the real
// CallContext hasn't even been resolved yet.
PolarisCallContext polarisContext =
new PolarisCallContext(
sessionSupplierMap.get(realmContext.getRealmIdentifier()).get(), diagServices);
PrincipalSecretsResult secretsResult =
bootstrapServiceAndCreatePolarisPrincipalForRealm(
realmContext, metaStoreManagerMap.get(realmContext.getRealmIdentifier()));
realmContext,
metaStoreManagerMap.get(realmContext.getRealmIdentifier()),
polarisContext);
results.put(realmContext.getRealmIdentifier(), secretsResult);
if (this.printCredentials(polarisContext)) {
String msg =
String.format(
"realm: %1s root principal credentials: %2s:%3s",
realmContext.getRealmIdentifier(),
secretsResult.getPrincipalSecrets().getPrincipalClientId(),
secretsResult.getPrincipalSecrets().getMainSecret());
System.out.println(msg);
}
}
}

Expand Down Expand Up @@ -158,12 +176,9 @@ public void setStorageIntegrationProvider(PolarisStorageIntegrationProvider stor
* credentials and print them to stdout
*/
private PrincipalSecretsResult bootstrapServiceAndCreatePolarisPrincipalForRealm(
RealmContext realmContext, PolarisMetaStoreManager metaStoreManager) {
// While bootstrapping we need to act as a fake privileged context since the real
// CallContext hasn't even been resolved yet.
PolarisCallContext polarisContext =
new PolarisCallContext(
sessionSupplierMap.get(realmContext.getRealmIdentifier()).get(), diagServices);
RealmContext realmContext,
PolarisMetaStoreManager metaStoreManager,
PolarisCallContext polarisContext) {
CallContext.setCurrentContext(CallContext.of(realmContext, polarisContext));

PolarisMetaStoreManager.EntityResult preliminaryRootPrincipalLookup =
Expand All @@ -181,6 +196,19 @@ private PrincipalSecretsResult bootstrapServiceAndCreatePolarisPrincipalForRealm
throw new IllegalArgumentException(overrideMessage);
}

// TODO rebase onto #422, call a method like PrincipalSecretsGenerator.hasEnvironmentVariables
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idea: maybe pass a flag down to PrincipalSecretsGenerator to not use random secrets if printCredentials is false? Then the PrincipalSecretsGenerator can simply throw if the specific realm/user combination is missing env. vars. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that idea. If there is a good pathway from the bootstrap command down to the PrincipalSecretsGenerator then I think that works as well. It should hopefully be more clear when #422 merges.

boolean environmentVariableCredentials = false;
if (!this.printCredentials(polarisContext) && !environmentVariableCredentials) {
String failureMessage =
String.format(
"It appears that environment variables were not provided for root credentials, and that printing "
+ "the root credentials is disabled via %s. If bootstrapping were to proceed, there would be no way "
+ "to recover the root credentials",
PolarisConfiguration.BOOTSTRAP_PRINT_CREDENTIALS.key);
LOGGER.error("\n\n {} \n\n", failureMessage);
throw new IllegalArgumentException(failureMessage);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea 👍

}

metaStoreManager.bootstrapPolarisService(polarisContext);

PolarisMetaStoreManager.EntityResult rootPrincipalLookup =
Expand Down Expand Up @@ -238,4 +266,11 @@ private void checkPolarisServiceBootstrappedForRealm(
"Realm is not bootstrapped, please run server in bootstrap mode.");
}
}

/** Whether or not to print credentials after bootstrapping */
protected boolean printCredentials(PolarisCallContext polarisCallContext) {
return polarisCallContext
.getConfigurationStore()
.getConfiguration(polarisCallContext, PolarisConfiguration.BOOTSTRAP_PRINT_CREDENTIALS);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,12 @@
package org.apache.polaris.service.persistence;

import com.fasterxml.jackson.annotation.JsonTypeName;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;
import org.apache.polaris.core.PolarisCallContext;
import org.apache.polaris.core.PolarisDiagnostics;
import org.apache.polaris.core.auth.PolarisSecretsManager.PrincipalSecretsResult;
import org.apache.polaris.core.context.RealmContext;
import org.apache.polaris.core.persistence.LocalPolarisMetaStoreManagerFactory;
import org.apache.polaris.core.persistence.PolarisMetaStoreManager;
Expand Down Expand Up @@ -55,7 +54,7 @@ public synchronized PolarisMetaStoreManager getOrCreateMetaStoreManager(
RealmContext realmContext) {
String realmId = realmContext.getRealmIdentifier();
if (!bootstrappedRealms.contains(realmId)) {
bootstrapRealmAndPrintCredentials(realmId);
bootstrapRealms(List.of(realmId));
}
return super.getOrCreateMetaStoreManager(realmContext);
}
Expand All @@ -65,24 +64,14 @@ public synchronized Supplier<PolarisMetaStoreSession> getOrCreateSessionSupplier
RealmContext realmContext) {
String realmId = realmContext.getRealmIdentifier();
if (!bootstrappedRealms.contains(realmId)) {
bootstrapRealmAndPrintCredentials(realmId);
bootstrapRealms(List.of(realmId));
}
return super.getOrCreateSessionSupplier(realmContext);
}

private void bootstrapRealmAndPrintCredentials(String realmId) {
Map<String, PrincipalSecretsResult> results =
this.bootstrapRealms(Collections.singletonList(realmId));
bootstrappedRealms.add(realmId);

PrincipalSecretsResult principalSecrets = results.get(realmId);

String msg =
String.format(
"realm: %1s root principal credentials: %2s:%3s",
realmId,
principalSecrets.getPrincipalSecrets().getPrincipalClientId(),
principalSecrets.getPrincipalSecrets().getMainSecret());
System.out.println(msg);
/** {@inheritDoc} */
@Override
protected boolean printCredentials(PolarisCallContext polarisCallContext) {
return true;
}
}