diff options
author | Ola Aunrønning <olaa@verizonmedia.com> | 2021-02-18 14:35:21 +0100 |
---|---|---|
committer | Ola Aunrønning <olaa@verizonmedia.com> | 2021-02-18 15:02:26 +0100 |
commit | c01b41f05eb3325dd25ef4cc865e4f159883175e (patch) | |
tree | 5b46b16d75a38f0b9b3cda3caf53bfdc5bdc1bdd | |
parent | cf904cc81f6a39a2e68c4aa7433befdaf9ca9cf3 (diff) |
Add test. Include protocol
6 files changed, 125 insertions, 5 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java index 8c13d52a201..a253dac7d1b 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java @@ -268,6 +268,11 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye return this; } + public Builder withSecretStoreValidator(SecretStoreValidator secretStoreValidator) { + this.secretStoreValidator = secretStoreValidator; + return this; + } + public ApplicationRepository build() { return new ApplicationRepository(tenantRepository, hostProvisioner, diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/SecretStoreValidator.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/SecretStoreValidator.java index d8c09eecd6d..d3ce5096583 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/SecretStoreValidator.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/SecretStoreValidator.java @@ -10,7 +10,6 @@ import com.yahoo.slime.SlimeUtils; import com.yahoo.vespa.config.server.application.Application; import com.yahoo.vespa.config.server.application.TenantSecretStore; import com.yahoo.yolean.Exceptions; -import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.impl.client.CloseableHttpClient; @@ -26,6 +25,8 @@ import static com.yahoo.yolean.Exceptions.uncheck; */ public class SecretStoreValidator { + // http for easier testing. VespaHttpClient rewrites to https + private static final String PROTOCOL = "http://"; private static final String AWS_PARAMETER_VALIDATION_HANDLER_POSTFIX = ":4080/validate-secret-store"; private final SecretStore secretStore; private final CloseableHttpClient httpClient = VespaHttpClientBuilder.create().build(); @@ -60,7 +61,7 @@ public class SecretStoreValidator { .count() > 0) .map(HostInfo::getHostname) .findFirst().orElseThrow(); - return URI.create(hostname + AWS_PARAMETER_VALIDATION_HANDLER_POSTFIX); + return URI.create(PROTOCOL + hostname + AWS_PARAMETER_VALIDATION_HANDLER_POSTFIX); } private HttpResponse postRequest(URI uri, Slime slime) { @@ -68,8 +69,8 @@ public class SecretStoreValidator { var data = uncheck(() -> SlimeUtils.toJsonBytes(slime)); var entity = new ByteArrayEntity(data); postRequest.setEntity(entity); - try (CloseableHttpResponse response = httpClient.execute(postRequest)){ - return new ProxyResponse(response); + try { + return new ProxyResponse(httpClient.execute(postRequest)); } catch (IOException e) { return HttpErrorResponse.internalServerError( String.format("Failed to post request to %s: %s", uri, Exceptions.toMessageString(e)) diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java index ec714eed575..e4aae404919 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java @@ -426,7 +426,7 @@ public class ApplicationHandler extends HttpHandler { private static String tenantSecretNameFromRequest(HttpRequest req) { BindingMatch<?> bm = getBindingMatch(req); - return bm.group(8); + return bm.group(7); } private static ApplicationId getApplicationIdFromRequest(HttpRequest req) { diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/MockSecretStoreValidator.java b/configserver/src/test/java/com/yahoo/vespa/config/server/MockSecretStoreValidator.java new file mode 100644 index 00000000000..a46cfc4fef0 --- /dev/null +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/MockSecretStoreValidator.java @@ -0,0 +1,23 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.config.server; + +import com.yahoo.container.jdisc.HttpResponse; +import com.yahoo.container.jdisc.SecretStoreProvider; +import com.yahoo.restapi.StringResponse; +import com.yahoo.vespa.config.server.application.Application; +import com.yahoo.vespa.config.server.application.TenantSecretStore; +import com.yahoo.vespa.config.server.http.SecretStoreValidator; + +/** + * @author olaa + */ +public class MockSecretStoreValidator extends SecretStoreValidator { + + public MockSecretStoreValidator() { + super(new SecretStoreProvider().get()); + } + + public HttpResponse validateSecretStore(Application application, TenantSecretStore tenantSecretStore, String tenantSecretName) { + return new StringResponse(tenantSecretStore.toString() + " - " + tenantSecretName); + } +} diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/SecretStoreValidatorTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/SecretStoreValidatorTest.java new file mode 100644 index 00000000000..affab6ab835 --- /dev/null +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/SecretStoreValidatorTest.java @@ -0,0 +1,71 @@ +package com.yahoo.vespa.config.server.http; + +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import com.yahoo.config.model.api.HostInfo; +import com.yahoo.config.model.api.Model; +import com.yahoo.config.model.api.ServiceInfo; +import com.yahoo.container.jdisc.secretstore.SecretStore; +import com.yahoo.vespa.config.server.application.Application; +import com.yahoo.vespa.config.server.application.TenantSecretStore; +import org.junit.Rule; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.List; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * @author olaa + */ +public class SecretStoreValidatorTest { + + private final SecretStore secretStore = mock(SecretStore.class); + private final SecretStoreValidator secretStoreValidator = new SecretStoreValidator(secretStore); + + @Rule + public final WireMockRule wireMock = new WireMockRule(options().port(4080), true); + + @Test + public void createsCorrectRequestData() throws IOException { + var app = mockApplication(); + var tenantSecretStore = new TenantSecretStore("store", "123", "role"); + var tenantSecretName = "some-secret"; + when(secretStore.getSecret(tenantSecretName)).thenReturn("some-secret-value"); + + stubFor(post(urlEqualTo("/validate-secret-store")) + .withRequestBody(equalToJson("{\"externalId\":\"some-secret-value\"," + + "\"awsId\":\"123\"," + + "\"name\":\"store\"," + + "\"role\":\"role\"" + + "}")) + .willReturn(aResponse() + .withStatus(200) + .withBody("is ok"))); + var response = secretStoreValidator.validateSecretStore(app, tenantSecretStore, tenantSecretName); + var body = new ByteArrayOutputStream(); + response.render(body); + assertEquals("is ok", body.toString()); + } + + private Application mockApplication() { + var app = mock(Application.class); + var model = mock(Model.class); + var hostList = createHostList(); + when(app.getModel()).thenReturn(model); + when(model.getHosts()).thenReturn(hostList); + return app; + } + + private List<HostInfo> createHostList() { + return List.of(new HostInfo("localhost", + List.of(new ServiceInfo("default", "container", null, null, "", "localhost")) + )); + } +}
\ No newline at end of file diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java index e699e5f82b2..ab9457c5d2a 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java @@ -17,6 +17,7 @@ import com.yahoo.test.ManualClock; import com.yahoo.vespa.config.server.ApplicationRepository; import com.yahoo.vespa.config.server.MockLogRetriever; import com.yahoo.vespa.config.server.MockProvisioner; +import com.yahoo.vespa.config.server.MockSecretStoreValidator; import com.yahoo.vespa.config.server.MockTesterClient; import com.yahoo.vespa.config.server.application.ApplicationCuratorDatabase; import com.yahoo.vespa.config.server.application.ApplicationReindexing; @@ -28,6 +29,7 @@ import com.yahoo.vespa.config.server.deploy.DeployTester; import com.yahoo.vespa.config.server.filedistribution.MockFileDistributionFactory; import com.yahoo.vespa.config.server.http.HandlerTest; import com.yahoo.vespa.config.server.http.HttpErrorResponse; +import com.yahoo.vespa.config.server.http.SecretStoreValidator; import com.yahoo.vespa.config.server.http.SessionHandlerTest; import com.yahoo.vespa.config.server.http.StaticResponse; import com.yahoo.vespa.config.server.http.v2.ApplicationHandler.ReindexingResponse; @@ -89,6 +91,7 @@ public class ApplicationHandlerTest { private final static MockTesterClient testerClient = new MockTesterClient(); private static final MockLogRetriever logRetriever = new MockLogRetriever(); private static final Version vespaVersion = Version.fromString("7.8.9"); + private static final SecretStoreValidator secretStoreValidator = new MockSecretStoreValidator(); private TenantRepository tenantRepository; private ApplicationRepository applicationRepository; @@ -126,6 +129,7 @@ public class ApplicationHandlerTest { .withTesterClient(testerClient) .withLogRetriever(logRetriever) .withConfigserverConfig(configserverConfig) + .withSecretStoreValidator(secretStoreValidator) .build(); } @@ -395,6 +399,22 @@ public class ApplicationHandlerTest { } @Test + public void testValidateSecretStore() throws IOException { + applicationRepository.deploy(new File("src/test/apps/app-logserver-with-container"), prepareParams(applicationId)); + var url = toUrlPath(applicationId, Zone.defaultZone(), true) + "/validate-secret-store/some-secret-name"; + var mockHandler = createApplicationHandler(); + + var requestData = new ByteArrayInputStream("{\"name\": \"store\", \"awsId\":\"aws-id\", \"role\":\"role\"}".getBytes(StandardCharsets.UTF_8)); + var response = mockHandler.handle(createTestRequest(url, POST, requestData)); + assertEquals(200, response.getStatus()); + + + // MockSecretStoreValidator returns response on format tenantSecretStore.toString() - tenantSecretName + var expectedResponse = "TenantSecretStore{name='store', awsId='aws-id', role='role'} - some-secret-name"; + assertEquals(expectedResponse, getRenderedString(response)); + } + + @Test public void testTesterStatus() throws IOException { applicationRepository.deploy(testApp, prepareParams(applicationId)); String url = toUrlPath(applicationId, Zone.defaultZone(), true) + "/tester/status"; |