aboutsummaryrefslogtreecommitdiffstats
path: root/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java')
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java1130
1 files changed, 565 insertions, 565 deletions
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
index 2435bb2efb8..e3292700432 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
@@ -70,8 +70,8 @@ import com.yahoo.vespa.hosted.controller.tenant.AthenzTenant;
import com.yahoo.vespa.hosted.controller.tenant.LastLoginInfo;
import com.yahoo.vespa.hosted.controller.versions.VespaVersion;
import com.yahoo.yolean.Exceptions;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import javax.security.auth.x500.X500Principal;
import java.io.File;
@@ -100,9 +100,9 @@ import static com.yahoo.application.container.handler.Request.Method.PUT;
import static java.net.URLEncoder.encode;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.stream.Collectors.joining;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author bratseth
@@ -153,7 +153,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
private ContainerTester tester;
private DeploymentTester deploymentTester;
- @Before
+ @BeforeEach
public void before() {
tester = new ContainerTester(container, responseFiles);
deploymentTester = new DeploymentTester(new ControllerTester(tester));
@@ -161,24 +161,24 @@ public class ApplicationApiTest extends ControllerContainerTest {
}
@Test
- public void testApplicationApi() {
+ void testApplicationApi() {
createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID); // (Necessary but not provided in this API)
// GET API root
tester.assertResponse(request("/application/v4/", GET).userIdentity(USER_ID),
- new File("root.json"));
+ new File("root.json"));
// POST (add) a tenant without property ID
tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
- .userIdentity(USER_ID)
- .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
- .oAuthCredentials(OKTA_CREDENTIALS),
- new File("tenant-without-applications.json"));
+ .userIdentity(USER_ID)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ new File("tenant-without-applications.json"));
// PUT (modify) a tenant
tester.assertResponse(request("/application/v4/tenant/tenant1", PUT)
- .userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS)
- .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
- new File("tenant-without-applications.json"));
+ .userIdentity(USER_ID)
+ .oAuthCredentials(OKTA_CREDENTIALS)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
+ new File("tenant-without-applications.json"));
// Add another Athens domain, so we can try to create more tenants
createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN_2, USER_ID); // New domain to test tenant w/property ID
@@ -187,59 +187,59 @@ public class ApplicationApiTest extends ControllerContainerTest {
// POST (add) a tenant with property ID
tester.assertResponse(request("/application/v4/tenant/tenant2", POST)
- .userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS)
- .data("{\"athensDomain\":\"domain2\", \"property\":\"property2\", \"propertyId\":\"1234\"}"),
- new File("tenant-without-applications-with-id.json"));
+ .userIdentity(USER_ID)
+ .oAuthCredentials(OKTA_CREDENTIALS)
+ .data("{\"athensDomain\":\"domain2\", \"property\":\"property2\", \"propertyId\":\"1234\"}"),
+ new File("tenant-without-applications-with-id.json"));
// PUT (modify) a tenant with property ID
tester.assertResponse(request("/application/v4/tenant/tenant2", PUT)
- .userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS)
- .data("{\"athensDomain\":\"domain2\", \"property\":\"property2\", \"propertyId\":\"1234\"}"),
- new File("tenant-without-applications-with-id.json"));
+ .userIdentity(USER_ID)
+ .oAuthCredentials(OKTA_CREDENTIALS)
+ .data("{\"athensDomain\":\"domain2\", \"property\":\"property2\", \"propertyId\":\"1234\"}"),
+ new File("tenant-without-applications-with-id.json"));
// GET a tenant with property ID and contact information
updateContactInformation();
tester.controller().tenants().updateLastLogin(TenantName.from("tenant2"),
List.of(LastLoginInfo.UserLevel.user, LastLoginInfo.UserLevel.administrator), Instant.ofEpochMilli(1234));
tester.assertResponse(request("/application/v4/tenant/tenant2", GET).userIdentity(USER_ID),
- new File("tenant2.json"));
+ new File("tenant2.json"));
// POST (create) an application
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", POST)
- .userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS),
- new File("instance-reference.json"));
+ .userIdentity(USER_ID)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ new File("instance-reference.json"));
// GET a tenant
tester.assertResponse(request("/application/v4/tenant/tenant1", GET).userIdentity(USER_ID),
- new File("tenant-with-application.json"));
+ new File("tenant-with-application.json"));
tester.assertResponse(request("/application/v4/tenant/tenant1", GET)
- .userIdentity(USER_ID)
- .properties(Map.of("activeInstances", "true")),
- new File("tenant-without-applications.json"));
+ .userIdentity(USER_ID)
+ .properties(Map.of("activeInstances", "true")),
+ new File("tenant-without-applications.json"));
// GET tenant applications
tester.assertResponse(request("/application/v4/tenant/tenant1/application/", GET).userIdentity(USER_ID),
- new File("application-list.json"));
+ new File("application-list.json"));
// GET tenant application instances for application that does not exist
tester.assertResponse(request("/application/v4/tenant/tenant1/application/fake-app/instance/", GET).userIdentity(USER_ID),
"{\"error-code\":\"NOT_FOUND\",\"message\":\"Application 'fake-app' does not exist\"}", 404);
// GET tenant applications (instances of "application1" only)
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/", GET).userIdentity(USER_ID),
- new File("application-list.json"));
+ new File("application-list.json"));
// GET at a tenant, with "&recursive=true&production=true", recurses over no instances yet, as they are not in deployment spec.
tester.assertResponse(request("/application/v4/tenant/tenant1/", GET)
- .userIdentity(USER_ID)
- .properties(Map.of("recursive", "true",
- "production", "true")),
- new File("tenant-with-empty-application.json"));
+ .userIdentity(USER_ID)
+ .properties(Map.of("recursive", "true",
+ "production", "true")),
+ new File("tenant-with-empty-application.json"));
// GET at an application, with "&recursive=true&production=true", recurses over no instances yet, as they are not in deployment spec.
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", GET)
- .userIdentity(USER_ID)
- .properties(Map.of("recursive", "true",
- "production", "true")),
- new File("application-without-instances.json"));
+ .userIdentity(USER_ID)
+ .properties(Map.of("recursive", "true",
+ "production", "true")),
+ new File("application-without-instances.json"));
addUserToHostedOperatorRole(HostedAthenzIdentities.from(HOSTED_VESPA_OPERATOR));
@@ -249,87 +249,87 @@ public class ApplicationApiTest extends ControllerContainerTest {
// POST (deploy) an application to start a manual deployment in prod is not allowed
MultiPartStreamer entity = createApplicationDeployData(applicationPackageInstance1);
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploy/production-us-east-3/", POST)
- .data(entity)
- .userIdentity(USER_ID),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Direct deployments are only allowed to manually deployed environments.\"}", 400);
+ .data(entity)
+ .userIdentity(USER_ID),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Direct deployments are only allowed to manually deployed environments.\"}", 400);
// POST (deploy) an application to start a manual deployment in prod is allowed for operators
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploy/production-us-east-3/", POST)
- .data(entity)
- .userIdentity(HOSTED_VESPA_OPERATOR),
- "{\"message\":\"Deployment started in run 1 of production-us-east-3 for tenant1.application1.instance1. This may take about 15 minutes the first time.\",\"run\":1}");
+ .data(entity)
+ .userIdentity(HOSTED_VESPA_OPERATOR),
+ "{\"message\":\"Deployment started in run 1 of production-us-east-3 for tenant1.application1.instance1. This may take about 15 minutes the first time.\",\"run\":1}");
app1.runJob(DeploymentContext.productionUsEast3);
tester.controller().applications().deactivate(app1.instanceId(), ZoneId.from("prod", "us-east-3"));
// POST (deploy) an application to start a manual deployment to dev
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploy/dev-us-east-1/", POST)
- .data(entity)
- .userIdentity(USER_ID),
- "{\"message\":\"Deployment started in run 1 of dev-us-east-1 for tenant1.application1.instance1. This may take about 15 minutes the first time.\",\"run\":1}");
+ .data(entity)
+ .userIdentity(USER_ID),
+ "{\"message\":\"Deployment started in run 1 of dev-us-east-1 for tenant1.application1.instance1. This may take about 15 minutes the first time.\",\"run\":1}");
app1.runJob(DeploymentContext.devUsEast1);
// POST (deploy) a job to restart a manual deployment to dev
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/job/dev-us-east-1", POST)
- .userIdentity(USER_ID),
- "{\"message\":\"Triggered dev-us-east-1 for tenant1.application1.instance1\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"Triggered dev-us-east-1 for tenant1.application1.instance1\"}");
app1.runJob(DeploymentContext.devUsEast1);
// GET dev application package
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/job/dev-us-east-1/package", GET)
- .userIdentity(USER_ID),
- (response) -> {
- assertEquals("attachment; filename=\"tenant1.application1.instance1.dev.us-east-1.zip\"", response.getHeaders().getFirst("Content-Disposition"));
- assertArrayEquals(applicationPackageInstance1.zippedContent(), response.getBody());
- },
- 200);
+ .userIdentity(USER_ID),
+ (response) -> {
+ assertEquals("attachment; filename=\"tenant1.application1.instance1.dev.us-east-1.zip\"", response.getHeaders().getFirst("Content-Disposition"));
+ assertArrayEquals(applicationPackageInstance1.zippedContent(), response.getBody());
+ },
+ 200);
// POST an application package is not generally allowed under user instance
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/otheruser/deploy/dev-us-east-1", POST)
- .userIdentity(OTHER_USER_ID)
- .data(createApplicationDeployData(applicationPackageInstance1)),
- accessDenied,
- 403);
+ .userIdentity(OTHER_USER_ID)
+ .data(createApplicationDeployData(applicationPackageInstance1)),
+ accessDenied,
+ 403);
// DELETE a dev deployment is not generally allowed under user instance
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/otheruser/environment/dev/region/us-east-1", DELETE)
- .userIdentity(OTHER_USER_ID),
- accessDenied,
- 403);
+ .userIdentity(OTHER_USER_ID),
+ accessDenied,
+ 403);
// When the user is a tenant admin, user instances are allowed.
// POST an application package is not allowed under user instance for tenant admins
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/myuser/deploy/dev-us-east-1", POST)
- .userIdentity(USER_ID)
- .data(createApplicationDeployData(applicationPackageInstance1)),
- new File("deployment-job-accepted-2.json"));
+ .userIdentity(USER_ID)
+ .data(createApplicationDeployData(applicationPackageInstance1)),
+ new File("deployment-job-accepted-2.json"));
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/myuser/job/dev-us-east-1/diff/1", GET).userIdentity(HOSTED_VESPA_OPERATOR),
- (response) -> assertTrue(response.getBodyAsString(),
- response.getBodyAsString().contains("--- schemas/test.sd\n" +
+ (response) -> assertTrue(response.getBodyAsString().contains("--- schemas/test.sd\n" +
"@@ -1,0 +1,1 @@\n" +
- "+ search test { }\n")),
+ "+ search test { }\n"),
+ response.getBodyAsString()),
200);
// DELETE a dev deployment is allowed under user instance for tenant admins
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/myuser/environment/dev/region/us-east-1", DELETE)
- .userIdentity(USER_ID),
- "{\"message\":\"Deactivated tenant1.application1.myuser in dev.us-east-1\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"Deactivated tenant1.application1.myuser in dev.us-east-1\"}");
// DELETE a user instance
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/myuser", DELETE)
- .userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS),
- "{\"message\":\"Deleted instance tenant1.application1.myuser\"}");
+ .userIdentity(USER_ID)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ "{\"message\":\"Deleted instance tenant1.application1.myuser\"}");
addScrewdriverUserToDeployRole(SCREWDRIVER_ID,
- ATHENZ_TENANT_DOMAIN,
- id.application());
+ ATHENZ_TENANT_DOMAIN,
+ id.application());
// POST an application package and a test jar, submitting a new application for production deployment.
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/submit", POST)
- .screwdriverIdentity(SCREWDRIVER_ID)
- .data(createApplicationSubmissionData(applicationPackageInstance1, 123)),
- "{\"message\":\"application build 1, source revision of repository 'repository1', branch 'master' with commit 'commit1', by a@b, built against 6.1 at 1970-01-01T00:00:01Z\"}");
+ .screwdriverIdentity(SCREWDRIVER_ID)
+ .data(createApplicationSubmissionData(applicationPackageInstance1, 123)),
+ "{\"message\":\"application build 1, source revision of repository 'repository1', branch 'master' with commit 'commit1', by a@b, built against 6.1 at 1970-01-01T00:00:01Z\"}");
app1.runJob(DeploymentContext.systemTest).runJob(DeploymentContext.stagingTest).runJob(DeploymentContext.productionUsCentral1);
@@ -344,102 +344,102 @@ public class ApplicationApiTest extends ControllerContainerTest {
// POST (create) another application
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/instance/default", POST)
- .userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS),
- new File("instance-reference-2.json"));
+ .userIdentity(USER_ID)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ new File("instance-reference-2.json"));
ApplicationId id2 = ApplicationId.from("tenant2", "application2", "instance1");
var app2 = deploymentTester.newDeploymentContext(id2);
addScrewdriverUserToDeployRole(SCREWDRIVER_ID,
- ATHENZ_TENANT_DOMAIN_2,
- id2.application());
+ ATHENZ_TENANT_DOMAIN_2,
+ id2.application());
// POST an application package and a test jar, submitting a new application for production deployment.
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/submit", POST)
- .screwdriverIdentity(SCREWDRIVER_ID)
- .data(createApplicationSubmissionData(applicationPackage, 1000)),
- "{\"message\":\"application build 1, source revision of repository 'repository1', branch 'master' with commit 'commit1', by a@b, built against 6.1 at 1970-01-01T00:00:01Z\"}");
+ .screwdriverIdentity(SCREWDRIVER_ID)
+ .data(createApplicationSubmissionData(applicationPackage, 1000)),
+ "{\"message\":\"application build 1, source revision of repository 'repository1', branch 'master' with commit 'commit1', by a@b, built against 6.1 at 1970-01-01T00:00:01Z\"}");
deploymentTester.triggerJobs();
// POST a triggering to force a production job to start without successful tests
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/instance/instance1/job/production-us-west-1", POST)
- .data("{ \"skipTests\": true, \"skipRevision\": true, \"skipUpgrade\": true }")
- .userIdentity(USER_ID),
- "{\"message\":\"Triggered production-us-west-1 for tenant2.application2.instance1, without revision and platform upgrade\"}");
+ .data("{ \"skipTests\": true, \"skipRevision\": true, \"skipUpgrade\": true }")
+ .userIdentity(USER_ID),
+ "{\"message\":\"Triggered production-us-west-1 for tenant2.application2.instance1, without revision and platform upgrade\"}");
app2.runJob(DeploymentContext.productionUsWest1);
// POST a re-triggering to force a production job to start with previous parameters
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/instance/instance1/job/production-us-west-1", POST)
- .data("{\"reTrigger\":true}")
- .userIdentity(USER_ID),
- "{\"message\":\"Triggered production-us-west-1 for tenant2.application2.instance1\"}");
+ .data("{\"reTrigger\":true}")
+ .userIdentity(USER_ID),
+ "{\"message\":\"Triggered production-us-west-1 for tenant2.application2.instance1\"}");
// DELETE manually deployed prod deployment again
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/instance/instance1/environment/prod/region/us-west-1", DELETE)
- .userIdentity(HOSTED_VESPA_OPERATOR),
- "{\"message\":\"Deactivated tenant2.application2.instance1 in prod.us-west-1\"}");
+ .userIdentity(HOSTED_VESPA_OPERATOR),
+ "{\"message\":\"Deactivated tenant2.application2.instance1 in prod.us-west-1\"}");
// GET application having both change and outstanding change
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2", GET)
- .screwdriverIdentity(SCREWDRIVER_ID),
- new File("application2.json"));
+ .screwdriverIdentity(SCREWDRIVER_ID),
+ new File("application2.json"));
// PATCH in a major version override
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2", PATCH)
- .userIdentity(USER_ID)
- .data("{\"majorVersion\":7}"),
- "{\"message\":\"Set major version to 7\"}");
+ .userIdentity(USER_ID)
+ .data("{\"majorVersion\":7}"),
+ "{\"message\":\"Set major version to 7\"}");
// POST a pem deploy key
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/key", POST)
- .userIdentity(USER_ID)
- .data("{\"key\":\"" + pemPublicKey + "\"}"),
- "{\"keys\":[\"-----BEGIN PUBLIC KEY-----\\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuKVFA8dXk43kVfYKzkUqhEY2rDT9\\nz/4jKSTHwbYR8wdsOSrJGVEUPbS2nguIJ64OJH7gFnxM6sxUVj+Nm2HlXw==\\n-----END PUBLIC KEY-----\\n\"]}");
+ .userIdentity(USER_ID)
+ .data("{\"key\":\"" + pemPublicKey + "\"}"),
+ "{\"keys\":[\"-----BEGIN PUBLIC KEY-----\\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuKVFA8dXk43kVfYKzkUqhEY2rDT9\\nz/4jKSTHwbYR8wdsOSrJGVEUPbS2nguIJ64OJH7gFnxM6sxUVj+Nm2HlXw==\\n-----END PUBLIC KEY-----\\n\"]}");
// PATCH in a pem deploy key at deprecated path
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/instance/default", PATCH)
- .userIdentity(USER_ID)
- .data("{\"pemDeployKey\":\"" + pemPublicKey + "\"}"),
- "{\"message\":\"Added deploy key " + quotedPemPublicKey + "\"}");
+ .userIdentity(USER_ID)
+ .data("{\"pemDeployKey\":\"" + pemPublicKey + "\"}"),
+ "{\"message\":\"Added deploy key " + quotedPemPublicKey + "\"}");
// GET an application with a major version override
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2", GET)
- .userIdentity(USER_ID),
- new File("application2-with-patches.json"));
+ .userIdentity(USER_ID),
+ new File("application2-with-patches.json"));
// PATCH in removal of the application major version override removal
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2", PATCH)
- .userIdentity(USER_ID)
- .data("{\"majorVersion\":null}"),
- "{\"message\":\"Set major version to empty\"}");
+ .userIdentity(USER_ID)
+ .data("{\"majorVersion\":null}"),
+ "{\"message\":\"Set major version to empty\"}");
// GET compile version for an application
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/compile-version", GET)
- .userIdentity(USER_ID),
- "{\"compileVersion\":\"6.1.0\"}");
+ .userIdentity(USER_ID),
+ "{\"compileVersion\":\"6.1.0\"}");
// DELETE the pem deploy key
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/key", DELETE)
- .userIdentity(USER_ID)
- .data("{\"key\":\"" + pemPublicKey + "\"}"),
- "{\"keys\":[]}");
+ .userIdentity(USER_ID)
+ .data("{\"key\":\"" + pemPublicKey + "\"}"),
+ "{\"keys\":[]}");
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2", GET)
- .userIdentity(USER_ID),
- new File("application2.json"));
+ .userIdentity(USER_ID),
+ new File("application2.json"));
// DELETE instance 1 of 2
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/instance/default", DELETE)
- .userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS),
- "{\"message\":\"Deleted instance tenant2.application2.default\"}");
+ .userIdentity(USER_ID)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ "{\"message\":\"Deleted instance tenant2.application2.default\"}");
// DELETE application with only one instance left
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2", DELETE)
- .userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS),
- "{\"message\":\"Deleted application tenant2.application2\"}");
+ .userIdentity(USER_ID)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ "{\"message\":\"Deleted application tenant2.application2\"}");
// Set version 6.1 to broken to change compile version for.
deploymentTester.upgrader().overrideConfidence(Version.fromString("6.1"), VespaVersion.Confidence.broken);
@@ -448,44 +448,44 @@ public class ApplicationApiTest extends ControllerContainerTest {
// GET tenant application deployments
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", GET)
- .userIdentity(USER_ID),
- new File("instance.json"));
+ .userIdentity(USER_ID),
+ new File("instance.json"));
// GET an application deployment
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-central-1/instance/instance1", GET)
- .userIdentity(USER_ID),
- new File("deployment.json"));
+ .userIdentity(USER_ID),
+ new File("deployment.json"));
addIssues(deploymentTester, TenantAndApplicationId.from("tenant1", "application1"));
// GET at root, with "&recursive=deployment", returns info about all tenants, their applications and their deployments
tester.assertResponse(request("/application/v4/", GET)
- .userIdentity(USER_ID)
- .recursive("deployment"),
- new File("recursive-root.json"));
+ .userIdentity(USER_ID)
+ .recursive("deployment"),
+ new File("recursive-root.json"));
// GET at root, with "&recursive=tenant", returns info about all tenants, with limited info about their applications.
tester.assertResponse(request("/application/v4/", GET)
- .userIdentity(USER_ID)
- .recursive("tenant"),
- new File("recursive-until-tenant-root.json"));
+ .userIdentity(USER_ID)
+ .recursive("tenant"),
+ new File("recursive-until-tenant-root.json"));
// GET at a tenant, with "&recursive=true", returns full info about their applications and their deployments
tester.assertResponse(request("/application/v4/tenant/tenant1/", GET)
- .userIdentity(USER_ID)
- .recursive("true"),
- new File("tenant1-recursive.json"));
+ .userIdentity(USER_ID)
+ .recursive("true"),
+ new File("tenant1-recursive.json"));
// GET at an application, with "&recursive=true", returns full info about its deployments
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", GET)
- .userIdentity(USER_ID)
- .recursive("true"),
- new File("instance1-recursive.json"));
+ .userIdentity(USER_ID)
+ .recursive("true"),
+ new File("instance1-recursive.json"));
// GET nodes
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-central-1/instance/instance1/nodes", GET)
- .userIdentity(USER_ID),
- new File("application-nodes.json"));
+ .userIdentity(USER_ID),
+ new File("application-nodes.json"));
// GET clusters
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-central-1/instance/instance1/clusters", GET)
- .userIdentity(USER_ID),
- new File("application-clusters.json"));
+ .userIdentity(USER_ID),
+ new File("application-clusters.json"));
// GET logs
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application1/environment/dev/region/us-east-1/instance/default/logs?from=1233&to=3214", GET)
@@ -494,12 +494,12 @@ public class ApplicationApiTest extends ControllerContainerTest {
// GET controller logs
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application1/environment/prod/region/controller/instance/default/logs?from=1233&to=3214", GET)
- .userIdentity(USER_ID),
- "INFO - All good");
+ .userIdentity(USER_ID),
+ "INFO - All good");
// Get content/../foo
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application1/instance/default/environment/dev/region/us-east-1/content/%2E%2E%2Ffoo", GET).userIdentity(USER_ID),
- accessDenied, 403);
+ accessDenied, 403);
// Get content - root
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application1/instance/default/environment/dev/region/us-east-1/content/", GET).userIdentity(USER_ID),
"{\"path\":\"/\"}");
@@ -513,121 +513,121 @@ public class ApplicationApiTest extends ControllerContainerTest {
// GET metrics
tester.assertJsonResponse(request("/application/v4/tenant/tenant2/application/application1/environment/dev/region/us-east-1/instance/default/metrics", GET)
.userIdentity(USER_ID),
- new File("proton-metrics.json"));
+ new File("proton-metrics.json"));
// POST a roll-out of the latest application
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploying/application", POST)
- .userIdentity(USER_ID),
- "{\"message\":\"Triggered revision change to build 1 for tenant1.application1.instance1\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"Triggered revision change to build 1 for tenant1.application1.instance1\"}");
// POST a roll-out of a given revision
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploying/application", POST)
- .data("{ \"build\": 1 }")
- .userIdentity(USER_ID),
- "{\"message\":\"Triggered revision change to build 1 for tenant1.application1.instance1\"}");
+ .data("{ \"build\": 1 }")
+ .userIdentity(USER_ID),
+ "{\"message\":\"Triggered revision change to build 1 for tenant1.application1.instance1\"}");
// DELETE (cancel) ongoing change
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploying", DELETE)
- .userIdentity(HOSTED_VESPA_OPERATOR),
- "{\"message\":\"Changed deployment from 'revision change to build 1' to 'no change' for tenant1.application1.instance1\"}");
+ .userIdentity(HOSTED_VESPA_OPERATOR),
+ "{\"message\":\"Changed deployment from 'revision change to build 1' to 'no change' for tenant1.application1.instance1\"}");
// DELETE (cancel) again is a no-op
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploying", DELETE)
- .userIdentity(USER_ID)
- .data("{\"cancel\":\"all\"}"),
- "{\"message\":\"No deployment in progress for tenant1.application1.instance1 at this time\"}");
+ .userIdentity(USER_ID)
+ .data("{\"cancel\":\"all\"}"),
+ "{\"message\":\"No deployment in progress for tenant1.application1.instance1 at this time\"}");
// POST pinning to a given version to an application
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploying/pin", POST)
- .userIdentity(USER_ID)
- .data("6.1.0"),
- "{\"message\":\"Triggered pin to 6.1 for tenant1.application1.instance1\"}");
- assertTrue("Action is logged to audit log",
- tester.controller().auditLogger().readLog().entries().stream()
- .anyMatch(entry -> entry.resource().equals("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploying/pin?")));
+ .userIdentity(USER_ID)
+ .data("6.1.0"),
+ "{\"message\":\"Triggered pin to 6.1 for tenant1.application1.instance1\"}");
+ assertTrue(tester.controller().auditLogger().readLog().entries().stream()
+ .anyMatch(entry -> entry.resource().equals("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploying/pin?")),
+ "Action is logged to audit log");
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploying", GET)
- .userIdentity(USER_ID), "{\"platform\":\"6.1\",\"pinned\":true}");
+ .userIdentity(USER_ID), "{\"platform\":\"6.1\",\"pinned\":true}");
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploying/pin", GET)
- .userIdentity(USER_ID), "{\"platform\":\"6.1\",\"pinned\":true}");
+ .userIdentity(USER_ID), "{\"platform\":\"6.1\",\"pinned\":true}");
// DELETE only the pin to a given version
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploying/pin", DELETE)
- .userIdentity(USER_ID),
- "{\"message\":\"Changed deployment from 'pin to 6.1' to 'upgrade to 6.1' for tenant1.application1.instance1\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"Changed deployment from 'pin to 6.1' to 'upgrade to 6.1' for tenant1.application1.instance1\"}");
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploying", GET)
- .userIdentity(USER_ID), "{\"platform\":\"6.1\",\"pinned\":false}");
+ .userIdentity(USER_ID), "{\"platform\":\"6.1\",\"pinned\":false}");
// POST pinning again
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploying/pin", POST)
- .userIdentity(USER_ID)
- .data("6.1"),
- "{\"message\":\"Triggered pin to 6.1 for tenant1.application1.instance1\"}");
+ .userIdentity(USER_ID)
+ .data("6.1"),
+ "{\"message\":\"Triggered pin to 6.1 for tenant1.application1.instance1\"}");
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploying", GET)
- .userIdentity(USER_ID), "{\"platform\":\"6.1\",\"pinned\":true}");
+ .userIdentity(USER_ID), "{\"platform\":\"6.1\",\"pinned\":true}");
// DELETE only the version, but leave the pin
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploying/platform", DELETE)
- .userIdentity(USER_ID),
- "{\"message\":\"Changed deployment from 'pin to 6.1' to 'pin to current platform' for tenant1.application1.instance1\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"Changed deployment from 'pin to 6.1' to 'pin to current platform' for tenant1.application1.instance1\"}");
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploying", GET)
- .userIdentity(USER_ID), "{\"pinned\":true}");
+ .userIdentity(USER_ID), "{\"pinned\":true}");
// DELETE also the pin to a given version
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploying/pin", DELETE)
- .userIdentity(USER_ID),
- "{\"message\":\"Changed deployment from 'pin to current platform' to 'no change' for tenant1.application1.instance1\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"Changed deployment from 'pin to current platform' to 'no change' for tenant1.application1.instance1\"}");
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploying", GET)
- .userIdentity(USER_ID), "{}");
+ .userIdentity(USER_ID), "{}");
// POST a pause to a production job
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/job/production-us-west-1/pause", POST)
- .userIdentity(USER_ID),
- "{\"message\":\"production-us-west-1 for tenant1.application1.instance1 paused for " + DeploymentTrigger.maxPause + "\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"production-us-west-1 for tenant1.application1.instance1 paused for " + DeploymentTrigger.maxPause + "\"}");
// DELETE a pause of a production job
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/job/production-us-west-1/pause", DELETE)
- .userIdentity(USER_ID),
- "{\"message\":\"production-us-west-1 for tenant1.application1.instance1 resumed\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"production-us-west-1 for tenant1.application1.instance1 resumed\"}");
// POST a triggering to the same production job
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/job/production-us-west-1", POST)
- .userIdentity(USER_ID),
- "{\"message\":\"Triggered production-us-west-1 for tenant1.application1.instance1\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"Triggered production-us-west-1 for tenant1.application1.instance1\"}");
// POST a 'reindex application' command
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/reindex", POST)
- .properties(Map.of("indexedOnly", "true",
- "speed", "10"))
- .userIdentity(USER_ID),
- "{\"message\":\"Requested reindexing of tenant1.application1.instance1 in prod.us-central-1, for indexed types, with speed 10.0\"}");
+ .properties(Map.of("indexedOnly", "true",
+ "speed", "10"))
+ .userIdentity(USER_ID),
+ "{\"message\":\"Requested reindexing of tenant1.application1.instance1 in prod.us-central-1, for indexed types, with speed 10.0\"}");
// POST a 'reindex application' command with cluster filter
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/reindex", POST)
- .properties(Map.of("clusterId", "boo,moo"))
- .userIdentity(USER_ID),
- "{\"message\":\"Requested reindexing of tenant1.application1.instance1 in prod.us-central-1, on clusters boo, moo\"}");
+ .properties(Map.of("clusterId", "boo,moo"))
+ .userIdentity(USER_ID),
+ "{\"message\":\"Requested reindexing of tenant1.application1.instance1 in prod.us-central-1, on clusters boo, moo\"}");
// POST a 'reindex application' command with cluster and document type filters
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/reindex", POST)
- .properties(Map.of("clusterId", "boo,moo",
- "documentType", "foo,boo"))
- .userIdentity(USER_ID),
- "{\"message\":\"Requested reindexing of tenant1.application1.instance1 in prod.us-central-1, on clusters boo, moo, for types foo, boo\"}");
+ .properties(Map.of("clusterId", "boo,moo",
+ "documentType", "foo,boo"))
+ .userIdentity(USER_ID),
+ "{\"message\":\"Requested reindexing of tenant1.application1.instance1 in prod.us-central-1, on clusters boo, moo, for types foo, boo\"}");
// POST to enable reindexing
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/reindexing", POST)
- .userIdentity(USER_ID),
- "{\"message\":\"Enabled reindexing of tenant1.application1.instance1 in prod.us-central-1\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"Enabled reindexing of tenant1.application1.instance1 in prod.us-central-1\"}");
// DELETE to disable reindexing
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/reindexing", DELETE)
- .userIdentity(USER_ID),
- "{\"message\":\"Disabled reindexing of tenant1.application1.instance1 in prod.us-central-1\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"Disabled reindexing of tenant1.application1.instance1 in prod.us-central-1\"}");
// GET to get reindexing status
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/reindexing", GET)
- .userIdentity(USER_ID),
- "{\"enabled\":true,\"clusters\":[{\"name\":\"cluster\",\"pending\":[{\"type\":\"type\",\"requiredGeneration\":100}],\"ready\":[{\"type\":\"type\",\"readyAtMillis\":345,\"startedAtMillis\":456,\"endedAtMillis\":567,\"state\":\"failed\",\"message\":\"(#`д´)ノ\",\"progress\":0.1,\"speed\":1.0}]}]}");
+ .userIdentity(USER_ID),
+ "{\"enabled\":true,\"clusters\":[{\"name\":\"cluster\",\"pending\":[{\"type\":\"type\",\"requiredGeneration\":100}],\"ready\":[{\"type\":\"type\",\"readyAtMillis\":345,\"startedAtMillis\":456,\"endedAtMillis\":567,\"state\":\"failed\",\"message\":\"(#`д´)ノ\",\"progress\":0.1,\"speed\":1.0}]}]}");
// POST to request a service dump
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/node/host-tenant1.application1.instance1-prod.us-central-1/service-dump", POST)
@@ -643,122 +643,122 @@ public class ApplicationApiTest extends ControllerContainerTest {
// POST a 'restart application' command
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-central-1/instance/instance1/restart", POST)
- .userIdentity(USER_ID),
- "{\"message\":\"Requested restart of tenant1.application1.instance1 in prod.us-central-1\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"Requested restart of tenant1.application1.instance1 in prod.us-central-1\"}");
// POST a 'restart application' command
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-central-1/instance/instance1/restart", POST)
- .userIdentity(HOSTED_VESPA_OPERATOR),
- "{\"message\":\"Requested restart of tenant1.application1.instance1 in prod.us-central-1\"}");
+ .userIdentity(HOSTED_VESPA_OPERATOR),
+ "{\"message\":\"Requested restart of tenant1.application1.instance1 in prod.us-central-1\"}");
addUserToHostedOperatorRole(HostedAthenzIdentities.from(SCREWDRIVER_ID));
// POST a 'restart application' in staging environment
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/staging/region/us-east-3/instance/instance1/restart", POST)
- .screwdriverIdentity(SCREWDRIVER_ID),
- "{\"message\":\"Requested restart of tenant1.application1.instance1 in staging.us-east-3\"}");
+ .screwdriverIdentity(SCREWDRIVER_ID),
+ "{\"message\":\"Requested restart of tenant1.application1.instance1 in staging.us-east-3\"}");
// POST a 'restart application' in test environment
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/test/region/us-east-1/instance/instance1/restart", POST)
- .screwdriverIdentity(SCREWDRIVER_ID),
- "{\"message\":\"Requested restart of tenant1.application1.instance1 in test.us-east-1\"}");
+ .screwdriverIdentity(SCREWDRIVER_ID),
+ "{\"message\":\"Requested restart of tenant1.application1.instance1 in test.us-east-1\"}");
// POST a 'restart application' in dev environment
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-east-1/instance/instance1/restart", POST)
- .userIdentity(USER_ID),
- "{\"message\":\"Requested restart of tenant1.application1.instance1 in dev.us-east-1\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"Requested restart of tenant1.application1.instance1 in dev.us-east-1\"}");
// POST a 'restart application' command with a host filter (other filters not supported yet)
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-central-1/instance/instance1/restart", POST)
- .properties(Map.of("hostname", "node-1-tenant-host-prod.us-central-1"))
- .screwdriverIdentity(SCREWDRIVER_ID),
- "{\"message\":\"Requested restart of tenant1.application1.instance1 in prod.us-central-1\"}", 200);
+ .properties(Map.of("hostname", "node-1-tenant-host-prod.us-central-1"))
+ .screwdriverIdentity(SCREWDRIVER_ID),
+ "{\"message\":\"Requested restart of tenant1.application1.instance1 in prod.us-central-1\"}", 200);
// POST a 'suspend application' in dev environment
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/dev/region/us-east-1/suspend", POST)
- .userIdentity(USER_ID),
- "{\"message\":\"Suspended orchestration of tenant1.application1.instance1 in dev.us-east-1\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"Suspended orchestration of tenant1.application1.instance1 in dev.us-east-1\"}");
// POST a 'resume application' in dev environment
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/dev/region/us-east-1/suspend", DELETE)
- .userIdentity(USER_ID),
- "{\"message\":\"Resumed orchestration of tenant1.application1.instance1 in dev.us-east-1\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"Resumed orchestration of tenant1.application1.instance1 in dev.us-east-1\"}");
// POST a 'suspend application' in prod environment fails
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-east-3/suspend", POST)
- .userIdentity(USER_ID),
- accessDenied, 403);
+ .userIdentity(USER_ID),
+ accessDenied, 403);
// GET suspended
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-central-1/instance/instance1/suspended", GET)
- .userIdentity(USER_ID),
- new File("suspended.json"));
+ .userIdentity(USER_ID),
+ new File("suspended.json"));
// GET service/state/v1
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/service/storagenode/host.com/state/v1/?foo=bar", GET)
- .userIdentity(USER_ID),
- new File("service"));
+ .userIdentity(USER_ID),
+ new File("service"));
// GET orchestrator
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/orchestrator", GET)
- .userIdentity(USER_ID),
- "{\"json\":\"thank you very much\"}");
+ .userIdentity(USER_ID),
+ "{\"json\":\"thank you very much\"}");
// GET application package which has been deployed to production
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/package", GET)
- .properties(Map.of("build", "latestDeployed"))
- .userIdentity(HOSTED_VESPA_OPERATOR),
- (response) -> {
- assertEquals("attachment; filename=\"tenant1.application1-build1.zip\"", response.getHeaders().getFirst("Content-Disposition"));
- assertArrayEquals(applicationPackageInstance1.zippedContent(), response.getBody());
- },
- 200);
+ .properties(Map.of("build", "latestDeployed"))
+ .userIdentity(HOSTED_VESPA_OPERATOR),
+ (response) -> {
+ assertEquals("attachment; filename=\"tenant1.application1-build1.zip\"", response.getHeaders().getFirst("Content-Disposition"));
+ assertArrayEquals(applicationPackageInstance1.zippedContent(), response.getBody());
+ },
+ 200);
// DELETE application with active deployments fails
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", DELETE)
- .userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS),
- new File("delete-with-active-deployments.json"), 400);
+ .userIdentity(USER_ID)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ new File("delete-with-active-deployments.json"), 400);
// DELETE (deactivate) a deployment - dev
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-east-1/instance/instance1", DELETE)
- .userIdentity(USER_ID),
- "{\"message\":\"Deactivated tenant1.application1.instance1 in dev.us-east-1\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"Deactivated tenant1.application1.instance1 in dev.us-east-1\"}");
// DELETE (deactivate) a deployment - prod
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-central-1/instance/instance1", DELETE)
- .screwdriverIdentity(SCREWDRIVER_ID),
- "{\"message\":\"Deactivated tenant1.application1.instance1 in prod.us-central-1\"}");
+ .screwdriverIdentity(SCREWDRIVER_ID),
+ "{\"message\":\"Deactivated tenant1.application1.instance1 in prod.us-central-1\"}");
// DELETE (deactivate) a deployment is idempotent
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-central-1/instance/instance1", DELETE)
- .screwdriverIdentity(SCREWDRIVER_ID),
- "{\"message\":\"Deactivated tenant1.application1.instance1 in prod.us-central-1\"}");
+ .screwdriverIdentity(SCREWDRIVER_ID),
+ "{\"message\":\"Deactivated tenant1.application1.instance1 in prod.us-central-1\"}");
// Setup for test config tests
tester.controller().jobController().deploy(ApplicationId.from("tenant1", "application1", "default"),
- DeploymentContext.productionUsCentral1,
- Optional.empty(),
- applicationPackageDefault);
+ DeploymentContext.productionUsCentral1,
+ Optional.empty(),
+ applicationPackageDefault);
tester.controller().jobController().deploy(ApplicationId.from("tenant1", "application1", "my-user"),
- DeploymentContext.devUsEast1,
- Optional.empty(),
- applicationPackageDefault);
+ DeploymentContext.devUsEast1,
+ Optional.empty(),
+ applicationPackageDefault);
// GET test-config for local tests against a dev deployment
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/my-user/job/dev-us-east-1/test-config", GET)
- .userIdentity(USER_ID),
- new File("test-config-dev.json"));
+ .userIdentity(USER_ID),
+ new File("test-config-dev.json"));
// GET test-config for local tests against a prod deployment
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/my-user/job/production-us-central-1/test-config", GET)
- .userIdentity(USER_ID),
- new File("test-config.json"));
+ .userIdentity(USER_ID),
+ new File("test-config.json"));
tester.controller().applications().deactivate(ApplicationId.from("tenant1", "application1", "default"),
- ZoneId.from("prod", "us-central-1"));
+ ZoneId.from("prod", "us-central-1"));
tester.controller().applications().deactivate(ApplicationId.from("tenant1", "application1", "my-user"),
- ZoneId.from("dev", "us-east-1"));
+ ZoneId.from("dev", "us-east-1"));
// teardown for test config tests
// Second attempt has a service under a different domain than the tenant of the application, and fails.
@@ -769,9 +769,9 @@ public class ApplicationApiTest extends ControllerContainerTest {
.build();
allowLaunchOfService(new com.yahoo.vespa.athenz.api.AthenzService(ATHENZ_TENANT_DOMAIN_2, "service"));
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/submit", POST)
- .screwdriverIdentity(SCREWDRIVER_ID)
- .data(createApplicationSubmissionData(packageWithServiceForWrongDomain, 123)),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Athenz domain in deployment.xml: [domain2] must match tenant domain: [domain1]\"}", 400);
+ .screwdriverIdentity(SCREWDRIVER_ID)
+ .data(createApplicationSubmissionData(packageWithServiceForWrongDomain, 123)),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Athenz domain in deployment.xml: [domain2] must match tenant domain: [domain1]\"}", 400);
// Third attempt has a service under the domain of the tenant, and also succeeds.
ApplicationPackage packageWithService = new ApplicationPackageBuilder()
@@ -783,54 +783,54 @@ public class ApplicationApiTest extends ControllerContainerTest {
.build();
allowLaunchOfService(new com.yahoo.vespa.athenz.api.AthenzService(ATHENZ_TENANT_DOMAIN, "service"));
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/submit", POST)
- .screwdriverIdentity(SCREWDRIVER_ID)
- .data(createApplicationSubmissionData(packageWithService, 123)),
- "{\"message\":\"application build 2, source revision of repository 'repository1', branch 'master' with commit 'commit1', by a@b, built against 6.1 at 1970-01-01T00:00:01Z\"}");
+ .screwdriverIdentity(SCREWDRIVER_ID)
+ .data(createApplicationSubmissionData(packageWithService, 123)),
+ "{\"message\":\"application build 2, source revision of repository 'repository1', branch 'master' with commit 'commit1', by a@b, built against 6.1 at 1970-01-01T00:00:01Z\"}");
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/diff/2", GET).userIdentity(HOSTED_VESPA_OPERATOR),
- (response) -> assertTrue(response.getBodyAsString(),
- response.getBodyAsString().contains("+ <deployment version='1.0' athenz-domain='domain1' athenz-service='service'>\n" +
- "- <deployment version='1.0' >\n")),
- 200);
+ (response) -> assertTrue(response.getBodyAsString().contains("+ <deployment version='1.0' athenz-domain='domain1' athenz-service='service'>\n" +
+ "- <deployment version='1.0' >\n"),
+ response.getBodyAsString()),
+ 200);
// GET last submitted application package
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/package", GET).userIdentity(HOSTED_VESPA_OPERATOR),
- (response) -> {
- assertEquals("attachment; filename=\"tenant1.application1-build2.zip\"", response.getHeaders().getFirst("Content-Disposition"));
- assertArrayEquals(packageWithService.zippedContent(), response.getBody());
- },
- 200);
+ (response) -> {
+ assertEquals("attachment; filename=\"tenant1.application1-build2.zip\"", response.getHeaders().getFirst("Content-Disposition"));
+ assertArrayEquals(packageWithService.zippedContent(), response.getBody());
+ },
+ 200);
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/package", GET).userIdentity(HOSTED_VESPA_OPERATOR).properties(Map.of("tests", "true")),
- (response) -> {
- assertEquals("attachment; filename=\"tenant1.application1-tests2.zip\"", response.getHeaders().getFirst("Content-Disposition"));
- assertArrayEquals("content".getBytes(UTF_8), response.getBody());
- },
- 200);
+ (response) -> {
+ assertEquals("attachment; filename=\"tenant1.application1-tests2.zip\"", response.getHeaders().getFirst("Content-Disposition"));
+ assertArrayEquals("content".getBytes(UTF_8), response.getBody());
+ },
+ 200);
// GET application package for specific build
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/package", GET)
- .properties(Map.of("build", "2"))
- .userIdentity(HOSTED_VESPA_OPERATOR),
- (response) -> {
- assertEquals("attachment; filename=\"tenant1.application1-build2.zip\"", response.getHeaders().getFirst("Content-Disposition"));
- assertArrayEquals(packageWithService.zippedContent(), response.getBody());
- },
- 200);
+ .properties(Map.of("build", "2"))
+ .userIdentity(HOSTED_VESPA_OPERATOR),
+ (response) -> {
+ assertEquals("attachment; filename=\"tenant1.application1-build2.zip\"", response.getHeaders().getFirst("Content-Disposition"));
+ assertArrayEquals(packageWithService.zippedContent(), response.getBody());
+ },
+ 200);
// Fourth attempt has a wrong content hash in a header, and fails.
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/submit", POST)
- .screwdriverIdentity(SCREWDRIVER_ID)
- .header("X-Content-Hash", "not/the/right/hash")
- .data(createApplicationSubmissionData(packageWithService, 123)),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Value of X-Content-Hash header does not match computed content hash\"}", 400);
+ .screwdriverIdentity(SCREWDRIVER_ID)
+ .header("X-Content-Hash", "not/the/right/hash")
+ .data(createApplicationSubmissionData(packageWithService, 123)),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Value of X-Content-Hash header does not match computed content hash\"}", 400);
// Fifth attempt has the right content hash in a header, and succeeds.
MultiPartStreamer streamer = createApplicationSubmissionData(packageWithService, 123);
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/submit", POST)
- .screwdriverIdentity(SCREWDRIVER_ID)
- .header("X-Content-Hash", Base64.getEncoder().encodeToString(Signatures.sha256Digest(streamer::data)))
- .data(streamer),
- "{\"message\":\"application build 3, source revision of repository 'repository1', branch 'master' with commit 'commit1', by a@b, built against 6.1 at 1970-01-01T00:00:01Z\"}");
+ .screwdriverIdentity(SCREWDRIVER_ID)
+ .header("X-Content-Hash", Base64.getEncoder().encodeToString(Signatures.sha256Digest(streamer::data)))
+ .data(streamer),
+ "{\"message\":\"application build 3, source revision of repository 'repository1', branch 'master' with commit 'commit1', by a@b, built against 6.1 at 1970-01-01T00:00:01Z\"}");
// Sixth attempt has a multi-instance deployment spec, and is accepted.
ApplicationPackage multiInstanceSpec = new ApplicationPackageBuilder()
@@ -841,53 +841,53 @@ public class ApplicationApiTest extends ControllerContainerTest {
.endpoint("default", "foo", "us-central-1", "us-west-1", "us-east-3")
.build();
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/submit", POST)
- .screwdriverIdentity(SCREWDRIVER_ID)
- .data(createApplicationSubmissionData(multiInstanceSpec, 123)),
- "{\"message\":\"application build 4, source revision of repository 'repository1', branch 'master' with commit 'commit1', by a@b, built against 6.1 at 1970-01-01T00:00:01Z\"}");
+ .screwdriverIdentity(SCREWDRIVER_ID)
+ .data(createApplicationSubmissionData(multiInstanceSpec, 123)),
+ "{\"message\":\"application build 4, source revision of repository 'repository1', branch 'master' with commit 'commit1', by a@b, built against 6.1 at 1970-01-01T00:00:01Z\"}");
// DELETE submitted build, to mark it as non-deployable
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/submit/2", DELETE)
- .userIdentity(USER_ID),
- "{\"message\":\"Marked build '2' as non-deployable\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"Marked build '2' as non-deployable\"}");
// GET deployment job overview, after triggering system and staging test jobs.
assertEquals(2, tester.controller().applications().deploymentTrigger().triggerReadyJobs().triggered());
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/job", GET)
- .userIdentity(USER_ID),
- new File("jobs.json"));
+ .userIdentity(USER_ID),
+ new File("jobs.json"));
// GET deployment job overview for whole application.
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deployment", GET)
- .userIdentity(USER_ID),
- new File("deployment-overview.json"));
+ .userIdentity(USER_ID),
+ new File("deployment-overview.json"));
// GET system test job overview.
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/job/system-test", GET)
- .userIdentity(USER_ID),
- new File("system-test-job.json"));
+ .userIdentity(USER_ID),
+ new File("system-test-job.json"));
// GET system test run 1 details.
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/job/system-test/run/1", GET)
- .userIdentity(USER_ID),
- new File("system-test-details.json"));
+ .userIdentity(USER_ID),
+ new File("system-test-details.json"));
// DELETE a running job to have it aborted.
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/job/staging-test", DELETE)
- .userIdentity(USER_ID),
- "{\"message\":\"Aborting run 2 of staging-test for tenant1.application1.instance1\"}");
+ .userIdentity(USER_ID),
+ "{\"message\":\"Aborting run 2 of staging-test for tenant1.application1.instance1\"}");
// GET compile version for specific major
deploymentTester.controllerTester().upgradeSystem(Version.fromString("7.0"));
deploymentTester.controllerTester().flagSource().withListFlag(PermanentFlags.INCOMPATIBLE_VERSIONS.id(), List.of("*"), String.class);
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/compile-version", GET)
- .userIdentity(USER_ID).properties(Map.of("allowMajor", "7")),
- "{\"compileVersion\":\"7.0.0\"}");
+ .userIdentity(USER_ID).properties(Map.of("allowMajor", "7")),
+ "{\"compileVersion\":\"7.0.0\"}");
// OPTIONS return 200 OK
tester.assertResponse(request("/application/v4/", Request.Method.OPTIONS)
- .userIdentity(USER_ID),
- "");
+ .userIdentity(USER_ID),
+ "");
addNotifications(TenantName.from("tenant1"));
addNotifications(TenantName.from("tenant2"));
@@ -902,14 +902,14 @@ public class ApplicationApiTest extends ControllerContainerTest {
// DELETE the application which no longer has any deployments
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE)
- .userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS),
- "{\"message\":\"Deleted application tenant1.application1\"}");
+ .userIdentity(USER_ID)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ "{\"message\":\"Deleted application tenant1.application1\"}");
// DELETE an empty tenant
tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE).userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS),
- "{\"message\":\"Deleted tenant tenant1\"}");
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ "{\"message\":\"Deleted tenant tenant1\"}");
// The tenant is not found
tester.assertResponse(request("/application/v4/tenant/tenant1", GET).userIdentity(USER_ID)
@@ -947,7 +947,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
}
@Test
- public void testRotationOverride() {
+ void testRotationOverride() {
// Setup
createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID);
var westZone = ZoneId.from("prod", "us-west-1");
@@ -965,60 +965,60 @@ public class ApplicationApiTest extends ControllerContainerTest {
// Invalid application fails
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/environment/prod/region/us-west-1/instance/default/global-rotation", GET)
- .userIdentity(USER_ID),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"tenant2.application2 not found\"}",
- 400);
+ .userIdentity(USER_ID),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"tenant2.application2 not found\"}",
+ 400);
// Invalid deployment fails
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/global-rotation", GET)
- .userIdentity(USER_ID),
- "{\"error-code\":\"NOT_FOUND\",\"message\":\"application 'tenant1.application1.instance1' has no deployment in prod.us-central-1\"}",
- 404);
+ .userIdentity(USER_ID),
+ "{\"error-code\":\"NOT_FOUND\",\"message\":\"application 'tenant1.application1.instance1' has no deployment in prod.us-central-1\"}",
+ 404);
// Change status of non-existing deployment fails
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/global-rotation/override", PUT)
- .userIdentity(USER_ID)
- .data("{\"reason\":\"unit-test\"}"),
- "{\"error-code\":\"NOT_FOUND\",\"message\":\"application 'tenant1.application1.instance1' has no deployment in prod.us-central-1\"}",
- 404);
+ .userIdentity(USER_ID)
+ .data("{\"reason\":\"unit-test\"}"),
+ "{\"error-code\":\"NOT_FOUND\",\"message\":\"application 'tenant1.application1.instance1' has no deployment in prod.us-central-1\"}",
+ 404);
// GET global rotation status
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-west-1/global-rotation", GET)
- .userIdentity(USER_ID),
- new File("global-rotation.json"));
+ .userIdentity(USER_ID),
+ new File("global-rotation.json"));
// GET global rotation override status
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-west-1/global-rotation/override", GET)
- .userIdentity(USER_ID),
- new File("global-rotation-get.json"));
+ .userIdentity(USER_ID),
+ new File("global-rotation-get.json"));
// SET global rotation override status
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-west-1/global-rotation/override", PUT)
- .userIdentity(USER_ID)
- .data("{\"reason\":\"unit-test\"}"),
- new File("global-rotation-put.json"));
+ .userIdentity(USER_ID)
+ .data("{\"reason\":\"unit-test\"}"),
+ new File("global-rotation-put.json"));
// Status of routing policy is changed
assertGlobalRouting(app.deploymentIdIn(westZone), RoutingStatus.Value.out, RoutingStatus.Agent.tenant);
// DELETE global rotation override status
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-west-1/global-rotation/override", DELETE)
- .userIdentity(USER_ID)
- .data("{\"reason\":\"unit-test\"}"),
- new File("global-rotation-delete.json"));
+ .userIdentity(USER_ID)
+ .data("{\"reason\":\"unit-test\"}"),
+ new File("global-rotation-delete.json"));
assertGlobalRouting(app.deploymentIdIn(westZone), RoutingStatus.Value.in, RoutingStatus.Agent.tenant);
// SET global rotation override status by operator
addUserToHostedOperatorRole(HostedAthenzIdentities.from(HOSTED_VESPA_OPERATOR));
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-west-1/global-rotation/override", PUT)
- .userIdentity(HOSTED_VESPA_OPERATOR)
- .data("{\"reason\":\"unit-test\"}"),
- new File("global-rotation-put.json"));
+ .userIdentity(HOSTED_VESPA_OPERATOR)
+ .data("{\"reason\":\"unit-test\"}"),
+ new File("global-rotation-put.json"));
assertGlobalRouting(app.deploymentIdIn(westZone), RoutingStatus.Value.out, RoutingStatus.Agent.operator);
}
@Test
- public void multiple_endpoints() {
+ void multiple_endpoints() {
// Setup
createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID);
ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
@@ -1036,34 +1036,34 @@ public class ApplicationApiTest extends ControllerContainerTest {
// GET global rotation status without specifying endpointId fails
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-west-1/global-rotation", GET)
- .userIdentity(USER_ID),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"application 'tenant1.application1.instance1' has multiple rotations. Query parameter 'endpointId' must be given\"}",
- 400);
+ .userIdentity(USER_ID),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"application 'tenant1.application1.instance1' has multiple rotations. Query parameter 'endpointId' must be given\"}",
+ 400);
// GET global rotation status for us-west-1 in default endpoint
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-west-1/global-rotation", GET)
- .properties(Map.of("endpointId", "default"))
- .userIdentity(USER_ID),
- "{\"bcpStatus\":{\"rotationStatus\":\"UNKNOWN\"}}",
- 200);
+ .properties(Map.of("endpointId", "default"))
+ .userIdentity(USER_ID),
+ "{\"bcpStatus\":{\"rotationStatus\":\"UNKNOWN\"}}",
+ 200);
// GET global rotation status for us-west-1 in eu endpoint
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-west-1/global-rotation", GET)
- .properties(Map.of("endpointId", "eu"))
- .userIdentity(USER_ID),
- "{\"bcpStatus\":{\"rotationStatus\":\"UNKNOWN\"}}",
- 200);
+ .properties(Map.of("endpointId", "eu"))
+ .userIdentity(USER_ID),
+ "{\"bcpStatus\":{\"rotationStatus\":\"UNKNOWN\"}}",
+ 200);
// GET global rotation status for eu-west-1 in eu endpoint
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/eu-west-1/global-rotation", GET)
- .properties(Map.of("endpointId", "eu"))
- .userIdentity(USER_ID),
- "{\"bcpStatus\":{\"rotationStatus\":\"UNKNOWN\"}}",
- 200);
+ .properties(Map.of("endpointId", "eu"))
+ .userIdentity(USER_ID),
+ "{\"bcpStatus\":{\"rotationStatus\":\"UNKNOWN\"}}",
+ 200);
}
@Test
- public void testDeployWithApplicationPackage() {
+ void testDeployWithApplicationPackage() {
// Setup
addUserToHostedOperatorRole(HostedAthenzIdentities.from(HOSTED_VESPA_OPERATOR));
deploymentTester.controllerTester().upgradeController(new Version("6.2"));
@@ -1071,22 +1071,22 @@ public class ApplicationApiTest extends ControllerContainerTest {
// POST (deploy) a system application with an application package
MultiPartStreamer noAppEntity = createApplicationDeployData(Optional.empty());
tester.assertResponse(request("/application/v4/tenant/hosted-vespa/application/routing/environment/prod/region/us-central-1/instance/default/deploy", POST)
- .data(noAppEntity)
- .userIdentity(HOSTED_VESPA_OPERATOR),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Deployment of system applications during a system upgrade is not allowed\"}",
- 400);
+ .data(noAppEntity)
+ .userIdentity(HOSTED_VESPA_OPERATOR),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Deployment of system applications during a system upgrade is not allowed\"}",
+ 400);
deploymentTester.controllerTester()
- .upgradeSystem(deploymentTester.controller().readVersionStatus().controllerVersion().get()
- .versionNumber());
+ .upgradeSystem(deploymentTester.controller().readVersionStatus().controllerVersion().get()
+ .versionNumber());
tester.assertResponse(request("/application/v4/tenant/hosted-vespa/application/routing/environment/prod/region/us-central-1/instance/default/deploy", POST)
- .data(noAppEntity)
- .userIdentity(HOSTED_VESPA_OPERATOR),
- new File("deploy-result.json"));
+ .data(noAppEntity)
+ .userIdentity(HOSTED_VESPA_OPERATOR),
+ new File("deploy-result.json"));
}
@Test
- public void testRemovingAllDeployments() {
+ void testRemovingAllDeployments() {
createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID);
ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
.instances("instance1")
@@ -1116,100 +1116,100 @@ public class ApplicationApiTest extends ControllerContainerTest {
}
@Test
- public void testErrorResponses() {
+ void testErrorResponses() {
createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID);
// PUT (update) non-existing tenant returns 403 as tenant access cannot be determined when the tenant does not exist
tester.assertResponse(request("/application/v4/tenant/tenant1", PUT)
- .userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS)
- .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
- accessDenied,
- 403);
+ .userIdentity(USER_ID)
+ .oAuthCredentials(OKTA_CREDENTIALS)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
+ accessDenied,
+ 403);
// GET non-existing tenant
tester.assertResponse(request("/application/v4/tenant/tenant1", GET)
- .userIdentity(USER_ID),
- "{\"error-code\":\"NOT_FOUND\",\"message\":\"Tenant 'tenant1' does not exist\"}",
- 404);
+ .userIdentity(USER_ID),
+ "{\"error-code\":\"NOT_FOUND\",\"message\":\"Tenant 'tenant1' does not exist\"}",
+ 404);
// GET non-existing tenant's applications
tester.assertResponse(request("/application/v4/tenant/tenant1/application", GET)
- .userIdentity(USER_ID),
- "{\"error-code\":\"NOT_FOUND\",\"message\":\"Tenant 'tenant1' does not exist\"}",
- 404);
+ .userIdentity(USER_ID),
+ "{\"error-code\":\"NOT_FOUND\",\"message\":\"Tenant 'tenant1' does not exist\"}",
+ 404);
// GET non-existing application
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", GET)
- .userIdentity(USER_ID),
- "{\"error-code\":\"NOT_FOUND\",\"message\":\"tenant1.application1 not found\"}",
- 404);
+ .userIdentity(USER_ID),
+ "{\"error-code\":\"NOT_FOUND\",\"message\":\"tenant1.application1 not found\"}",
+ 404);
// GET non-existing deployment
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-east/instance/default", GET)
- .userIdentity(USER_ID),
- "{\"error-code\":\"NOT_FOUND\",\"message\":\"tenant1.application1 not found\"}",
- 404);
+ .userIdentity(USER_ID),
+ "{\"error-code\":\"NOT_FOUND\",\"message\":\"tenant1.application1 not found\"}",
+ 404);
// POST (add) a tenant
tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
- .userIdentity(USER_ID)
- .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
- .oAuthCredentials(OKTA_CREDENTIALS),
- new File("tenant-without-applications.json"));
+ .userIdentity(USER_ID)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ new File("tenant-without-applications.json"));
// POST (add) another tenant under the same domain
tester.assertResponse(request("/application/v4/tenant/tenant2", POST)
- .userIdentity(USER_ID)
- .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
- .oAuthCredentials(OKTA_CREDENTIALS),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Could not create tenant 'tenant2': The Athens domain 'domain1' is already connected to tenant 'tenant1'\"}",
- 400);
+ .userIdentity(USER_ID)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Could not create tenant 'tenant2': The Athens domain 'domain1' is already connected to tenant 'tenant1'\"}",
+ 400);
// Add the same tenant again
tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
- .userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS)
- .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Tenant 'tenant1' already exists\"}",
- 400);
+ .userIdentity(USER_ID)
+ .oAuthCredentials(OKTA_CREDENTIALS)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Tenant 'tenant1' already exists\"}",
+ 400);
// POST (add) an Athenz tenant with underscore in name
tester.assertResponse(request("/application/v4/tenant/my_tenant_2", POST)
- .userIdentity(USER_ID)
- .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
- .oAuthCredentials(OKTA_CREDENTIALS),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"New tenant or application names must start with a letter, may contain no more than 20 characters, and may only contain lowercase letters, digits or dashes, but no double-dashes.\"}",
- 400);
+ .userIdentity(USER_ID)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"New tenant or application names must start with a letter, may contain no more than 20 characters, and may only contain lowercase letters, digits or dashes, but no double-dashes.\"}",
+ 400);
// POST (add) an Athenz tenant with a reserved name
tester.assertResponse(request("/application/v4/tenant/hosted-vespa", POST)
- .userIdentity(USER_ID)
- .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
- .oAuthCredentials(OKTA_CREDENTIALS),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Tenant 'hosted-vespa' already exists\"}",
- 400);
+ .userIdentity(USER_ID)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Tenant 'hosted-vespa' already exists\"}",
+ 400);
// POST (create) an (empty) application
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", POST)
- .userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS),
- new File("instance-reference.json"));
+ .userIdentity(USER_ID)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ new File("instance-reference.json"));
// Create the same application again
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", POST)
- .oAuthCredentials(OKTA_CREDENTIALS)
- .userIdentity(USER_ID),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Could not create 'tenant1.application1.instance1': Instance already exists\"}",
- 400);
+ .oAuthCredentials(OKTA_CREDENTIALS)
+ .userIdentity(USER_ID),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Could not create 'tenant1.application1.instance1': Instance already exists\"}",
+ 400);
ConfigServerMock configServer = tester.serviceRegistry().configServerMock();
configServer.throwOnNextPrepare(new ConfigServerException(ConfigServerException.ErrorCode.INVALID_APPLICATION_PACKAGE, "Failed to prepare application", "Invalid application package"));
// GET non-existent application package
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/package", GET).userIdentity(HOSTED_VESPA_OPERATOR),
- "{\"error-code\":\"NOT_FOUND\",\"message\":\"no application package has been submitted for tenant1.application1\"}",
- 404);
+ "{\"error-code\":\"NOT_FOUND\",\"message\":\"no application package has been submitted for tenant1.application1\"}",
+ 404);
// GET non-existent application package of specific build
addScrewdriverUserToDeployRole(SCREWDRIVER_ID, ATHENZ_TENANT_DOMAIN, ApplicationName.from("application1"));
@@ -1218,63 +1218,63 @@ public class ApplicationApiTest extends ControllerContainerTest {
.data(createApplicationSubmissionData(applicationPackageInstance1, 1000)),
"{\"message\":\"application build 1, source revision of repository 'repository1', branch 'master' with commit 'commit1', by a@b, built against 6.1 at 1970-01-01T00:00:01Z\"}");
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/package", GET)
- .properties(Map.of("build", "42"))
- .userIdentity(HOSTED_VESPA_OPERATOR),
- "{\"error-code\":\"NOT_FOUND\",\"message\":\"No build 42 found for tenant1.application1\"}",
- 404);
+ .properties(Map.of("build", "42"))
+ .userIdentity(HOSTED_VESPA_OPERATOR),
+ "{\"error-code\":\"NOT_FOUND\",\"message\":\"No build 42 found for tenant1.application1\"}",
+ 404);
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deployment", DELETE).userIdentity(USER_ID).oAuthCredentials(OKTA_CREDENTIALS),
"{\"message\":\"All deployments removed\"}");
// GET non-existent application package of invalid build
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/package", GET)
- .properties(Map.of("build", "foobar"))
- .userIdentity(HOSTED_VESPA_OPERATOR),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"invalid value for request parameter 'build': For input string: \\\"foobar\\\"\"}",
- 400);
-
+ .properties(Map.of("build", "foobar"))
+ .userIdentity(HOSTED_VESPA_OPERATOR),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"invalid value for request parameter 'build': For input string: \\\"foobar\\\"\"}",
+ 400);
+
// POST (deploy) an application to legacy deploy path
MultiPartStreamer entity = createApplicationDeployData(applicationPackageInstance1);
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-east-1/instance/instance1/deploy", POST)
- .data(entity)
- .userIdentity(USER_ID),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Deployment of tenant1.application1.instance1 is not supported through this API\"}", 400);
+ .data(entity)
+ .userIdentity(USER_ID),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Deployment of tenant1.application1.instance1 is not supported through this API\"}", 400);
// DELETE tenant which has an application
tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE)
- .userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Could not delete tenant 'tenant1': This tenant has active applications\"}",
- 400);
+ .userIdentity(USER_ID)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Could not delete tenant 'tenant1': This tenant has active applications\"}",
+ 400);
// DELETE application
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", DELETE)
- .userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS),
- "{\"message\":\"Deleted instance tenant1.application1.instance1\"}");
+ .userIdentity(USER_ID)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ "{\"message\":\"Deleted instance tenant1.application1.instance1\"}");
// DELETE application again - should produce 404
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", DELETE)
- .oAuthCredentials(OKTA_CREDENTIALS)
- .userIdentity(USER_ID),
- "{\"error-code\":\"NOT_FOUND\",\"message\":\"Could not delete instance 'tenant1.application1.instance1': Instance not found\"}",
- 404);
+ .oAuthCredentials(OKTA_CREDENTIALS)
+ .userIdentity(USER_ID),
+ "{\"error-code\":\"NOT_FOUND\",\"message\":\"Could not delete instance 'tenant1.application1.instance1': Instance not found\"}",
+ 404);
// DELETE and forget an application as non-operator
tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE).properties(Map.of("forget", "true"))
- .userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS),
- "{\"error-code\":\"FORBIDDEN\",\"message\":\"Only operators can forget a tenant\"}",
- 403);
+ .userIdentity(USER_ID)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ "{\"error-code\":\"FORBIDDEN\",\"message\":\"Only operators can forget a tenant\"}",
+ 403);
// DELETE tenant
tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE)
- .userIdentity(USER_ID)
- .oAuthCredentials(OKTA_CREDENTIALS),
- "{\"message\":\"Deleted tenant tenant1\"}");
+ .userIdentity(USER_ID)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ "{\"message\":\"Deleted tenant tenant1\"}");
// DELETE tenant again returns 403 as tenant access cannot be determined when the tenant does not exist
tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE)
- .userIdentity(USER_ID),
- accessDenied,
- 403);
+ .userIdentity(USER_ID),
+ accessDenied,
+ 403);
// Create legacy tenant name containing underscores
tester.controller().curator().writeTenant(new AthenzTenant(TenantName.from("my_tenant"), ATHENZ_TENANT_DOMAIN,
@@ -1282,116 +1282,116 @@ public class ApplicationApiTest extends ControllerContainerTest {
// POST (add) a Athenz tenant with dashes duplicates existing one with underscores
tester.assertResponse(request("/application/v4/tenant/my-tenant", POST)
- .userIdentity(USER_ID)
- .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
- .oAuthCredentials(OKTA_CREDENTIALS),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Tenant 'my-tenant' already exists\"}",
- 400);
+ .userIdentity(USER_ID)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Tenant 'my-tenant' already exists\"}",
+ 400);
}
@Test
- public void testAuthorization() {
+ void testAuthorization() {
UserId authorizedUser = USER_ID;
UserId unauthorizedUser = new UserId("othertenant");
-
+
// Mutation without an user is disallowed
tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
- .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
- "{\n \"message\" : \"Not authenticated\"\n}",
- 401);
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
+ "{\n \"message\" : \"Not authenticated\"\n}",
+ 401);
// ... but read methods are allowed for authenticated user
tester.assertResponse(request("/application/v4/tenant/", GET)
- .userIdentity(USER_ID)
- .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
- "[]",
- 200);
+ .userIdentity(USER_ID)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
+ "[]",
+ 200);
createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID);
// Creating a tenant for an Athens domain the user is not admin for is disallowed
tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
- .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
- .oAuthCredentials(OKTA_CREDENTIALS)
- .userIdentity(unauthorizedUser),
- "{\"error-code\":\"FORBIDDEN\",\"message\":\"The user 'user.othertenant' is not admin in Athenz domain 'domain1'\"}",
- 403);
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
+ .oAuthCredentials(OKTA_CREDENTIALS)
+ .userIdentity(unauthorizedUser),
+ "{\"error-code\":\"FORBIDDEN\",\"message\":\"The user 'user.othertenant' is not admin in Athenz domain 'domain1'\"}",
+ 403);
// (Create it with the right tenant id)
tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
- .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
- .userIdentity(authorizedUser)
- .oAuthCredentials(OKTA_CREDENTIALS),
- new File("tenant-without-applications.json"),
- 200);
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
+ .userIdentity(authorizedUser)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ new File("tenant-without-applications.json"),
+ 200);
// Creating an application for an Athens domain the user is not admin for is disallowed
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", POST)
- .userIdentity(unauthorizedUser)
- .oAuthCredentials(OKTA_CREDENTIALS),
- accessDenied,
- 403);
+ .userIdentity(unauthorizedUser)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ accessDenied,
+ 403);
// (Create it with the right tenant id)
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", POST)
- .userIdentity(authorizedUser)
- .oAuthCredentials(OKTA_CREDENTIALS),
- new File("instance-reference.json"),
- 200);
+ .userIdentity(authorizedUser)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ new File("instance-reference.json"),
+ 200);
// Deploy to an authorized zone by a user tenant is disallowed
MultiPartStreamer entity = createApplicationDeployData(applicationPackageDefault);
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/deploy", POST)
- .data(entity)
- .userIdentity(USER_ID),
- accessDenied,
- 403);
+ .data(entity)
+ .userIdentity(USER_ID),
+ accessDenied,
+ 403);
// Deleting an application for an Athens domain the user is not admin for is disallowed
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE)
- .userIdentity(unauthorizedUser),
- accessDenied,
- 403);
+ .userIdentity(unauthorizedUser),
+ accessDenied,
+ 403);
// Create another instance under the application
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/default", POST)
- .userIdentity(authorizedUser)
- .oAuthCredentials(OKTA_CREDENTIALS),
- new File("instance-reference-default.json"),
- 200);
+ .userIdentity(authorizedUser)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ new File("instance-reference-default.json"),
+ 200);
// (Deleting the application with the right tenant id)
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE)
- .userIdentity(authorizedUser)
- .oAuthCredentials(OKTA_CREDENTIALS),
- "{\"message\":\"Deleted application tenant1.application1\"}",
- 200);
+ .userIdentity(authorizedUser)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ "{\"message\":\"Deleted application tenant1.application1\"}",
+ 200);
// Updating a tenant for an Athens domain the user is not admin for is disallowed
tester.assertResponse(request("/application/v4/tenant/tenant1", PUT)
- .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
- .userIdentity(unauthorizedUser),
- accessDenied,
- 403);
-
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
+ .userIdentity(unauthorizedUser),
+ accessDenied,
+ 403);
+
// Change Athens domain
createAthenzDomainWithAdmin(new AthenzDomain("domain2"), USER_ID);
tester.assertResponse(request("/application/v4/tenant/tenant1", PUT)
- .data("{\"athensDomain\":\"domain2\", \"property\":\"property1\"}")
- .userIdentity(authorizedUser)
- .oAuthCredentials(OKTA_CREDENTIALS),
- new File("tenant1.json"),
- 200);
+ .data("{\"athensDomain\":\"domain2\", \"property\":\"property1\"}")
+ .userIdentity(authorizedUser)
+ .oAuthCredentials(OKTA_CREDENTIALS),
+ new File("tenant1.json"),
+ 200);
// Deleting a tenant for an Athens domain the user is not admin for is disallowed
tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE)
- .userIdentity(unauthorizedUser),
- accessDenied,
- 403);
+ .userIdentity(unauthorizedUser),
+ accessDenied,
+ 403);
}
@Test
- public void athenz_service_must_be_allowed_to_launch_and_be_under_tenant_domain() {
+ void athenz_service_must_be_allowed_to_launch_and_be_under_tenant_domain() {
ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
.upgradePolicy("default")
.athenzIdentity(com.yahoo.config.provision.AthenzDomain.from("another.domain"), com.yahoo.config.provision.AthenzService.from("service"))
@@ -1407,10 +1407,10 @@ public class ApplicationApiTest extends ControllerContainerTest {
allowLaunchOfService(new com.yahoo.vespa.athenz.api.AthenzService(new AthenzDomain("another.domain"), "service"));
// Submit a package with a service under a different Athenz domain from that of the tenant
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/submit/", POST)
- .data(createApplicationSubmissionData(applicationPackage, 123))
- .screwdriverIdentity(screwdriverId),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Athenz domain in deployment.xml: [another.domain] must match tenant domain: [domain1]\"}",
- 400);
+ .data(createApplicationSubmissionData(applicationPackage, 123))
+ .screwdriverIdentity(screwdriverId),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Athenz domain in deployment.xml: [another.domain] must match tenant domain: [domain1]\"}",
+ 400);
// Set the correct domain in the application package, but do not yet allow Vespa to launch the service.
applicationPackage = new ApplicationPackageBuilder()
@@ -1420,22 +1420,22 @@ public class ApplicationApiTest extends ControllerContainerTest {
.build();
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/submit", POST)
- .data(createApplicationSubmissionData(applicationPackage, 123))
- .screwdriverIdentity(screwdriverId),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Not allowed to launch Athenz service domain1.service\"}",
- 400);
+ .data(createApplicationSubmissionData(applicationPackage, 123))
+ .screwdriverIdentity(screwdriverId),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Not allowed to launch Athenz service domain1.service\"}",
+ 400);
// Allow Vespa to launch the Athenz service.
allowLaunchOfService(new com.yahoo.vespa.athenz.api.AthenzService(ATHENZ_TENANT_DOMAIN, "service"));
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/submit/", POST)
- .data(createApplicationSubmissionData(applicationPackage, 123))
- .screwdriverIdentity(screwdriverId),
- "{\"message\":\"application build 1, source revision of repository 'repository1', branch 'master' with commit 'commit1', by a@b, built against 6.1 at 1970-01-01T00:00:01Z\"}");
+ .data(createApplicationSubmissionData(applicationPackage, 123))
+ .screwdriverIdentity(screwdriverId),
+ "{\"message\":\"application build 1, source revision of repository 'repository1', branch 'master' with commit 'commit1', by a@b, built against 6.1 at 1970-01-01T00:00:01Z\"}");
}
@Test
- public void personal_deployment_with_athenz_service_requires_user_is_admin() {
+ void personal_deployment_with_athenz_service_requires_user_is_admin() {
// Setup
UserId tenantAdmin = new UserId("tenant-admin");
UserId userId = new UserId("new-user");
@@ -1450,26 +1450,26 @@ public class ApplicationApiTest extends ControllerContainerTest {
MultiPartStreamer entity = createApplicationDeployData(applicationPackage);
// POST (deploy) an application to dev through a deployment job, with user instance and a proper tenant
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/new-user/deploy/dev-us-east-1", POST)
- .data(entity)
- .userIdentity(userId),
- accessDenied,
- 403);
+ .data(entity)
+ .userIdentity(userId),
+ accessDenied,
+ 403);
// Add "new-user" to the admin role, to allow service launches.
tester.athenzClientFactory().getSetup()
.domains.get(ATHENZ_TENANT_DOMAIN)
- .admin(HostedAthenzIdentities.from(userId));
+ .admin(HostedAthenzIdentities.from(userId));
// POST (deploy) an application to dev through a deployment job
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/new-user/deploy/dev-us-east-1", POST)
- .data(entity)
- .userIdentity(userId),
- "{\"message\":\"Deployment started in run 1 of dev-us-east-1 for tenant1.application1.new-user. This may take about 15 minutes the first time.\",\"run\":1}");
+ .data(entity)
+ .userIdentity(userId),
+ "{\"message\":\"Deployment started in run 1 of dev-us-east-1 for tenant1.application1.new-user. This may take about 15 minutes the first time.\",\"run\":1}");
}
- @Test
// Deploy to sandbox tenant launching a service from another domain.
- public void developers_can_deploy_when_privileged() {
+ @Test
+ void developers_can_deploy_when_privileged() {
// Create an athenz domain where the developer is not yet authorized
UserId tenantAdmin = new UserId("tenant-admin");
createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, tenantAdmin);
@@ -1503,7 +1503,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
// Allow developer launch privilege to domain1.service. Deployment now completes.
AthenzDbMock.Domain domainMock = tester.athenzClientFactory().getSetup().getOrCreateDomain(ATHENZ_TENANT_DOMAIN);
- domainMock.withPolicy("launch-" +developer.id(), "user." + developer.id(), "launch", "service.service");
+ domainMock.withPolicy("launch-" + developer.id(), "user." + developer.id(), "launch", "service.service");
tester.assertResponse(request("/application/v4/tenant/sandbox/application/myapp/instance/default/deploy/dev-us-east-1", POST)
@@ -1526,25 +1526,25 @@ public class ApplicationApiTest extends ControllerContainerTest {
// POST (deploy) an application package as content type application/zip — not multipart
tester.assertResponse(request("/application/v4/tenant/sandbox/application/myapp/instance/default/deploy/dev-us-east-1", POST)
- .data(applicationPackageInstance1.zippedContent())
- .contentType("application/zip")
- .userIdentity(developer2),
- "{\"message\":\"Deployment started in run 3 of dev-us-east-1 for sandbox.myapp. This may take about 15 minutes the first time.\",\"run\":3}");
+ .data(applicationPackageInstance1.zippedContent())
+ .contentType("application/zip")
+ .userIdentity(developer2),
+ "{\"message\":\"Deployment started in run 3 of dev-us-east-1 for sandbox.myapp. This may take about 15 minutes the first time.\",\"run\":3}");
// POST (deploy) an application package not as content type application/zip — not multipart — is disallowed
tester.assertResponse(request("/application/v4/tenant/sandbox/application/myapp/instance/default/deploy/dev-us-east-1", POST)
- .data(applicationPackageInstance1.zippedContent())
- .contentType("application/gzip")
- .userIdentity(developer2),
- "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Expected a multipart or application/zip message, but got Content-Type: application/gzip\"}", 400);
+ .data(applicationPackageInstance1.zippedContent())
+ .contentType("application/gzip")
+ .userIdentity(developer2),
+ "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Expected a multipart or application/zip message, but got Content-Type: application/gzip\"}", 400);
}
@Test
- public void applicationWithRoutingPolicy() {
+ void applicationWithRoutingPolicy() {
var app = deploymentTester.newDeploymentContext(createTenantAndApplication());
var zone = ZoneId.from(Environment.prod, RegionName.from("us-west-1"));
deploymentTester.controllerTester().zoneRegistry().setRoutingMethod(ZoneApiMock.from(zone),
- RoutingMethod.exclusive);
+ RoutingMethod.exclusive);
ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
.athenzIdentity(com.yahoo.config.provision.AthenzDomain.from("domain"), AthenzService.from("service"))
.instances("instance1")
@@ -1555,22 +1555,22 @@ public class ApplicationApiTest extends ControllerContainerTest {
// GET application
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", GET)
- .userIdentity(USER_ID),
- new File("instance-with-routing-policy.json"));
+ .userIdentity(USER_ID),
+ new File("instance-with-routing-policy.json"));
// GET deployment
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/instance1", GET)
- .userIdentity(USER_ID),
- new File("deployment-with-routing-policy.json"));
+ .userIdentity(USER_ID),
+ new File("deployment-with-routing-policy.json"));
// GET deployment
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/instance1", GET)
- .userIdentity(USER_ID),
- new File("deployment-without-shared-endpoints.json"));
+ .userIdentity(USER_ID),
+ new File("deployment-without-shared-endpoints.json"));
}
@Test
- public void support_access() {
+ void support_access() {
var app = deploymentTester.newDeploymentContext(createTenantAndApplication());
var zone = ZoneId.from(Environment.prod, RegionName.from("us-west-1"));
deploymentTester.controllerTester().zoneRegistry().setRoutingMethod(ZoneApiMock.from(zone), RoutingMethod.exclusive);
@@ -1601,15 +1601,15 @@ public class ApplicationApiTest extends ControllerContainerTest {
// Grant access to support user
X509Certificate support_cert = grantCertificate(now, now.plusSeconds(3600));
- String grantPayload= "{\n" +
- " \"applicationId\": \"tenant1:application1:instance1\",\n" +
- " \"zone\": \"prod.us-west-1\",\n" +
- " \"certificate\":\""+X509CertificateUtils.toPem(support_cert)+ "\"\n" +
- "}";
- tester.assertResponse(request("/controller/v1/access/grants/"+HOSTED_VESPA_OPERATOR.id(), POST)
- .data(grantPayload)
- .userIdentity(HOSTED_VESPA_OPERATOR),
- "{\"message\":\"Operator user.johnoperator granted access and job production-us-west-1 triggered\"}");
+ String grantPayload = "{\n" +
+ " \"applicationId\": \"tenant1:application1:instance1\",\n" +
+ " \"zone\": \"prod.us-west-1\",\n" +
+ " \"certificate\":\"" + X509CertificateUtils.toPem(support_cert) + "\"\n" +
+ "}";
+ tester.assertResponse(request("/controller/v1/access/grants/" + HOSTED_VESPA_OPERATOR.id(), POST)
+ .data(grantPayload)
+ .userIdentity(HOSTED_VESPA_OPERATOR),
+ "{\"message\":\"Operator user.johnoperator granted access and job production-us-west-1 triggered\"}");
// GET shows grant
String grantResponse = allowedResponse.replaceAll("\"grants\":\\[]",
@@ -1631,7 +1631,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
// DELETE removes access
String disallowedResponse = grantResponse
.replaceAll("ALLOWED\".*?}", "NOT_ALLOWED\"}")
- .replace("history\":[", "history\":[{\"state\":\"disallowed\",\"at\":\""+ serializeInstant(now) +"\",\"by\":\"user.myuser\"},");
+ .replace("history\":[", "history\":[{\"state\":\"disallowed\",\"at\":\"" + serializeInstant(now) + "\",\"by\":\"user.myuser\"},");
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-west-1/access/support", DELETE)
.userIdentity(USER_ID),
disallowedResponse, 200
@@ -1646,7 +1646,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
}
@Test
- public void create_application_on_deploy() {
+ void create_application_on_deploy() {
// Setup
createAthenzDomainWithAdmin(ATHENZ_TENANT_DOMAIN, USER_ID);
addUserToHostedOperatorRole(HostedAthenzIdentities.from(HOSTED_VESPA_OPERATOR));
@@ -1668,7 +1668,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/deploy/dev-us-east-1/", POST)
.data(entity)
.oAuthCredentials(OKTA_CREDENTIALS)
-
+
.userIdentity(USER_ID),
"{\"message\":\"Deployment started in run 1 of dev-us-east-1 for tenant1.application1.instance1. This may take about 15 minutes the first time.\",\"run\":1}");