From 75f53faf74ad050c7c8fecb1162cf7de19da3bb6 Mon Sep 17 00:00:00 2001 From: Morten Tokle Date: Mon, 3 Jan 2022 12:53:32 +0100 Subject: Revert "Allow developers to deploy application in manual zones" --- .../api/integration/athenz/ZmsClientMock.java | 2 +- .../vespa/hosted/controller/api/role/Role.java | 5 --- .../hosted/controller/api/role/RoleDefinition.java | 3 -- .../controller/athenz/impl/AthenzFacade.java | 11 +++---- .../restapi/filter/AthenzRoleFilter.java | 37 ++-------------------- .../filter/ControllerAuthorizationFilterTest.java | 13 -------- 6 files changed, 8 insertions(+), 63 deletions(-) diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/ZmsClientMock.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/ZmsClientMock.java index 9fb6fa1501b..4679f660319 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/ZmsClientMock.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/ZmsClientMock.java @@ -40,7 +40,7 @@ public class ZmsClientMock implements ZmsClient { private final AthenzDbMock athenz; private final AthenzIdentity controllerIdentity; private static final Pattern TENANT_RESOURCE_PATTERN = Pattern.compile("service\\.hosting\\.tenant\\.(?[\\w\\-_]+)\\..*"); - private static final Pattern APPLICATION_RESOURCE_PATTERN = Pattern.compile("service\\.hosting\\.tenant\\.[\\w\\-_]+\\.res_group\\.(?[\\w\\-_]+)\\.(?[.*]+)"); + private static final Pattern APPLICATION_RESOURCE_PATTERN = Pattern.compile("service\\.hosting\\.tenant\\.[\\w\\-_]+\\.res_group\\.(?[\\w\\-_]+)\\.wildcard"); public ZmsClientMock(AthenzDbMock athenz, AthenzIdentity controllerIdentity) { this.athenz = athenz; diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Role.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Role.java index c40c2d4db01..5cdd12ecb1c 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Role.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Role.java @@ -52,11 +52,6 @@ public abstract class Role { return new TenantRole(RoleDefinition.developer, tenant); } - /** Returns a {@link RoleDefinition#hostedDeveloper} for the current system and given tenant. */ - public static TenantRole hostedDeveloper(TenantName tenant) { - return new TenantRole(RoleDefinition.hostedDeveloper, tenant); - } - /** Returns a {@link RoleDefinition#administrator} for the current system and given tenant. */ public static TenantRole administrator(TenantName tenant) { return new TenantRole(RoleDefinition.administrator, tenant); diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java index aed5c08f0db..eeb3bae4431 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java @@ -60,9 +60,6 @@ public enum RoleDefinition { Policy.billingInformationRead, Policy.secretStoreOperations), - /** Developer for manual deployments for a tenant */ - hostedDeveloper(Policy.developmentDeployment), - /** Admin — the administrative function for user management etc. */ administrator(Policy.tenantUpdate, Policy.tenantManager, 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 28cf132af90..d116ef3333c 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 @@ -5,9 +5,7 @@ import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.inject.Inject; import com.yahoo.config.provision.ApplicationName; -import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.TenantName; -import com.yahoo.config.provision.Zone; import com.yahoo.text.Text; import com.yahoo.vespa.athenz.api.AthenzDomain; import com.yahoo.vespa.athenz.api.AthenzIdentity; @@ -250,9 +248,9 @@ public class AthenzFacade implements AccessControl { } public boolean hasApplicationAccess( - AthenzIdentity identity, ApplicationAction action, AthenzDomain tenantDomain, ApplicationName applicationName, Optional zone) { + AthenzIdentity identity, ApplicationAction action, AthenzDomain tenantDomain, ApplicationName applicationName) { return hasAccess( - action.name(), applicationResourceString(tenantDomain, applicationName, zone), identity); + action.name(), applicationResourceString(tenantDomain, applicationName), identity); } public boolean hasTenantAdminAccess(AthenzIdentity identity, AthenzDomain tenantDomain) { @@ -327,9 +325,8 @@ public class AthenzFacade implements AccessControl { return resourceStringPrefix(tenantDomain) + ".wildcard"; } - private String applicationResourceString(AthenzDomain tenantDomain, ApplicationName applicationName, Optional zone) { - String environment = zone.map(Zone::environment).map(Environment::value).orElse("*"); - return resourceStringPrefix(tenantDomain) + "." + "res_group" + "." + applicationName.value() + "." + environment; + private String applicationResourceString(AthenzDomain tenantDomain, ApplicationName applicationName) { + return resourceStringPrefix(tenantDomain) + "." + "res_group" + "." + applicationName.value() + ".wildcard"; } private enum TenantAction { diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java index 7ab3b75a758..c685390c7ed 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java @@ -4,10 +4,7 @@ package com.yahoo.vespa.hosted.controller.restapi.filter; import com.auth0.jwt.JWT; import com.google.inject.Inject; import com.yahoo.config.provision.ApplicationName; -import com.yahoo.config.provision.Environment; -import com.yahoo.config.provision.RegionName; import com.yahoo.config.provision.TenantName; -import com.yahoo.config.provision.Zone; import com.yahoo.jdisc.http.filter.DiscFilterRequest; import com.yahoo.jdisc.http.filter.security.base.JsonSecurityRequestFilterBase; @@ -19,7 +16,6 @@ import com.yahoo.restapi.Path; 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; import com.yahoo.vespa.hosted.controller.Controller; import com.yahoo.vespa.hosted.controller.TenantController; @@ -98,15 +94,6 @@ public class AthenzRoleFilter extends JsonSecurityRequestFilterBase { path.matches("/application/v4/tenant/{tenant}/application/{application}/{*}"); Optional application = Optional.ofNullable(path.get("application")).map(ApplicationName::from); - final Optional zone; - if(path.matches("/application/v4/tenant/{tenant}/application/{application}/{*}/instance/{*}/environment/{environment}/region/{region}/{*}")) { - zone = Optional.of(new Zone(Environment.from(path.get("environment")), RegionName.from(path.get("region")))); - } else if(path.matches("/application/v4/tenant/{tenant}/application/{application}/{*}/environment/{environment}/region/{region}/{*}")) { - zone = Optional.of(new Zone(Environment.from(path.get("environment")), RegionName.from(path.get("region")))); - } else { - zone = Optional.empty(); - } - AthenzIdentity identity = principal.getIdentity(); Set roleMemberships = new CopyOnWriteArraySet<>(); @@ -134,18 +121,10 @@ public class AthenzRoleFilter extends JsonSecurityRequestFilterBase { && ! tenant.get().name().value().equals("sandbox")) futures.add(executor.submit(() -> { if ( tenant.get().type() == Tenant.Type.athenz - && hasDeployerAccess(identity, ((AthenzTenant) tenant.get()).domain(), application.get(), zone)) + && hasDeployerAccess(identity, ((AthenzTenant) tenant.get()).domain(), application.get())) roleMemberships.add(Role.buildService(tenant.get().name(), application.get())); })); - if (identity instanceof AthenzUser && zone.isPresent()) { - Zone z = zone.get(); - futures.add(executor.submit(() -> { - if (canDeployToManualZones(identity, ((AthenzTenant) tenant.get()).domain(), application.get(), z)) - roleMemberships.add(Role.hostedDeveloper(tenant.get().name())); - })); - } - futures.add(executor.submit(() -> { if (athenz.hasSystemFlagsAccess(identity, /*dryrun*/false)) roleMemberships.add(Role.systemFlagsDeployer()); @@ -188,22 +167,12 @@ public class AthenzRoleFilter extends JsonSecurityRequestFilterBase { } } - private boolean hasDeployerAccess(AthenzIdentity identity, AthenzDomain tenantDomain, ApplicationName application, Optional zone) { + private boolean hasDeployerAccess(AthenzIdentity identity, AthenzDomain tenantDomain, ApplicationName application) { try { return athenz.hasApplicationAccess(identity, ApplicationAction.deploy, tenantDomain, - application, - zone); - } catch (ZmsClientException e) { - throw new RuntimeException("Failed to authorize operation: (" + e.getMessage() + ")", e); - } - } - - private boolean canDeployToManualZones(AthenzIdentity identity, AthenzDomain tenantDomain, ApplicationName application, Zone zone) { - if (! zone.environment().isManuallyDeployed()) return false; - try { - return athenz.hasApplicationAccess(identity, ApplicationAction.deploy, tenantDomain, application, Optional.of(zone)); + application); } catch (ZmsClientException e) { throw new RuntimeException("Failed to authorize operation: (" + e.getMessage() + ")", e); } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java index eab3a37a9c3..9e17b44c9a6 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java @@ -4,7 +4,6 @@ package com.yahoo.vespa.hosted.controller.restapi.filter; import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.application.container.handler.Request; import com.yahoo.config.provision.SystemName; -import com.yahoo.config.provision.TenantName; import com.yahoo.jdisc.http.HttpRequest.Method; import com.yahoo.jdisc.http.filter.DiscFilterRequest; import com.yahoo.vespa.hosted.controller.ControllerTester; @@ -76,18 +75,6 @@ public class ControllerAuthorizationFilterTest { assertIsAllowed(invokeFilter(filter, createRequest(Method.GET, "/zone/v1/path", securityContext))); } - @Test - public void hostedDeveloper() { - ControllerTester tester = new ControllerTester(); - TenantName tenantName = TenantName.defaultName(); - SecurityContext securityContext = new SecurityContext(() -> "user", Set.of(Role.hostedDeveloper(tenantName))); - - ControllerAuthorizationFilter filter = createFilter(tester); - assertIsAllowed(invokeFilter(filter, createRequest(Method.POST, "/application/v4/tenant/" + tenantName.value() + "/application/app/instance/default/environment/dev/region/region/deploy", securityContext))); - assertIsForbidden(invokeFilter(filter, createRequest(Method.POST, "/application/v4/tenant/" + tenantName.value() + "/application/app/instance/default/environment/prod/region/region/deploy", securityContext))); - assertIsForbidden(invokeFilter(filter, createRequest(Method.POST, "/application/v4/tenant/" + tenantName.value() + "/application/app/submit", securityContext))); - } - private static void assertIsAllowed(Optional response) { assertFalse("Expected no response from filter, but got \"" + response.map(r -> r.message + "\" (" + r.statusCode + ")").orElse(""), -- cgit v1.2.3