in catalogs/catalog-hive/src/main/java/org/apache/gravitino/catalog/hive/HiveCatalogOperations.java [176:267]
private void initKerberosIfNecessary(Map<String, String> conf, Configuration hadoopConf) {
if (UserGroupInformation.AuthenticationMethod.KERBEROS
== SecurityUtil.getAuthenticationMethod(hadoopConf)) {
try {
Path keytabsPath = Paths.get("keytabs");
if (!Files.exists(keytabsPath)) {
// Ignore the return value, because there exists many Hive catalog operations making
// this directory.
Files.createDirectory(keytabsPath);
}
// The id of entity is a random unique id.
Path keytabPath = Paths.get(String.format(GRAVITINO_KEYTAB_FORMAT, info.id()));
keytabPath.toFile().deleteOnExit();
if (Files.exists(keytabPath)) {
try {
Files.delete(keytabPath);
} catch (IOException e) {
throw new IllegalStateException(
String.format("Fail to delete keytab file %s", keytabPath.toAbsolutePath()), e);
}
}
String keytabUri =
(String)
propertiesMetadata
.catalogPropertiesMetadata()
.getOrDefault(conf, HiveCatalogPropertiesMetadata.KEY_TAB_URI);
Preconditions.checkArgument(StringUtils.isNotBlank(keytabUri), "Keytab uri can't be blank");
// TODO: Support to download the file from Kerberos HDFS
Preconditions.checkArgument(
!keytabUri.trim().startsWith("hdfs"), "Keytab uri doesn't support to use HDFS");
int fetchKeytabFileTimeout =
(int)
propertiesMetadata
.catalogPropertiesMetadata()
.getOrDefault(conf, HiveCatalogPropertiesMetadata.FETCH_TIMEOUT_SEC);
FetchFileUtils.fetchFileFromUri(
keytabUri, keytabPath.toFile(), fetchKeytabFileTimeout, hadoopConf);
hiveConf.setVar(
ConfVars.METASTORE_KERBEROS_KEYTAB_FILE, keytabPath.toAbsolutePath().toString());
String catalogPrincipal =
(String) propertiesMetadata.catalogPropertiesMetadata().getOrDefault(conf, PRINCIPAL);
Preconditions.checkArgument(
StringUtils.isNotBlank(catalogPrincipal), "The principal can't be blank");
@SuppressWarnings("null")
List<String> principalComponents = Splitter.on('@').splitToList(catalogPrincipal);
Preconditions.checkArgument(
principalComponents.size() == 2, "The principal has the wrong format");
this.kerberosRealm = principalComponents.get(1);
checkTgtExecutor =
new ScheduledThreadPoolExecutor(
1, getThreadFactory(String.format("Kerberos-check-%s", info.id())));
LOG.info("krb5 path: {}", System.getProperty("java.security.krb5.conf"));
refreshKerberosConfig();
UserGroupInformation.setConfiguration(hadoopConf);
UserGroupInformation.loginUserFromKeytab(
catalogPrincipal, keytabPath.toAbsolutePath().toString());
UserGroupInformation kerberosLoginUgi = UserGroupInformation.getCurrentUser();
int checkInterval =
(int)
propertiesMetadata
.catalogPropertiesMetadata()
.getOrDefault(conf, HiveCatalogPropertiesMetadata.CHECK_INTERVAL_SEC);
checkTgtExecutor.scheduleAtFixedRate(
() -> {
try {
kerberosLoginUgi.checkTGTAndReloginFromKeytab();
} catch (Exception e) {
LOG.error("Fail to refresh ugi token: ", e);
}
},
checkInterval,
checkInterval,
TimeUnit.SECONDS);
} catch (IOException ioe) {
throw new UncheckedIOException(ioe);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}