use of com.yahoo.vespa.hosted.controller.api.Tenant in project vespa by vespa-engine.
the class ApplicationOwnershipConfirmer method confirmApplicationOwnerships.
/**
* File an ownership issue with the owners of all applications we know about.
*/
private void confirmApplicationOwnerships() {
ApplicationList.from(controller().applications().asList()).notPullRequest().hasProductionDeployment().asList().forEach(application -> {
try {
Tenant tenant = ownerOf(application.id());
Optional<IssueId> ourIssueId = application.ownershipIssueId();
ourIssueId = tenant.tenantType() == TenantType.USER ? ownershipIssues.confirmOwnership(ourIssueId, application.id(), userFor(tenant)) : ownershipIssues.confirmOwnership(ourIssueId, application.id(), propertyIdFor(tenant));
ourIssueId.ifPresent(issueId -> store(issueId, application.id()));
} catch (RuntimeException e) {
// Catch errors due to wrong data in the controller, or issues client timeout.
log.log(Level.WARNING, "Exception caught when attempting to file an issue for " + application.id(), e);
}
});
}
use of com.yahoo.vespa.hosted.controller.api.Tenant in project vespa by vespa-engine.
the class ApplicationController method createApplication.
/**
* Creates a new application for an existing tenant.
*
* @throws IllegalArgumentException if the application already exists
*/
public Application createApplication(ApplicationId id, Optional<NToken> token) {
if (// TODO: Support instances properly
!(id.instance().isDefault() || id.instance().value().matches("\\d+")))
throw new UnsupportedOperationException("Only the instance names 'default' and names which are just the PR number are supported at the moment");
try (Lock lock = lock(id)) {
// Validate only application names which do not already exist.
if (asList(id.tenant()).stream().noneMatch(application -> application.id().application().equals(id.application())))
com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId.validate(id.application().value());
Optional<Tenant> tenant = controller.tenants().tenant(new TenantId(id.tenant().value()));
if (!tenant.isPresent())
throw new IllegalArgumentException("Could not create '" + id + "': This tenant does not exist");
if (get(id).isPresent())
throw new IllegalArgumentException("Could not create '" + id + "': Application already exists");
if (// VESPA-1945
get(dashToUnderscore(id)).isPresent())
throw new IllegalArgumentException("Could not create '" + id + "': Application " + dashToUnderscore(id) + " already exists");
if (id.instance().isDefault() && tenant.get().isAthensTenant()) {
// Only create the athens application for "default" instances.
if (!token.isPresent())
throw new IllegalArgumentException("Could not create '" + id + "': No NToken provided");
ZmsClient zmsClient = zmsClientFactory.createZmsClientWithAuthorizedServiceToken(token.get());
zmsClient.addApplication(tenant.get().getAthensDomain().get(), new com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId(id.application().value()));
}
LockedApplication application = new LockedApplication(new Application(id), lock);
store(application);
log.info("Created " + application);
return application;
}
}
use of com.yahoo.vespa.hosted.controller.api.Tenant in project vespa by vespa-engine.
the class ApplicationController method deleteApplication.
/**
* Deletes the the given application. All known instances of the applications will be deleted,
* including PR instances.
*
* @throws IllegalArgumentException if the application has deployments or the caller is not authorized
* @throws NotExistsException if no instances of the application exist
*/
public void deleteApplication(ApplicationId applicationId, Optional<NToken> token) {
// Find all instances of the application
List<ApplicationId> instances = controller.applications().asList(applicationId.tenant()).stream().map(Application::id).filter(id -> id.application().equals(applicationId.application()) && id.tenant().equals(applicationId.tenant())).collect(Collectors.toList());
if (instances.isEmpty()) {
throw new NotExistsException("Could not delete application '" + applicationId + "': Application not found");
}
// TODO: Make this one transaction when database is moved to ZooKeeper
instances.forEach(id -> lockOrThrow(id, application -> {
if (!application.deployments().isEmpty())
throw new IllegalArgumentException("Could not delete '" + application + "': It has active deployments");
Tenant tenant = controller.tenants().tenant(new TenantId(id.tenant().value())).get();
if (tenant.isAthensTenant() && !token.isPresent())
throw new IllegalArgumentException("Could not delete '" + application + "': No NToken provided");
// Only delete in Athenz once
if (id.instance().isDefault() && tenant.isAthensTenant()) {
zmsClientFactory.createZmsClientWithAuthorizedServiceToken(token.get()).deleteApplication(tenant.getAthensDomain().get(), new com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId(id.application().value()));
}
db.deleteApplication(id);
log.info("Deleted " + application);
}));
}
use of com.yahoo.vespa.hosted.controller.api.Tenant in project vespa by vespa-engine.
the class TenantController method internalCreateTenant.
private void internalCreateTenant(Tenant tenant, Optional<NToken> token) {
TenantId.validate(tenant.getId().id());
if (tenant(tenant.getId()).isPresent())
throw new IllegalArgumentException("Tenant '" + tenant.getId() + "' already exists");
if (tenant(dashToUnderscore(tenant.getId())).isPresent())
throw new IllegalArgumentException("Could not create " + tenant + ": Tenant " + dashToUnderscore(tenant.getId()) + " already exists");
if (tenant.isAthensTenant() && !token.isPresent())
throw new IllegalArgumentException("Could not create " + tenant + ": No NToken provided");
if (tenant.isAthensTenant()) {
AthenzDomain domain = tenant.getAthensDomain().get();
Optional<Tenant> existingTenantWithDomain = tenantHaving(domain);
if (existingTenantWithDomain.isPresent())
throw new IllegalArgumentException("Could not create " + tenant + ": The Athens domain '" + domain.getName() + "' is already connected to " + existingTenantWithDomain.get());
athenzClientFactory.createZmsClientWithAuthorizedServiceToken(token.get()).createTenant(domain);
}
db.createTenant(tenant);
log.info("Created " + tenant);
}
use of com.yahoo.vespa.hosted.controller.api.Tenant in project vespa by vespa-engine.
the class TenantController method deleteTenant.
public void deleteTenant(TenantId id, Optional<NToken> token) {
try (Lock lock = lock(id)) {
if (!tenant(id).isPresent())
// TODO: Change exception and message
throw new NotExistsException(id);
if (!controller.applications().asList(TenantName.from(id.id())).isEmpty())
throw new IllegalArgumentException("Could not delete tenant '" + id + "': This tenant has active applications");
Tenant tenant = tenant(id).get();
if (tenant.isAthensTenant() && !token.isPresent())
throw new IllegalArgumentException("Could not delete tenant '" + id + "': No NToken provided");
try {
db.deleteTenant(id);
} catch (PersistenceException e) {
// TODO: Don't allow these to leak out
throw new RuntimeException(e);
}
if (tenant.isAthensTenant())
athenzClientFactory.createZmsClientWithAuthorizedServiceToken(token.get()).deleteTenant(tenant.getAthensDomain().get());
log.info("Deleted " + tenant);
}
}
Aggregations