use of io.cdap.cdap.proto.id.KerberosPrincipalId in project cdap by caskdata.
the class ProgramRunners method getApplicationPrincipal.
/**
* Returns the application principal if there is one.
*
* @param programOptions the program options to extract information from
* @return the application principal or {@code null} if no application principal is available.
*/
@Nullable
public static KerberosPrincipalId getApplicationPrincipal(ProgramOptions programOptions) {
Arguments systemArgs = programOptions.getArguments();
boolean hasAppPrincipal = Boolean.parseBoolean(systemArgs.getOption(ProgramOptionConstants.APP_PRINCIPAL_EXISTS));
return hasAppPrincipal ? new KerberosPrincipalId(systemArgs.getOption(ProgramOptionConstants.PRINCIPAL)) : null;
}
use of io.cdap.cdap.proto.id.KerberosPrincipalId in project cdap by caskdata.
the class DefaultNamespaceAdmin method create.
/**
* Creates a new namespace
*
* @param metadata the {@link NamespaceMeta} for the new namespace to be created
* @throws NamespaceAlreadyExistsException if the specified namespace already exists
*/
@Override
public synchronized void create(final NamespaceMeta metadata) throws Exception {
// TODO: CDAP-1427 - This should be transactional, but we don't support transactions on files yet
Preconditions.checkArgument(metadata != null, "Namespace metadata should not be null.");
NamespaceId namespace = metadata.getNamespaceId();
if (exists(namespace)) {
throw new NamespaceAlreadyExistsException(namespace);
}
// need to enforce on the principal id if impersonation is involved
String ownerPrincipal = metadata.getConfig().getPrincipal();
Principal requestingUser = authenticationContext.getPrincipal();
if (ownerPrincipal != null) {
accessEnforcer.enforce(new KerberosPrincipalId(ownerPrincipal), requestingUser, AccessPermission.SET_OWNER);
}
accessEnforcer.enforce(namespace, requestingUser, StandardPermission.CREATE);
// If this namespace has custom mapping then validate the given custom mapping
if (hasCustomMapping(metadata)) {
validateCustomMapping(metadata);
}
// check that the user has configured either both or none of the following configuration: principal and keytab URI
boolean hasValidKerberosConf = false;
if (metadata.getConfig() != null) {
String configuredPrincipal = metadata.getConfig().getPrincipal();
String configuredKeytabURI = metadata.getConfig().getKeytabURI();
if ((!Strings.isNullOrEmpty(configuredPrincipal) && Strings.isNullOrEmpty(configuredKeytabURI)) || (Strings.isNullOrEmpty(configuredPrincipal) && !Strings.isNullOrEmpty(configuredKeytabURI))) {
throw new BadRequestException(String.format("Either both or none of the following two configurations must be configured. " + "Configured principal: %s, Configured keytabURI: %s", configuredPrincipal, configuredKeytabURI));
}
hasValidKerberosConf = true;
}
// check that if explore as principal is explicitly set to false then user has kerberos configuration
if (!metadata.getConfig().isExploreAsPrincipal() && !hasValidKerberosConf) {
throw new BadRequestException(String.format("No kerberos principal or keytab-uri was provided while '%s' was set to true.", NamespaceConfig.EXPLORE_AS_PRINCIPAL));
}
// store the meta first in the namespace store because namespacedLocationFactory needs to look up location
// mapping from namespace config
nsStore.create(metadata);
try {
UserGroupInformation ugi;
if (NamespaceId.DEFAULT.equals(namespace)) {
ugi = UserGroupInformation.getCurrentUser();
} else {
ugi = impersonator.getUGI(namespace);
}
ImpersonationUtils.doAs(ugi, (Callable<Void>) () -> {
storageProviderNamespaceAdmin.get().create(metadata);
return null;
});
// if needed, run master environment specific logic
MasterEnvironment masterEnv = MasterEnvironments.getMasterEnvironment();
if (masterEnv != null) {
masterEnv.onNamespaceCreation(namespace.getNamespace(), metadata.getConfig().getConfigs());
}
} catch (Throwable t) {
LOG.error(String.format("Failed to create namespace '%s'", namespace.getNamespace()), t);
// failed to create namespace in underlying storage so delete the namespace meta stored in the store earlier
deleteNamespaceMeta(metadata.getNamespaceId());
throw new NamespaceCannotBeCreatedException(namespace, t);
}
emitNamespaceCountMetric();
LOG.info("Namespace {} created with meta {}", metadata.getNamespaceId(), metadata);
}
use of io.cdap.cdap.proto.id.KerberosPrincipalId in project cdap by caskdata.
the class CreateDatasetInstancesStage method process.
/**
* Receives an input containing application specification and location
* and verifies both.
*
* @param input An instance of {@link ApplicationDeployable}
*/
@Override
public void process(ApplicationDeployable input) throws Exception {
// create dataset instances
ApplicationSpecification specification = input.getSpecification();
NamespaceId namespaceId = input.getApplicationId().getParent();
KerberosPrincipalId ownerPrincipal = input.getOwnerPrincipal();
// get the authorizing user
String authorizingUser = AuthorizationUtil.getAppAuthorizingUser(ownerAdmin, authenticationContext, input.getApplicationId(), ownerPrincipal);
datasetInstanceCreator.createInstances(namespaceId, specification.getDatasets(), ownerPrincipal, authorizingUser);
// Emit the input to next stage.
emit(input);
}
use of io.cdap.cdap.proto.id.KerberosPrincipalId in project cdap by caskdata.
the class DeployDatasetModulesStage method process.
/**
* Deploys dataset modules specified in the given application spec.
*
* @param input An instance of {@link ApplicationDeployable}
*/
@Override
public void process(ApplicationDeployable input) throws Exception {
Map<String, String> datasetModules = input.getSpecification().getDatasetModules();
if (allowCustomModule) {
KerberosPrincipalId ownerPrincipal = input.getOwnerPrincipal();
// get the authorizing user
String authorizingUser = AuthorizationUtil.getAppAuthorizingUser(ownerAdmin, authenticationContext, input.getApplicationId(), ownerPrincipal);
EntityImpersonator classLoaderImpersonator = new EntityImpersonator(input.getArtifactId(), impersonator);
try (CloseableClassLoader classLoader = artifactRepository.createArtifactClassLoader(new ArtifactDescriptor(input.getArtifactId().getNamespace(), input.getArtifactId().toApiArtifactId(), input.getArtifactLocation()), classLoaderImpersonator)) {
deployer.deployModules(input.getApplicationId().getParent(), datasetModules, input.getArtifactLocation(), classLoader, authorizingUser);
}
} else if (deployer.hasNonSystemDatasetModules(datasetModules)) {
throw new IllegalStateException("Custom dataset module is not supported. " + "One of the dataset module is a custom module: " + datasetModules);
}
// Emit the input to next stage.
emit(input);
}
use of io.cdap.cdap.proto.id.KerberosPrincipalId in project cdap by caskdata.
the class AppLifecycleHttpHandler method deployAppFromArtifact.
// normally we wouldn't want to use a body consumer but would just want to read the request body directly
// since it wont be big. But the deploy app API has one path with different behavior based on content type
// the other behavior requires a BodyConsumer and only have one method per path is allowed,
// so we have to use a BodyConsumer
private BodyConsumer deployAppFromArtifact(final ApplicationId appId) throws IOException {
// Perform auth checks outside BodyConsumer as only the first http request containing auth header
// to populate SecurityRequestContext while http chunk doesn't. BodyConsumer runs in the thread
// that processes the last http chunk.
accessEnforcer.enforce(appId, authenticationContext.getPrincipal(), StandardPermission.CREATE);
// createTempFile() needs a prefix of at least 3 characters
return new AbstractBodyConsumer(File.createTempFile("apprequest-" + appId, ".json", tmpDir)) {
@Override
protected void onFinish(HttpResponder responder, File uploadedFile) {
try (FileReader fileReader = new FileReader(uploadedFile)) {
AppRequest<?> appRequest = DECODE_GSON.fromJson(fileReader, AppRequest.class);
ArtifactSummary artifactSummary = appRequest.getArtifact();
KerberosPrincipalId ownerPrincipalId = appRequest.getOwnerPrincipal() == null ? null : new KerberosPrincipalId(appRequest.getOwnerPrincipal());
// if we don't null check, it gets serialized to "null"
Object config = appRequest.getConfig();
String configString = config == null ? null : config instanceof String ? (String) config : GSON.toJson(config);
try {
applicationLifecycleService.deployApp(appId.getParent(), appId.getApplication(), appId.getVersion(), artifactSummary, configString, createProgramTerminator(), ownerPrincipalId, appRequest.canUpdateSchedules(), false, Collections.emptyMap());
} catch (DatasetManagementException e) {
if (e.getCause() instanceof UnauthorizedException) {
throw (UnauthorizedException) e.getCause();
} else {
throw e;
}
}
responder.sendString(HttpResponseStatus.OK, "Deploy Complete");
} catch (ArtifactNotFoundException e) {
responder.sendString(HttpResponseStatus.NOT_FOUND, e.getMessage());
} catch (ConflictException e) {
responder.sendString(HttpResponseStatus.CONFLICT, e.getMessage());
} catch (UnauthorizedException e) {
responder.sendString(HttpResponseStatus.FORBIDDEN, e.getMessage());
} catch (InvalidArtifactException e) {
responder.sendString(HttpResponseStatus.BAD_REQUEST, e.getMessage());
} catch (IOException e) {
LOG.error("Error reading request body for creating app {}.", appId);
responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, String.format("Error while reading json request body for app %s.", appId));
} catch (Exception e) {
LOG.error("Deploy failure", e);
responder.sendString(HttpResponseStatus.BAD_REQUEST, e.getMessage());
}
}
};
}
Aggregations