summaryrefslogtreecommitdiffstats
path: root/controller-server
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2019-03-22 09:55:06 +0000
committerGitHub <noreply@github.com>2019-03-22 09:55:06 +0000
commit4e6fb9a6ddcb917ef34cf62b3ec7363c241883a5 (patch)
treedf1d38c5b00f59d6855e46a523c4b79ae4d3a38c /controller-server
parentac38d5f22521a721b7df520082d0648a1da11aa5 (diff)
parentc97621406dc6c21918189f9df7e6a650bb81beac (diff)
Merge pull request #8871 from vespa-engine/jvenstad/remove-more-athenz-references
Jvenstad/remove more athenz references
Diffstat (limited to 'controller-server')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java16
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java6
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/TenantController.java14
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java35
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java117
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/AthenzAccessControlRequests.java17
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/AthenzCredentials.java4
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/AthenzTenantSpec.java12
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/TenantSpec.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java10
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java4
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant-with-contact-info.json4
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant2.json4
13 files changed, 113 insertions, 132 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
index b791852cba0..d68c5caf685 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
@@ -10,7 +10,7 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.TenantName;
import com.yahoo.vespa.athenz.api.AthenzDomain;
-import com.yahoo.vespa.athenz.api.AthenzIdentity;
+import com.yahoo.vespa.athenz.api.AthenzPrincipal;
import com.yahoo.vespa.athenz.api.AthenzUser;
import com.yahoo.vespa.curator.Lock;
import com.yahoo.vespa.hosted.controller.api.ActivateResult;
@@ -262,7 +262,7 @@ public class ApplicationController {
Optional<ApplicationPackage> applicationPackageFromDeployer,
Optional<ApplicationVersion> applicationVersionFromDeployer,
DeployOptions options,
- Optional<AthenzIdentity> deployingIdentity) {
+ Optional<Principal> deployingIdentity) {
if (applicationId.instance().isTester())
throw new IllegalArgumentException("'" + applicationId + "' is a tester application!");
@@ -727,10 +727,13 @@ public class ApplicationController {
* @param applicationPackage Application package
* @param deployer Principal initiating the deployment, possibly empty
*/
- public void verifyApplicationIdentityConfiguration(TenantName tenantName, ApplicationPackage applicationPackage, Optional<AthenzIdentity> deployer) {
+ public void verifyApplicationIdentityConfiguration(TenantName tenantName, ApplicationPackage applicationPackage, Optional<Principal> deployer) {
applicationPackage.deploymentSpec().athenzDomain().ifPresent(identityDomain -> {
Tenant tenant = controller.tenants().require(tenantName);
- deployer.filter(AthenzUser.class::isInstance)
+ deployer.filter(AthenzPrincipal.class::isInstance)
+ .map(AthenzPrincipal.class::cast)
+ .map(AthenzPrincipal::getIdentity)
+ .filter(AthenzUser.class::isInstance)
.ifPresentOrElse(user -> {
if ( ! ((AthenzFacade) accessControl).hasTenantAdminAccess(user, new AthenzDomain(identityDomain.value())))
throw new IllegalArgumentException("User " + user.getFullName() + " is not allowed to launch " +
@@ -758,9 +761,4 @@ public class ApplicationController {
.max(naturalOrder());
}
- private boolean isUserDeployment(Optional<AthenzIdentity> identity) {
- return identity
- .filter(id -> id instanceof AthenzUser)
- .isPresent();
- }
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java
index 5c9be7a34a3..e81c4d165f1 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java
@@ -8,14 +8,12 @@ import com.yahoo.component.Vtag;
import com.yahoo.config.provision.CloudName;
import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.SystemName;
-import com.yahoo.vespa.athenz.api.AthenzDomain;
import com.yahoo.vespa.curator.Lock;
import com.yahoo.vespa.hosted.controller.api.identifiers.Property;
import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId;
import com.yahoo.vespa.hosted.controller.api.integration.BuildService;
import com.yahoo.vespa.hosted.controller.api.integration.MetricsService;
import com.yahoo.vespa.hosted.controller.api.integration.RunDataStore;
-import com.yahoo.vespa.hosted.controller.api.integration.athenz.AthenzClientFactory;
import com.yahoo.vespa.hosted.controller.api.integration.chef.Chef;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServer;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationStore;
@@ -28,11 +26,10 @@ import com.yahoo.vespa.hosted.controller.api.integration.organization.Mailer;
import com.yahoo.vespa.hosted.controller.api.integration.routing.RoutingGenerator;
import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneId;
import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneRegistry;
-import com.yahoo.vespa.hosted.controller.athenz.impl.AthenzFacade;
import com.yahoo.vespa.hosted.controller.auditlog.AuditLogger;
import com.yahoo.vespa.hosted.controller.deployment.JobController;
-import com.yahoo.vespa.hosted.controller.security.AccessControl;
import com.yahoo.vespa.hosted.controller.persistence.CuratorDb;
+import com.yahoo.vespa.hosted.controller.security.AccessControl;
import com.yahoo.vespa.hosted.controller.versions.OsVersion;
import com.yahoo.vespa.hosted.controller.versions.OsVersionStatus;
import com.yahoo.vespa.hosted.controller.versions.VersionStatus;
@@ -42,7 +39,6 @@ import com.yahoo.vespa.serviceview.bindings.ApplicationView;
import java.time.Clock;
import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/TenantController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/TenantController.java
index ad2bbef4140..e8b3e334631 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/TenantController.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/TenantController.java
@@ -4,11 +4,10 @@ package com.yahoo.vespa.hosted.controller;
import com.yahoo.config.provision.TenantName;
import com.yahoo.vespa.curator.Lock;
import com.yahoo.vespa.hosted.controller.concurrent.Once;
+import com.yahoo.vespa.hosted.controller.persistence.CuratorDb;
import com.yahoo.vespa.hosted.controller.security.AccessControl;
import com.yahoo.vespa.hosted.controller.security.Credentials;
import com.yahoo.vespa.hosted.controller.security.TenantSpec;
-import com.yahoo.vespa.hosted.controller.persistence.CuratorDb;
-import com.yahoo.vespa.hosted.controller.tenant.AthenzTenant;
import com.yahoo.vespa.hosted.controller.tenant.Tenant;
import com.yahoo.vespa.hosted.controller.tenant.UserTenant;
@@ -122,7 +121,8 @@ public class TenantController {
/** Updates the tenant contained in the given tenant spec with new data. */
public void update(TenantSpec tenantSpec, Credentials credentials) {
try (Lock lock = lock(tenantSpec.tenant())) {
- curator.writeTenant(accessControl.updateTenant(tenantSpec, credentials, asList(), controller.applications().asList(tenantSpec.tenant())));
+ curator.writeTenant(accessControl.updateTenant(tenantSpec, credentials, asList(),
+ controller.applications().asList(tenantSpec.tenant())));
}
}
@@ -148,9 +148,9 @@ public class TenantController {
private void requireNonExistent(TenantName name) {
if (get(name).isPresent() ||
- // Underscores are allowed in existing Athenz tenant names, but tenants with - and _ cannot co-exist. E.g.
+ // Underscores are allowed in existing tenant names, but tenants with - and _ cannot co-exist. E.g.
// my-tenant cannot be created if my_tenant exists.
- get(dashToUnderscore(name.value())).isPresent()) {
+ get(name.value().replace('-', '_')).isPresent()) {
throw new IllegalArgumentException("Tenant '" + name + "' already exists");
}
}
@@ -164,8 +164,4 @@ public class TenantController {
return curator.lock(tenant);
}
- private static String dashToUnderscore(String s) {
- return s.replace('-', '_');
- }
-
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java
index 68b8535ff10..431020b735b 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java
@@ -62,7 +62,7 @@ public class AthenzFacade implements AccessControl {
public Tenant createTenant(TenantSpec tenantSpec, Credentials credentials, List<Tenant> existing) {
AthenzTenantSpec spec = (AthenzTenantSpec) tenantSpec;
AthenzCredentials athenzCredentials = (AthenzCredentials) credentials;
- AthenzDomain domain = athenzCredentials.domain();
+ AthenzDomain domain = spec.domain();
verifyIsDomainAdmin(athenzCredentials.user().getIdentity(), domain);
@@ -73,7 +73,7 @@ public class AthenzFacade implements AccessControl {
AthenzTenant tenant = AthenzTenant.create(spec.tenant(),
domain,
- spec.property().orElseThrow(() -> new IllegalArgumentException("Must provide property.")),
+ spec.property(),
spec.propertyId());
if (existingWithSameDomain.isPresent()) { // Throw if domain is already taken.
@@ -94,43 +94,40 @@ public class AthenzFacade implements AccessControl {
public Tenant updateTenant(TenantSpec tenantSpec, Credentials credentials, List<Tenant> existing, List<Application> applications) {
AthenzTenantSpec spec = (AthenzTenantSpec) tenantSpec;
AthenzCredentials athenzCredentials = (AthenzCredentials) credentials;
- AthenzDomain domain = athenzCredentials.domain();
+ AthenzDomain newDomain = spec.domain();
+ AthenzDomain oldDomain = athenzCredentials.domain();
- verifyIsDomainAdmin(athenzCredentials.user().getIdentity(), domain);
+ verifyIsDomainAdmin(athenzCredentials.user().getIdentity(), newDomain);
Optional<Tenant> existingWithSameDomain = existing.stream()
.filter(tenant -> tenant.type() == Tenant.Type.athenz
- && domain.equals(((AthenzTenant) tenant).domain()))
+ && newDomain.equals(((AthenzTenant) tenant).domain()))
.findAny();
Tenant tenant = AthenzTenant.create(spec.tenant(),
- domain,
- spec.property().orElseThrow(() -> new IllegalArgumentException("Must provide property.")),
+ newDomain,
+ spec.property(),
spec.propertyId());
- int index = existing.indexOf(tenant);
- if (index == -1) throw new IllegalArgumentException("Cannot update a non-existent tenant.");
- AthenzTenant oldTenant = (AthenzTenant) existing.get(index);
-
if (existingWithSameDomain.isPresent()) { // Throw if domain taken by someone else, or do nothing if taken by this tenant.
- if ( ! existingWithSameDomain.get().equals(oldTenant))
+ if ( ! existingWithSameDomain.get().equals(tenant)) // Equality by name.
throw new IllegalArgumentException("Could not create tenant '" + spec.tenant().value() +
"': The Athens domain '" +
- domain.getName() + "' is already connected to tenant '" +
+ newDomain.getName() + "' is already connected to tenant '" +
existingWithSameDomain.get().name().value() + "'");
return tenant; // Short-circuit here if domain is still the same.
}
else { // Delete and recreate tenant, and optionally application, resources in Athenz otherwise.
- log("createTenancy(tenantDomain=%s, service=%s)", domain, service);
- zmsClient.createTenancy(domain, service, athenzCredentials.token());
+ log("createTenancy(tenantDomain=%s, service=%s)", newDomain, service);
+ zmsClient.createTenancy(newDomain, service, athenzCredentials.token());
for (Application application : applications)
- createApplication(domain, application.id().application(), athenzCredentials.token());
+ createApplication(newDomain, application.id().application(), athenzCredentials.token());
- log("deleteTenancy(tenantDomain=%s, service=%s)", oldTenant.domain(), service);
+ log("deleteTenancy(tenantDomain=%s, service=%s)", oldDomain, service);
for (Application application : applications)
- deleteApplication(oldTenant.domain(), application.id().application(), athenzCredentials.token());
- zmsClient.deleteTenancy(oldTenant.domain(), service, athenzCredentials.token());
+ deleteApplication(oldDomain, application.id().application(), athenzCredentials.token());
+ zmsClient.deleteTenancy(oldDomain, service, athenzCredentials.token());
}
return tenant;
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
index 99678367a77..a0d807ac333 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
@@ -20,7 +20,7 @@ import com.yahoo.restapi.Path;
import com.yahoo.slime.Cursor;
import com.yahoo.slime.Inspector;
import com.yahoo.slime.Slime;
-import com.yahoo.vespa.athenz.api.AthenzDomain;
+import com.yahoo.vespa.athenz.api.AthenzIdentity;
import com.yahoo.vespa.athenz.api.AthenzPrincipal;
import com.yahoo.vespa.athenz.api.AthenzUser;
import com.yahoo.vespa.athenz.client.zms.ZmsClientException;
@@ -43,7 +43,6 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.Hostname;
import com.yahoo.vespa.hosted.controller.api.identifiers.Property;
import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId;
import com.yahoo.vespa.hosted.controller.api.identifiers.TenantId;
-import com.yahoo.vespa.hosted.controller.api.identifiers.UserId;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServerException;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.Log;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.Logs;
@@ -68,16 +67,15 @@ import com.yahoo.vespa.hosted.controller.application.RoutingPolicy;
import com.yahoo.vespa.hosted.controller.application.SystemApplication;
import com.yahoo.vespa.hosted.controller.deployment.DeploymentTrigger;
import com.yahoo.vespa.hosted.controller.deployment.DeploymentTrigger.ChangesToCancel;
-import com.yahoo.vespa.hosted.controller.security.AccessControlRequests;
import com.yahoo.vespa.hosted.controller.restapi.ErrorResponse;
import com.yahoo.vespa.hosted.controller.restapi.MessageResponse;
import com.yahoo.vespa.hosted.controller.restapi.ResourceResponse;
import com.yahoo.vespa.hosted.controller.restapi.SlimeJsonResponse;
import com.yahoo.vespa.hosted.controller.restapi.StringResponse;
+import com.yahoo.vespa.hosted.controller.security.AccessControlRequests;
import com.yahoo.vespa.hosted.controller.security.Credentials;
import com.yahoo.vespa.hosted.controller.tenant.AthenzTenant;
import com.yahoo.vespa.hosted.controller.tenant.Tenant;
-import com.yahoo.vespa.hosted.controller.tenant.Tenant.Type;
import com.yahoo.vespa.hosted.controller.tenant.UserTenant;
import com.yahoo.vespa.hosted.controller.versions.VespaVersion;
import com.yahoo.vespa.serviceview.bindings.ApplicationView;
@@ -102,7 +100,6 @@ import java.util.Scanner;
import java.util.Set;
import java.util.logging.Level;
-import static com.yahoo.yolean.Exceptions.uncheck;
import static java.util.stream.Collectors.joining;
/**
@@ -263,16 +260,17 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
}
private HttpResponse authenticatedUser(HttpRequest request) {
- AthenzPrincipal user = getUserPrincipal(request);
+ Principal user = requireUserPrincipal(request);
if (user == null)
throw new NotAuthorizedException("You must be authenticated.");
- TenantName tenantName = TenantName.from(UserTenant.normalizeUser(user.getIdentity().getName()));
+ String userName = user instanceof AthenzPrincipal ? ((AthenzPrincipal) user).getIdentity().getName() : user.getName();
+ TenantName tenantName = TenantName.from(UserTenant.normalizeUser(userName));
List<Tenant> tenants = controller.tenants().asList(new Credentials(user));
Slime slime = new Slime();
Cursor response = slime.setObject();
- response.setString("user", user.getIdentity().getName());
+ response.setString("user", userName);
Cursor tenantsArray = response.setArray("tenants");
for (Tenant tenant : tenants)
tenantInTenantsListToSlime(tenant, request.getUri(), tenantsArray.addObject());
@@ -627,7 +625,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
Inspector requestData = toSlime(request.getData()).get();
String reason = mandatory("reason", requestData).asString();
- String agent = getUserPrincipal(request).getIdentity().getFullName();
+ String agent = requireUserPrincipal(request).getName();
long timestamp = controller.clock().instant().getEpochSecond();
EndpointStatus.Status status = inService ? EndpointStatus.Status.in : EndpointStatus.Status.out;
EndpointStatus endpointStatus = new EndpointStatus(status, reason, agent, timestamp);
@@ -722,17 +720,22 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
}
private HttpResponse createUser(HttpRequest request) {
- Optional<UserId> user = getUserId(request);
- if ( ! user.isPresent()) throw new ForbiddenException("Not authenticated or not a user.");
-
- String username = UserTenant.normalizeUser(user.get().id());
- UserTenant tenant = UserTenant.create(username);
+ String user = Optional.of(requireUserPrincipal(request))
+ .filter(AthenzPrincipal.class::isInstance)
+ .map(AthenzPrincipal.class::cast)
+ .map(AthenzPrincipal::getIdentity)
+ .filter(AthenzUser.class::isInstance)
+ .map(AthenzIdentity::getName)
+ .map(UserTenant::normalizeUser)
+ .orElseThrow(() -> new ForbiddenException("Not authenticated or not a user."));
+
+ UserTenant tenant = UserTenant.create(user);
try {
controller.tenants().createUser(tenant);
- return new MessageResponse("Created user '" + username + "'");
+ return new MessageResponse("Created user '" + user + "'");
} catch (AlreadyExistsException e) {
// Ok
- return new MessageResponse("User '" + username + "' already exists");
+ return new MessageResponse("User '" + user + "' already exists");
}
}
@@ -948,7 +951,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
applicationPackage,
applicationVersion,
deployOptionsJsonClass,
- Optional.of(getUserPrincipal(request).getIdentity()));
+ Optional.of(requireUserPrincipal(request)));
return new SlimeJsonResponse(toSlime(result));
}
@@ -1078,11 +1081,26 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
private void toSlime(Cursor object, Tenant tenant, HttpRequest request) {
object.setString("tenant", tenant.name().value());
object.setString("type", tentantType(tenant));
- if (tenant instanceof AthenzTenant) {
- AthenzTenant athenzTenant = (AthenzTenant) tenant;
- object.setString("athensDomain", athenzTenant.domain().getName());
- object.setString("property", athenzTenant.property().id());
- athenzTenant.propertyId().ifPresent(id -> object.setString("propertyId", id.toString()));
+ switch (tenant.type()) {
+ case athenz:
+ AthenzTenant athenzTenant = (AthenzTenant) tenant;
+ object.setString("athensDomain", athenzTenant.domain().getName());
+ object.setString("property", athenzTenant.property().id());
+ athenzTenant.propertyId().ifPresent(id -> object.setString("propertyId", id.toString()));
+ athenzTenant.contact().ifPresent(c -> {
+ object.setString("propertyUrl", c.propertyUrl().toString());
+ object.setString("contactsUrl", c.url().toString());
+ object.setString("issueCreationUrl", c.issueTrackerUrl().toString());
+ Cursor contactsArray = object.setArray("contacts");
+ c.persons().forEach(persons -> {
+ Cursor personArray = contactsArray.addArray();
+ persons.forEach(personArray::addString);
+ });
+ });
+ break;
+ case user: break;
+ case cloud: break;
+ default: throw new IllegalArgumentException("Unexpected tenant type '" + tenant.type() + "'.");
}
Cursor applicationArray = object.setArray("applications");
for (Application application : controller.applications().asList(tenant.name())) {
@@ -1093,19 +1111,6 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
toSlime(application, applicationArray.addObject(), request);
}
}
- if (tenant instanceof AthenzTenant) {
- AthenzTenant athenzTenant = (AthenzTenant) tenant;
- athenzTenant.contact().ifPresent(c -> {
- object.setString("propertyUrl", c.propertyUrl().toString());
- object.setString("contactsUrl", c.url().toString());
- object.setString("issueCreationUrl", c.issueTrackerUrl().toString());
- Cursor contactsArray = object.setArray("contacts");
- c.persons().forEach(persons -> {
- Cursor personArray = contactsArray.addArray();
- persons.forEach(personArray::addString);
- });
- });
- }
}
// A tenant has different content when in a list ... antipattern, but not solvable before application/v5
@@ -1113,10 +1118,15 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
object.setString("tenant", tenant.name().value());
Cursor metaData = object.setObject("metaData");
metaData.setString("type", tentantType(tenant));
- if (tenant instanceof AthenzTenant) {
- AthenzTenant athenzTenant = (AthenzTenant) tenant;
- metaData.setString("athensDomain", athenzTenant.domain().getName());
- metaData.setString("property", athenzTenant.property().id());
+ switch (tenant.type()) {
+ case athenz:
+ AthenzTenant athenzTenant = (AthenzTenant) tenant;
+ metaData.setString("athensDomain", athenzTenant.domain().getName());
+ metaData.setString("property", athenzTenant.property().id());
+ break;
+ case user: break;
+ case cloud: break;
+ default: throw new IllegalArgumentException("Unexpected tenant type '" + tenant.type() + "'.");
}
object.setString("url", withPath("/application/v4/tenant/" + tenant.name().value(), requestURI).toString());
}
@@ -1159,23 +1169,10 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
}
}
- private static Optional<UserId> getUserId(HttpRequest request) {
- return Optional.of(getUserPrincipal(request))
- .map(AthenzPrincipal::getIdentity)
- .filter(AthenzUser.class::isInstance)
- .map(AthenzUser.class::cast)
- .map(AthenzUser::getName)
- .map(UserId::new);
- }
-
- private static AthenzPrincipal getUserPrincipal(HttpRequest request) { // TODO jvenstad: Not necessarily Athenz ...
+ private static Principal requireUserPrincipal(HttpRequest request) {
Principal principal = request.getJDiscRequest().getUserPrincipal();
if (principal == null) throw new InternalServerErrorException("Expected a user principal");
- if (!(principal instanceof AthenzPrincipal))
- throw new InternalServerErrorException(
- String.format("Expected principal of type %s, got %s",
- AthenzPrincipal.class.getSimpleName(), principal.getClass().getName()));
- return (AthenzPrincipal) principal;
+ return principal;
}
private Inspector mandatory(String key, Inspector object) {
@@ -1328,12 +1325,12 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
}
private static String tentantType(Tenant tenant) {
- if (tenant instanceof AthenzTenant) {
- return "ATHENS";
- } else if (tenant instanceof UserTenant) {
- return "USER";
+ switch (tenant.type()) {
+ case user: return "USER";
+ case athenz: return "ATHENS";
+ case cloud: return "CLOUD";
+ default: throw new IllegalArgumentException("Unknown tenant type: " + tenant.getClass().getSimpleName());
}
- throw new IllegalArgumentException("Unknown tenant type: " + tenant.getClass().getSimpleName());
}
private static ApplicationId appIdFromPath(Path path) {
@@ -1359,7 +1356,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
ApplicationPackage applicationPackage = new ApplicationPackage(dataParts.get(EnvironmentResource.APPLICATION_ZIP));
controller.applications().verifyApplicationIdentityConfiguration(TenantName.from(tenant),
applicationPackage,
- Optional.of(getUserPrincipal(request).getIdentity()));
+ Optional.of(requireUserPrincipal(request)));
return JobControllerApiHandlerHelper.submitResponse(controller.jobController(),
tenant,
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/AthenzAccessControlRequests.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/AthenzAccessControlRequests.java
index e8bcc2d9db1..c85eea2f2e9 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/AthenzAccessControlRequests.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/AthenzAccessControlRequests.java
@@ -14,12 +14,10 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId;
import com.yahoo.vespa.hosted.controller.tenant.AthenzTenant;
import java.security.Principal;
+import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
-import static com.yahoo.vespa.config.SlimeUtils.jsonToSlime;
-import static com.yahoo.yolean.Exceptions.uncheck;
-
/**
* Extracts access control data for Athenz or user tenants from HTTP requests.
*
@@ -37,21 +35,16 @@ public class AthenzAccessControlRequests implements AccessControlRequests {
@Override
public TenantSpec specification(TenantName tenant, Inspector requestObject) {
return new AthenzTenantSpec(tenant,
- optional("athensDomain", requestObject).map(AthenzDomain::new),
- optional("property", requestObject).map(Property::new),
+ new AthenzDomain(required("athensDomain", requestObject)),
+ new Property(required("property", requestObject)),
optional("propertyId", requestObject).map(PropertyId::new));
}
@Override
public Credentials credentials(TenantName tenant, Inspector requestObject, HttpRequest request) {
- // Get domain from request if present, which it should be for create and update requests.
- Optional<AthenzDomain> requestDomain = optional("athensDomain", requestObject).map(AthenzDomain::new);
- // Otherwise the tenant should already exist, and we use the domain stored under the tenant.
- Optional<AthenzDomain> tenantDomain = tenants.get(tenant).map(AthenzTenant.class::cast).map(AthenzTenant::domain);
-
return new AthenzCredentials(requireAthenzPrincipal(request),
- requestDomain.orElseGet(() -> tenantDomain
- .orElseThrow(() -> new IllegalArgumentException("Must specify 'athensDomain'."))),
+ tenants.get(tenant).map(AthenzTenant.class::cast).map(AthenzTenant::domain)
+ .orElseGet(() -> new AthenzDomain(required("athensDomain", requestObject))),
requireOktaAccessToken(request));
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/AthenzCredentials.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/AthenzCredentials.java
index d8ea9c8feeb..c9e3e249668 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/AthenzCredentials.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/AthenzCredentials.java
@@ -4,6 +4,8 @@ import com.yahoo.vespa.athenz.api.AthenzDomain;
import com.yahoo.vespa.athenz.api.AthenzPrincipal;
import com.yahoo.vespa.athenz.api.OktaAccessToken;
+import java.util.Optional;
+
import static java.util.Objects.requireNonNull;
/**
@@ -27,7 +29,7 @@ public class AthenzCredentials extends Credentials {
@Override
public AthenzPrincipal user() { return (AthenzPrincipal) super.user(); }
- /** Returns the Athenz domain on whose behalf this request is made. */
+ /** Returns the Athenz domain of the tenant on whose behalf this request is made. */
public AthenzDomain domain() { return domain; }
/** Returns the token proving access to the requested action under this domain. */
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/AthenzTenantSpec.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/AthenzTenantSpec.java
index 56fbd0a2b2a..b122199bf05 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/AthenzTenantSpec.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/AthenzTenantSpec.java
@@ -16,18 +16,22 @@ import static java.util.Objects.requireNonNull;
*/
public class AthenzTenantSpec extends TenantSpec {
- private final Optional<Property> property;
+ private final AthenzDomain domain;
+ private final Property property;
private final Optional<PropertyId> propertyId;
- public AthenzTenantSpec(TenantName tenant, Optional<AthenzDomain> domain,
- Optional<Property> property, Optional<PropertyId> propertyId) {
+ public AthenzTenantSpec(TenantName tenant, AthenzDomain domain, Property property, Optional<PropertyId> propertyId) {
super(tenant);
+ this.domain = domain;
this.property = requireNonNull(property);
this.propertyId = requireNonNull(propertyId);
}
+ /** The domain to create this tenant under. */
+ public AthenzDomain domain() { return domain; }
+
/** The property name of the tenant. */
- public Optional<Property> property() { return property; }
+ public Property property() { return property; }
/** The ID of the property of the tenant. */
public Optional<PropertyId> propertyId() { return propertyId; }
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/TenantSpec.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/TenantSpec.java
index 20a330bc378..2f7dd656678 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/TenantSpec.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/TenantSpec.java
@@ -2,8 +2,6 @@ package com.yahoo.vespa.hosted.controller.security;
import com.yahoo.config.provision.TenantName;
-import java.security.Principal;
-
import static java.util.Objects.requireNonNull;
/**
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java
index 191c7cf56d3..2c4043c369c 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java
@@ -90,7 +90,6 @@ public final class ControllerTester {
private final MetricsServiceMock metricsService;
private final RoutingGeneratorMock routingGenerator;
private final MockContactRetriever contactRetriever;
- private final MockIssueHandler issueHandler;
private Controller controller;
@@ -142,7 +141,6 @@ public final class ControllerTester {
this.metricsService = metricsService;
this.routingGenerator = routingGenerator;
this.contactRetriever = contactRetriever;
- this.issueHandler = issueHandler;
this.controller = createController(curator, rotationsConfig, configServer, clock, gitHub, zoneRegistry,
athenzDb, nameService, artifactRepository, appStoreMock, entityService, buildService,
metricsService, routingGenerator);
@@ -266,8 +264,8 @@ public final class ControllerTester {
AthenzUser user = new AthenzUser("user");
AthenzDomain domain = createDomainWithAdmin(domainName, user);
AthenzTenantSpec tenantSpec = new AthenzTenantSpec(name,
- Optional.of(domain),
- Optional.of(new Property("Property" + propertyId)),
+ domain,
+ new Property("Property" + propertyId),
Optional.ofNullable(propertyId).map(Object::toString).map(PropertyId::new));
AthenzCredentials credentials = new AthenzCredentials(new AthenzPrincipal(user), domain, new OktaAccessToken("okta-token"));
controller().tenants().create(tenantSpec, credentials);
@@ -283,7 +281,9 @@ public final class ControllerTester {
}
public Optional<Credentials> credentialsFor(ApplicationId id) {
- return domainOf(id).map(domain -> new AthenzCredentials(new AthenzPrincipal(new AthenzUser("user")), domain, new OktaAccessToken("okta-token")));
+ return domainOf(id).map(domain -> new AthenzCredentials(new AthenzPrincipal(new AthenzUser("user")),
+ domain,
+ new OktaAccessToken("okta-token")));
}
public Application createApplication(TenantName tenant, String applicationName, String instanceName, long projectId) {
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java
index 3b25daebfd0..5243e8c2759 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java
@@ -79,8 +79,8 @@ public class ContainerControllerTester {
AthenzPrincipal user = new AthenzPrincipal(new AthenzUser("user"));
AthenzCredentials credentials = new AthenzCredentials(user, domain1, new OktaAccessToken("okta-token"));
AthenzTenantSpec tenantSpec = new AthenzTenantSpec(TenantName.from(tenant),
- Optional.of(domain1),
- Optional.of(new Property("property1")),
+ domain1,
+ new Property("property1"),
Optional.of(new PropertyId("1234")));
controller().tenants().create(tenantSpec, credentials);
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant-with-contact-info.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant-with-contact-info.json
index 0ba0a01c5d0..01677f05eeb 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant-with-contact-info.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant-with-contact-info.json
@@ -4,7 +4,6 @@
"athensDomain": "domain2",
"property": "property2",
"propertyId": "1234",
- "applications": [],
"propertyUrl": "www.properties.tld/1234",
"contactsUrl": "www.contacts.tld/1234",
"issueCreationUrl": "www.issues.tld/1234",
@@ -15,5 +14,6 @@
[
"bob"
]
- ]
+ ],
+ "applications": []
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant2.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant2.json
index 6e66202b70d..2d6cc7b7208 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant2.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant2.json
@@ -4,7 +4,6 @@
"athensDomain": "domain2",
"property": "property2",
"propertyId": "1234",
- "applications": [],
"propertyUrl": "www.properties.tld/1234",
"contactsUrl": "www.contacts.tld/1234",
"issueCreationUrl": "www.issues.tld/1234",
@@ -15,5 +14,6 @@
[
"bob"
]
- ]
+ ],
+ "applications": []
} \ No newline at end of file