Search in sources :

Example 11 with Tenant

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);
        }
    });
}
Also used : Tenant(com.yahoo.vespa.hosted.controller.api.Tenant) IssueId(com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId)

Example 12 with Tenant

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;
    }
}
Also used : Lock(com.yahoo.vespa.curator.Lock) RotationLock(com.yahoo.vespa.hosted.controller.rotation.RotationLock) TenantId(com.yahoo.vespa.hosted.controller.api.identifiers.TenantId) Tenant(com.yahoo.vespa.hosted.controller.api.Tenant) ZmsClient(com.yahoo.vespa.hosted.controller.api.integration.athenz.ZmsClient)

Example 13 with Tenant

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);
    }));
}
Also used : ArtifactRepository(com.yahoo.vespa.hosted.controller.api.integration.deployment.ArtifactRepository) ZmsClient(com.yahoo.vespa.hosted.controller.api.integration.athenz.ZmsClient) EndpointStatus(com.yahoo.vespa.hosted.controller.api.application.v4.model.EndpointStatus) DeploymentTrigger(com.yahoo.vespa.hosted.controller.deployment.DeploymentTrigger) URISyntaxException(java.net.URISyntaxException) DeploymentJobs(com.yahoo.vespa.hosted.controller.application.DeploymentJobs) ValidationId(com.yahoo.config.application.api.ValidationId) JobReport(com.yahoo.vespa.hosted.controller.application.DeploymentJobs.JobReport) TenantName(com.yahoo.config.provision.TenantName) Tenant(com.yahoo.vespa.hosted.controller.api.Tenant) ZoneId(com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneId) DeploymentExpirer(com.yahoo.vespa.hosted.controller.maintenance.DeploymentExpirer) RevisionId(com.yahoo.vespa.hosted.controller.api.identifiers.RevisionId) Duration(java.time.Duration) Map(java.util.Map) DeployOptions(com.yahoo.vespa.hosted.controller.api.application.v4.model.DeployOptions) URI(java.net.URI) Rotation(com.yahoo.vespa.hosted.controller.rotation.Rotation) Exceptions(com.yahoo.yolean.Exceptions) RotationRepository(com.yahoo.vespa.hosted.controller.rotation.RotationRepository) ApplicationVersion(com.yahoo.vespa.hosted.controller.application.ApplicationVersion) Set(java.util.Set) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) List(java.util.List) Optional(java.util.Optional) Deployment(com.yahoo.vespa.hosted.controller.application.Deployment) RotationsConfig(com.yahoo.vespa.hosted.rotation.config.RotationsConfig) Log(com.yahoo.vespa.hosted.controller.api.integration.configserver.Log) AthenzClientFactory(com.yahoo.vespa.hosted.controller.api.integration.athenz.AthenzClientFactory) Version(com.yahoo.component.Version) ApplicationId(com.yahoo.config.provision.ApplicationId) DeploymentId(com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId) RecordId(com.yahoo.vespa.hosted.controller.api.integration.dns.RecordId) ConfigServerClient(com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServerClient) HashMap(java.util.HashMap) NToken(com.yahoo.vespa.athenz.api.NToken) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) HashSet(java.util.HashSet) ConfigChangeActions(com.yahoo.vespa.hosted.controller.api.application.v4.model.configserverbindings.ConfigChangeActions) ImmutableList(com.google.common.collect.ImmutableList) TenantId(com.yahoo.vespa.hosted.controller.api.identifiers.TenantId) RecordData(com.yahoo.vespa.hosted.controller.api.integration.dns.RecordData) RoutingEndpoint(com.yahoo.vespa.hosted.controller.api.integration.routing.RoutingEndpoint) RoutingGenerator(com.yahoo.vespa.hosted.controller.api.integration.routing.RoutingGenerator) ActivateResult(com.yahoo.vespa.hosted.controller.api.ActivateResult) NoInstanceException(com.yahoo.vespa.hosted.controller.api.integration.configserver.NoInstanceException) Lock(com.yahoo.vespa.curator.Lock) Hostname(com.yahoo.vespa.hosted.controller.api.identifiers.Hostname) Environment(com.yahoo.config.provision.Environment) ControllerDb(com.yahoo.vespa.hosted.controller.persistence.ControllerDb) CuratorDb(com.yahoo.vespa.hosted.controller.persistence.CuratorDb) IOException(java.io.IOException) ApplicationPackage(com.yahoo.vespa.hosted.controller.application.ApplicationPackage) Consumer(java.util.function.Consumer) Pair(com.yahoo.collections.Pair) DeploymentSpec(com.yahoo.config.application.api.DeploymentSpec) RecordName(com.yahoo.vespa.hosted.controller.api.integration.dns.RecordName) Clock(java.time.Clock) NameService(com.yahoo.vespa.hosted.controller.api.integration.dns.NameService) PrepareResponse(com.yahoo.vespa.hosted.controller.api.integration.configserver.PrepareResponse) Collections(java.util.Collections) Record(com.yahoo.vespa.hosted.controller.api.integration.dns.Record) RotationLock(com.yahoo.vespa.hosted.controller.rotation.RotationLock) TenantId(com.yahoo.vespa.hosted.controller.api.identifiers.TenantId) Tenant(com.yahoo.vespa.hosted.controller.api.Tenant) ApplicationId(com.yahoo.config.provision.ApplicationId)

Example 14 with Tenant

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);
}
Also used : Tenant(com.yahoo.vespa.hosted.controller.api.Tenant) AthenzDomain(com.yahoo.vespa.athenz.api.AthenzDomain)

Example 15 with 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);
    }
}
Also used : Tenant(com.yahoo.vespa.hosted.controller.api.Tenant) PersistenceException(com.yahoo.vespa.hosted.controller.persistence.PersistenceException) Lock(com.yahoo.vespa.curator.Lock)

Aggregations

Tenant (com.yahoo.vespa.hosted.controller.api.Tenant)18 TenantId (com.yahoo.vespa.hosted.controller.api.identifiers.TenantId)11 AthenzDomain (com.yahoo.vespa.athenz.api.AthenzDomain)7 Inspector (com.yahoo.slime.Inspector)5 Cursor (com.yahoo.slime.Cursor)4 Slime (com.yahoo.slime.Slime)4 NToken (com.yahoo.vespa.athenz.api.NToken)4 Lock (com.yahoo.vespa.curator.Lock)4 EndpointStatus (com.yahoo.vespa.hosted.controller.api.application.v4.model.EndpointStatus)4 Version (com.yahoo.component.Version)3 DeploymentSpec (com.yahoo.config.application.api.DeploymentSpec)3 ApplicationId (com.yahoo.config.provision.ApplicationId)3 Environment (com.yahoo.config.provision.Environment)3 TenantName (com.yahoo.config.provision.TenantName)3 ActivateResult (com.yahoo.vespa.hosted.controller.api.ActivateResult)3 DeployOptions (com.yahoo.vespa.hosted.controller.api.application.v4.model.DeployOptions)3 DeploymentId (com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId)3 Property (com.yahoo.vespa.hosted.controller.api.identifiers.Property)3 ApplicationPackage (com.yahoo.vespa.hosted.controller.application.ApplicationPackage)3 SlimeJsonResponse (com.yahoo.vespa.hosted.controller.restapi.SlimeJsonResponse)3