diff options
45 files changed, 938 insertions, 176 deletions
diff --git a/athenz-identity-provider-service/pom.xml b/athenz-identity-provider-service/pom.xml index 501904a1d62..a8de9b58269 100644 --- a/athenz-identity-provider-service/pom.xml +++ b/athenz-identity-provider-service/pom.xml @@ -94,6 +94,12 @@ <version>${project.version}</version> <scope>provided</scope> </dependency> + <dependency> + <groupId>com.yahoo.vespa</groupId> + <artifactId>container-dev</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> <!-- COMPILE --> <dependency> @@ -134,6 +140,18 @@ <version>${project.version}</version> <scope>test</scope> </dependency> + <dependency> + <groupId>com.yahoo.vespa</groupId> + <artifactId>application</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.yahoo.vespa</groupId> + <artifactId>testutil</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> </dependencies> <build> diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/Certificates.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/Certificates.java new file mode 100644 index 00000000000..6d121657a40 --- /dev/null +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/Certificates.java @@ -0,0 +1,57 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.ca; + +import com.yahoo.security.Pkcs10Csr; +import com.yahoo.security.SubjectAlternativeName; +import com.yahoo.security.X509CertificateBuilder; + +import java.security.PrivateKey; +import java.security.cert.X509Certificate; +import java.time.Clock; +import java.time.Duration; +import java.util.Objects; + +import static com.yahoo.security.SignatureAlgorithm.SHA256_WITH_ECDSA; +import static com.yahoo.security.SubjectAlternativeName.Type.DNS_NAME; + +/** + * Helper class for creating {@link X509Certificate}s. + * + * @author mpolden + */ +public class Certificates { + + private static final Duration CERTIFICATE_TTL = Duration.ofDays(30); + + private final Clock clock; + + public Certificates(Clock clock) { + this.clock = Objects.requireNonNull(clock, "clock must be non-null"); + } + + /** Create a new certificate from csr signed by the given CA private key */ + public X509Certificate create(Pkcs10Csr csr, X509Certificate caCertificate, PrivateKey caPrivateKey) { + var x500principal = caCertificate.getSubjectX500Principal(); + var now = clock.instant(); + var notBefore = now.minus(Duration.ofHours(1)); + var notAfter = now.plus(CERTIFICATE_TTL); + return X509CertificateBuilder.fromCsr(csr, + x500principal, + notBefore, + notAfter, + caPrivateKey, + SHA256_WITH_ECDSA, + X509CertificateBuilder.generateRandomSerialNumber()) + .build(); + } + + /** Returns the DNS name field from Subject Alternative Names in given csr */ + public static String extractDnsName(Pkcs10Csr csr) { + return csr.getSubjectAlternativeNames().stream() + .filter(san -> san.getType() == DNS_NAME) + .map(SubjectAlternativeName::getValue) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("DNS name not found in CSR")); + } + +} diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/instance/InstanceIdentity.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/instance/InstanceIdentity.java new file mode 100644 index 00000000000..b499debcc47 --- /dev/null +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/instance/InstanceIdentity.java @@ -0,0 +1,64 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.ca.instance; + +import java.security.cert.X509Certificate; +import java.util.Objects; +import java.util.Optional; + +/** + * A signed instance identity object that includes a client certificate. This is the result of a successful + * {@link InstanceRegistration}. + * + * @author mpolden + */ +public class InstanceIdentity { + + private final String provider; + private final String service; + private final String instanceId; + private final Optional<X509Certificate> x509Certificate; + + public InstanceIdentity(String provider, String service, String instanceId, Optional<X509Certificate> x509Certificate) { + this.provider = Objects.requireNonNull(provider, "provider must be non-null"); + this.service = Objects.requireNonNull(service, "service must be non-null"); + this.instanceId = Objects.requireNonNull(instanceId, "instanceId must be non-null"); + this.x509Certificate = Objects.requireNonNull(x509Certificate, "x509Certificate must be non-null"); + } + + /** Same as {@link InstanceRegistration#domain()} */ + public String provider() { + return provider; + } + + /** Same as {@link InstanceRegistration#service()} ()} */ + public String service() { + return service; + } + + /** A unique identifier of the instance to which the certificate is issued */ + public String instanceId() { + return instanceId; + } + + /** The issued certificate */ + public Optional<X509Certificate> x509Certificate() { + return x509Certificate; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + InstanceIdentity that = (InstanceIdentity) o; + return provider.equals(that.provider) && + service.equals(that.service) && + instanceId.equals(that.instanceId) && + x509Certificate.equals(that.x509Certificate); + } + + @Override + public int hashCode() { + return Objects.hash(provider, service, instanceId, x509Certificate); + } + +} diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/instance/InstanceRegistration.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/instance/InstanceRegistration.java new file mode 100644 index 00000000000..7a9ec74e075 --- /dev/null +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/instance/InstanceRegistration.java @@ -0,0 +1,81 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.ca.instance; + +import com.yahoo.security.Pkcs10Csr; + +import java.util.Objects; + +/** + * Information for registering a new instance in the system. This is similar to the InstanceRegisterInformation type in + * ZTS. + * + * @author mpolden + */ +public class InstanceRegistration { + + private final String provider; + private final String domain; + private final String service; + private final String attestationData; + private final Pkcs10Csr csr; + + public InstanceRegistration(String provider, String domain, String service, String attestationData, Pkcs10Csr csr) { + this.provider = Objects.requireNonNull(provider, "provider must be non-null"); + this.domain = Objects.requireNonNull(domain, "domain must be non-null"); + this.service = Objects.requireNonNull(service, "service must be non-null"); + this.attestationData = Objects.requireNonNull(attestationData, "attestationData must be non-null"); + this.csr = Objects.requireNonNull(csr, "csr must be non-null"); + } + + /** The provider which issued the attestation data contained in this */ + public String provider() { + return provider; + } + + /** Athenz domain of the instance */ + public String domain() { + return domain; + } + + /** Athenz service of the instance */ + public String service() { + return service; + } + + /** Host document describing this instance (received from config server) */ + public String attestationData() { + return attestationData; + } + + public Pkcs10Csr csr() { + return csr; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + InstanceRegistration that = (InstanceRegistration) o; + return provider.equals(that.provider) && + domain.equals(that.domain) && + service.equals(that.service) && + attestationData.equals(that.attestationData) && + csr.equals(that.csr); + } + + @Override + public int hashCode() { + return Objects.hash(provider, domain, service, attestationData, csr); + } + + @Override + public String toString() { + return "InstanceRegistration{" + + "provider='" + provider + '\'' + + ", domain='" + domain + '\'' + + ", service='" + service + '\'' + + ", attestationData='" + attestationData + '\'' + + ", csr=" + csr + + '}'; + } +} diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/restapi/CertificateAuthorityApiHandler.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/restapi/CertificateAuthorityApiHandler.java new file mode 100644 index 00000000000..ba4f0ce932c --- /dev/null +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/restapi/CertificateAuthorityApiHandler.java @@ -0,0 +1,109 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.ca.restapi; + +import com.google.inject.Inject; +import com.yahoo.config.provision.SystemName; +import com.yahoo.config.provision.Zone; +import com.yahoo.container.jdisc.HttpRequest; +import com.yahoo.container.jdisc.HttpResponse; +import com.yahoo.container.jdisc.LoggingRequestHandler; +import com.yahoo.container.jdisc.secretstore.SecretStore; +import com.yahoo.restapi.Path; +import com.yahoo.restapi.SlimeJsonResponse; +import com.yahoo.security.KeyUtils; +import com.yahoo.security.X509CertificateUtils; +import com.yahoo.slime.Slime; +import com.yahoo.vespa.config.SlimeUtils; +import com.yahoo.vespa.hosted.ca.Certificates; +import com.yahoo.vespa.hosted.ca.instance.InstanceIdentity; +import com.yahoo.vespa.hosted.provision.restapi.v2.ErrorResponse; +import com.yahoo.yolean.Exceptions; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; +import java.time.Clock; +import java.util.Optional; +import java.util.logging.Level; + +/** + * REST API for issuing and refreshing node certificates in a hosted Vespa system. + * + * The API implements the following subset of methods from the Athenz ZTS REST API: + * - Instance registration + * - Instance refresh + * + * @author mpolden + */ +public class CertificateAuthorityApiHandler extends LoggingRequestHandler { + + private final SecretStore secretStore; + private final Certificates certificates; + private final SystemName system; + + @Inject + public CertificateAuthorityApiHandler(Context ctx, SecretStore secretStore, Zone zone) { + this(ctx, secretStore, new Certificates(Clock.systemUTC()), zone.system()); + } + + CertificateAuthorityApiHandler(Context ctx, SecretStore secretStore, Certificates certificates, SystemName system) { + super(ctx); + this.secretStore = secretStore; + this.certificates = certificates; + this.system = system; + } + + @Override + public HttpResponse handle(HttpRequest request) { + try { + switch (request.getMethod()) { + case POST: return handlePost(request); + default: return ErrorResponse.methodNotAllowed("Method '" + request.getMethod() + "' is unsupported"); + } + } catch (IllegalArgumentException e) { + return ErrorResponse.badRequest(Exceptions.toMessageString(e)); + } catch (RuntimeException e) { + log.log(Level.WARNING, "Unexpected error handling '" + request.getUri() + "'", e); + return ErrorResponse.internalServerError(Exceptions.toMessageString(e)); + } + } + + private HttpResponse handlePost(HttpRequest request) { + Path path = new Path(request.getUri()); + if (path.matches("/ca/v1/instance/")) return registerInstance(request); + // TODO: Implement refresh + return ErrorResponse.notFoundError("Nothing at " + path); + } + + private HttpResponse registerInstance(HttpRequest request) { + var body = slimeFromRequest(request); + var instanceRegistration = InstanceSerializer.registrationFromSlime(body); + var certificate = certificates.create(instanceRegistration.csr(), caCertificate(), caPrivateKey()); + var instanceId = Certificates.extractDnsName(instanceRegistration.csr()); + var identity = new InstanceIdentity(instanceRegistration.provider(), instanceRegistration.service(), instanceId, + Optional.of(certificate)); + return new SlimeJsonResponse(InstanceSerializer.identityToSlime(identity)); + } + + /** Returns CA certificate from secret store */ + private X509Certificate caCertificate() { + var keyName = String.format("vespa.external.%s.configserver.ca.cert.cert", system.value().toLowerCase()); + return X509CertificateUtils.fromPem(secretStore.getSecret(keyName)); + } + + /** Returns CA private key from secret store */ + private PrivateKey caPrivateKey() { + var keyName = String.format("vespa.external.%s.configserver.ca.key.key", system.value().toLowerCase()); + return KeyUtils.fromPemEncodedPrivateKey(secretStore.getSecret(keyName)); + } + + private static Slime slimeFromRequest(HttpRequest request) { + try { + return SlimeUtils.jsonToSlime(request.getData().readAllBytes()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + +} diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/restapi/InstanceSerializer.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/restapi/InstanceSerializer.java new file mode 100644 index 00000000000..46a09e9c6f2 --- /dev/null +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/restapi/InstanceSerializer.java @@ -0,0 +1,54 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.ca.restapi; + +import com.yahoo.security.Pkcs10CsrUtils; +import com.yahoo.security.X509CertificateUtils; +import com.yahoo.slime.Cursor; +import com.yahoo.slime.Slime; +import com.yahoo.vespa.hosted.ca.instance.InstanceIdentity; +import com.yahoo.vespa.hosted.ca.instance.InstanceRegistration; + +/** + * @author mpolden + */ +public class InstanceSerializer { + + private static final String PROVIDER_FIELD = "provider"; + private static final String DOMAIN_FIELD = "domain"; + private static final String SERVICE_FIELD = "service"; + private static final String ATTESTATION_DATA_FIELD = "attestationData"; + private static final String CSR_FIELD = "csr"; + private static final String NAME_FIELD = "service"; + private static final String INSTANCE_ID_FIELD = "instanceId"; + private static final String X509_CERTIFICATE_FIELD = "x509Certificate"; + + private InstanceSerializer() {} + + public static InstanceRegistration registrationFromSlime(Slime slime) { + Cursor root = slime.get(); + return new InstanceRegistration(requireField(PROVIDER_FIELD, root).asString(), + requireField(DOMAIN_FIELD, root).asString(), + requireField(SERVICE_FIELD, root).asString(), + requireField(ATTESTATION_DATA_FIELD, root).asString(), + Pkcs10CsrUtils.fromPem(requireField(CSR_FIELD, root).asString())); + } + + public static Slime identityToSlime(InstanceIdentity identity) { + Slime slime = new Slime(); + Cursor root = slime.setObject(); + root.setString(PROVIDER_FIELD, identity.provider()); + root.setString(NAME_FIELD, identity.service()); + root.setString(INSTANCE_ID_FIELD, identity.instanceId()); + identity.x509Certificate() + .map(X509CertificateUtils::toPem) + .ifPresent(pem -> root.setString(X509_CERTIFICATE_FIELD, pem)); + return slime; + } + + private static Cursor requireField(String fieldName, Cursor root) { + var field = root.field(fieldName); + if (!field.valid()) throw new IllegalArgumentException("Missing required field '" + fieldName + "'"); + return field; + } + +} diff --git a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/CertificateTester.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/CertificateTester.java new file mode 100644 index 00000000000..4946de93f6d --- /dev/null +++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/CertificateTester.java @@ -0,0 +1,60 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.ca; + +import com.yahoo.security.KeyAlgorithm; +import com.yahoo.security.KeyUtils; +import com.yahoo.security.Pkcs10Csr; +import com.yahoo.security.Pkcs10CsrBuilder; +import com.yahoo.security.SignatureAlgorithm; +import com.yahoo.security.SubjectAlternativeName; +import com.yahoo.security.X509CertificateBuilder; + +import javax.security.auth.x500.X500Principal; +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.cert.X509Certificate; +import java.time.Duration; +import java.time.Instant; + +import static com.yahoo.security.SignatureAlgorithm.SHA256_WITH_ECDSA; + +/** + * Helper class for creating certificates, CSRs etc. for testing purposes. + * + * @author mpolden + */ +public class CertificateTester { + + private CertificateTester() {} + + public static X509Certificate createCertificate() { + var keyPair = KeyUtils.generateKeypair(KeyAlgorithm.EC, 256); + return createCertificate("subject", keyPair); + } + + public static X509Certificate createCertificate(String cn, KeyPair keyPair) { + var subject = new X500Principal("CN=" + cn); + return X509CertificateBuilder.fromKeypair(keyPair, + subject, + Instant.EPOCH, + Instant.EPOCH.plus(Duration.ofMinutes(1)), + SHA256_WITH_ECDSA, + BigInteger.ONE) + .build(); + } + + public static Pkcs10Csr createCsr() { + return createCsr(null); + } + + public static Pkcs10Csr createCsr(String dnsName) { + X500Principal subject = new X500Principal("CN=subject"); + KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.EC, 256); + var builder = Pkcs10CsrBuilder.fromKeypair(subject, keyPair, SignatureAlgorithm.SHA512_WITH_ECDSA); + if (dnsName != null) { + builder = builder.addSubjectAlternativeName(SubjectAlternativeName.Type.DNS_NAME, dnsName); + } + return builder.build(); + } + +} diff --git a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/CertificatesTest.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/CertificatesTest.java new file mode 100644 index 00000000000..4e306d9a70e --- /dev/null +++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/CertificatesTest.java @@ -0,0 +1,33 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.ca; + +import com.yahoo.security.KeyAlgorithm; +import com.yahoo.security.KeyUtils; +import com.yahoo.test.ManualClock; +import org.junit.Test; + +import java.time.Duration; + +import static java.time.temporal.ChronoUnit.SECONDS; +import static org.junit.Assert.assertEquals; + +/** + * @author mpolden + */ +public class CertificatesTest { + + @Test + public void expiry() { + var clock = new ManualClock(); + var certificates = new Certificates(clock); + var csr = CertificateTester.createCsr(); + var keyPair = KeyUtils.generateKeypair(KeyAlgorithm.EC, 256); + var caCertificate = CertificateTester.createCertificate("CA", keyPair); + var certificate = certificates.create(csr, caCertificate, keyPair.getPrivate()); + var now = clock.instant(); + + assertEquals(now.minus(Duration.ofHours(1)).truncatedTo(SECONDS), certificate.getNotBefore().toInstant()); + assertEquals(now.plus(Duration.ofDays(30)).truncatedTo(SECONDS), certificate.getNotAfter().toInstant()); + } + +} diff --git a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/restapi/CertificateAuthorityApiTest.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/restapi/CertificateAuthorityApiTest.java new file mode 100644 index 00000000000..4393c3a25b9 --- /dev/null +++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/restapi/CertificateAuthorityApiTest.java @@ -0,0 +1,101 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.ca.restapi; + +import com.yahoo.application.container.handler.Request; +import com.yahoo.security.KeyAlgorithm; +import com.yahoo.security.KeyUtils; +import com.yahoo.security.Pkcs10Csr; +import com.yahoo.security.Pkcs10CsrUtils; +import com.yahoo.security.X509CertificateUtils; +import com.yahoo.vespa.athenz.api.AthenzService; +import com.yahoo.vespa.athenz.client.zts.DefaultZtsClient; +import com.yahoo.vespa.config.SlimeUtils; +import com.yahoo.vespa.hosted.ca.CertificateTester; +import org.junit.Before; +import org.junit.Test; + +import javax.net.ssl.SSLContext; +import java.net.URI; +import java.nio.charset.StandardCharsets; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author mpolden + */ +public class CertificateAuthorityApiTest extends ContainerTester { + + @Before + public void before() { + setCaCertificateAndKey(); + } + + @Test + public void register_instance() throws Exception { + // POST instance registration + var csr = CertificateTester.createCsr("node1.example.com"); + assertRegistration(new Request("http://localhost:12345/ca/v1/instance/", + instanceRegistrationJson(csr), + Request.Method.POST)); + + // POST instance registration with ZTS client + var ztsClient = new DefaultZtsClient(URI.create("http://localhost:12345/ca/v1/"), SSLContext.getDefault()); + var instanceIdentity = ztsClient.registerInstance(new AthenzService("vespa.external", "provider_prod_us-north-1"), + new AthenzService("vespa.external", "tenant"), + "identity document generated by config server", + csr); + assertEquals("CN=Vespa CA", instanceIdentity.certificate().getIssuerX500Principal().getName()); + } + + @Test + public void invalid_register_instance() { + // POST instance registration with missing fields + assertResponse(400, "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Missing required field 'provider'\"}", + new Request("http://localhost:12345/ca/v1/instance/", + new byte[0], + Request.Method.POST)); + + // POST instance registration without DNS name in CSR + var csr = CertificateTester.createCsr(); + var request = new Request("http://localhost:12345/ca/v1/instance/", + instanceRegistrationJson(csr), + Request.Method.POST); + assertResponse(400, "{\"error-code\":\"BAD_REQUEST\",\"message\":\"DNS name not found in CSR\"}", request); + } + + private void setCaCertificateAndKey() { + var keyPair = KeyUtils.generateKeypair(KeyAlgorithm.EC, 256); + var caCertificatePem = X509CertificateUtils.toPem(CertificateTester.createCertificate("Vespa CA", keyPair)); + var privateKeyPem = KeyUtils.toPem(keyPair.getPrivate()); + secretStore().setSecret("vespa.external.main.configserver.ca.cert.cert", caCertificatePem) + .setSecret("vespa.external.main.configserver.ca.key.key", privateKeyPem); + } + + private void assertRegistration(Request request) { + assertResponse(200, (body) -> { + var slime = SlimeUtils.jsonToSlime(body); + var root = slime.get(); + assertEquals("provider_prod_us-north-1", root.field("provider").asString()); + assertEquals("tenant", root.field("service").asString()); + assertEquals("node1.example.com", root.field("instanceId").asString()); + var pemEncodedCertificate = root.field("x509Certificate").asString(); + assertTrue("Response contains PEM certificate", + pemEncodedCertificate.startsWith("-----BEGIN CERTIFICATE-----") && + pemEncodedCertificate.endsWith("-----END CERTIFICATE-----\n")); + }, request); + } + + private static byte[] instanceRegistrationJson(Pkcs10Csr csr) { + var csrPem = Pkcs10CsrUtils.toPem(csr); + var json = "{\n" + + " \"provider\": \"provider_prod_us-north-1\",\n" + + " \"domain\": \"vespa.external\",\n" + + " \"service\": \"tenant\",\n" + + " \"attestationData\": \"identity document generated by config server\",\n" + + " \"csr\": \"" + csrPem + "\"\n" + + "}"; + return json.getBytes(StandardCharsets.UTF_8); + } + +} diff --git a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/restapi/ContainerTester.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/restapi/ContainerTester.java new file mode 100644 index 00000000000..2ca45cf7e56 --- /dev/null +++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/restapi/ContainerTester.java @@ -0,0 +1,72 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.ca.restapi; + +import com.yahoo.application.Networking; +import com.yahoo.application.container.JDisc; +import com.yahoo.application.container.handler.Request; +import com.yahoo.vespa.hosted.ca.restapi.mock.SecretStoreMock; +import org.junit.After; +import org.junit.Before; + +import java.io.UncheckedIOException; +import java.nio.charset.CharacterCodingException; +import java.util.function.Consumer; + +import static org.junit.Assert.assertEquals; + +/** + * The superclass of REST API tests which require a functional container instance. + * + * @author mpolden + */ +public class ContainerTester { + + private JDisc container; + + @Before + public void startContainer() { + container = JDisc.fromServicesXml(servicesXml(), Networking.enable); + } + + @After + public void stopContainer() { + container.close(); + } + + public SecretStoreMock secretStore() { + return (SecretStoreMock) container.components().getComponent(SecretStoreMock.class.getName()); + } + + public void assertResponse(int expectedStatus, String expectedBody, Request request) { + assertResponse(expectedStatus, (body) -> assertEquals(expectedBody, body), request); + } + + public void assertResponse(int expectedStatus, Consumer<String> bodyAsserter, Request request) { + var response = container.handleRequest(request); + try { + bodyAsserter.accept(response.getBodyAsString()); + } catch (CharacterCodingException e) { + throw new UncheckedIOException(e); + } + assertEquals(expectedStatus, response.getStatus()); + assertEquals("application/json; charset=UTF-8", response.getHeaders().getFirst("Content-Type")); + } + + private static String servicesXml() { + return "<container version='1.0'>\n" + + " <config name=\"container.handler.threadpool\">\n" + + " <maxthreads>10</maxthreads>\n" + + " </config> \n" + + " <component id='com.yahoo.vespa.hosted.provision.testutils.MockNodeFlavors'/>\n" + + " <component id='com.yahoo.config.provision.Zone'/>\n" + + " <component id='com.yahoo.vespa.hosted.ca.restapi.mock.SecretStoreMock'/>\n" + + " <handler id='com.yahoo.vespa.hosted.ca.restapi.CertificateAuthorityApiHandler'>\n" + + " <binding>http://*/ca/v1/*</binding>\n" + + " </handler>\n" + + " <http>\n" + + " <server id='default' port='12345'/>\n" + + " </http>\n" + + "</container>"; + } + +} diff --git a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/restapi/InstanceSerializerTest.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/restapi/InstanceSerializerTest.java new file mode 100644 index 00000000000..51010422b6d --- /dev/null +++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/restapi/InstanceSerializerTest.java @@ -0,0 +1,66 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.ca.restapi; + +import com.yahoo.security.Pkcs10CsrUtils; +import com.yahoo.security.X509CertificateUtils; +import com.yahoo.slime.Slime; +import com.yahoo.vespa.config.SlimeUtils; +import com.yahoo.vespa.hosted.ca.CertificateTester; +import com.yahoo.vespa.hosted.ca.instance.InstanceIdentity; +import com.yahoo.vespa.hosted.ca.instance.InstanceRegistration; +import org.junit.Test; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; +import java.util.Optional; + +import static org.junit.Assert.assertEquals; + +/** + * @author mpolden + */ +public class InstanceSerializerTest { + + @Test + public void deserialize_instance_registration() { + var csr = CertificateTester.createCsr(); + var csrPem = Pkcs10CsrUtils.toPem(csr); + var json = "{\n" + + " \"provider\": \"provider_prod_us-north-1\",\n" + + " \"domain\": \"vespa.external\",\n" + + " \"service\": \"tenant\",\n" + + " \"attestationData\": \"identity document from configserevr\",\n" + + " \"csr\": \"" + csrPem + "\"\n" + + "}"; + var instanceRegistration = new InstanceRegistration("provider_prod_us-north-1", "vespa.external", + "tenant", "identity document from configserevr", + csr); + var deserialized = InstanceSerializer.registrationFromSlime(SlimeUtils.jsonToSlime(json)); + assertEquals(instanceRegistration, deserialized); + } + + @Test + public void serialize_instance_identity() { + var certificate = CertificateTester.createCertificate(); + var pem = X509CertificateUtils.toPem(certificate); + var identity = new InstanceIdentity("provider_prod_us-north-1", "tenant", "node1.example.com", + Optional.of(certificate)); + var json = "{" + + "\"provider\":\"provider_prod_us-north-1\"," + + "\"service\":\"tenant\"," + + "\"instanceId\":\"node1.example.com\"," + + "\"x509Certificate\":\"" + pem.replace("\n", "\\n") + "\"" + + "}"; + assertEquals(json, asJsonString(InstanceSerializer.identityToSlime(identity))); + } + + private static String asJsonString(Slime slime) { + try { + return new String(SlimeUtils.toJsonBytes(slime), StandardCharsets.UTF_8); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + +} diff --git a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/restapi/mock/SecretStoreMock.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/restapi/mock/SecretStoreMock.java new file mode 100644 index 00000000000..a53bf9d9fd3 --- /dev/null +++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/restapi/mock/SecretStoreMock.java @@ -0,0 +1,34 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.ca.restapi.mock; + +import com.yahoo.component.AbstractComponent; +import com.yahoo.container.jdisc.secretstore.SecretStore; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author mpolden + */ +public class SecretStoreMock extends AbstractComponent implements SecretStore { + + private final Map<String, String> secrets = new HashMap<>(); + + public SecretStoreMock setSecret(String key, String value) { + secrets.put(key, value); + return this; + } + + @Override + public String getSecret(String key) { + if (!secrets.containsKey(key)) throw new RuntimeException("No such key '" + key + "'"); + return secrets.get(key); + } + + @Override + public String getSecret(String key, int version) { + if (!secrets.containsKey(key)) throw new RuntimeException("No such key '" + key + "'"); + return secrets.get(key); + } + +} diff --git a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/FlagsHandler.java b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/FlagsHandler.java index 40bb69111e0..8810a13f909 100644 --- a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/FlagsHandler.java +++ b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/FlagsHandler.java @@ -6,6 +6,7 @@ import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.container.jdisc.LoggingRequestHandler; import com.yahoo.log.LogLevel; +import com.yahoo.restapi.ErrorResponse; import com.yahoo.restapi.Path; import com.yahoo.vespa.configserver.flags.FlagsDb; import com.yahoo.vespa.flags.FlagDefinition; diff --git a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/SlimeJsonResponse.java b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/SlimeJsonResponse.java deleted file mode 100644 index e5568514894..00000000000 --- a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/SlimeJsonResponse.java +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.configserver.flags.http; - -import com.yahoo.container.jdisc.HttpResponse; -import com.yahoo.slime.JsonFormat; -import com.yahoo.slime.Slime; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * A generic Json response using Slime for JSON encoding - * - * @author bratseth - */ -public class SlimeJsonResponse extends HttpResponse { - - private final Slime slime; - - public SlimeJsonResponse(Slime slime) { - super(200); - this.slime = slime; - } - - public SlimeJsonResponse(int statusCode, Slime slime) { - super(statusCode); - this.slime = slime; - } - - @Override - public void render(OutputStream stream) throws IOException { - new JsonFormat(true).encode(stream, slime); - } - - @Override - public String getContentType() { return "application/json"; } - -} diff --git a/container-core/abi-spec.json b/container-core/abi-spec.json index 81af58b6681..9292db89eb5 100644 --- a/container-core/abi-spec.json +++ b/container-core/abi-spec.json @@ -854,6 +854,57 @@ ], "fields": [] }, + "com.yahoo.restapi.ErrorResponse$errorCodes": { + "superClass": "java.lang.Enum", + "interfaces": [], + "attributes": [ + "public", + "final", + "enum" + ], + "methods": [ + "public static com.yahoo.restapi.ErrorResponse$errorCodes[] values()", + "public static com.yahoo.restapi.ErrorResponse$errorCodes valueOf(java.lang.String)" + ], + "fields": [ + "public static final enum com.yahoo.restapi.ErrorResponse$errorCodes NOT_FOUND", + "public static final enum com.yahoo.restapi.ErrorResponse$errorCodes BAD_REQUEST", + "public static final enum com.yahoo.restapi.ErrorResponse$errorCodes FORBIDDEN", + "public static final enum com.yahoo.restapi.ErrorResponse$errorCodes METHOD_NOT_ALLOWED", + "public static final enum com.yahoo.restapi.ErrorResponse$errorCodes INTERNAL_SERVER_ERROR", + "public static final enum com.yahoo.restapi.ErrorResponse$errorCodes UNAUTHORIZED" + ] + }, + "com.yahoo.restapi.ErrorResponse": { + "superClass": "com.yahoo.restapi.SlimeJsonResponse", + "interfaces": [], + "attributes": [ + "public" + ], + "methods": [ + "public void <init>(int, java.lang.String, java.lang.String)", + "public static com.yahoo.restapi.ErrorResponse notFoundError(java.lang.String)", + "public static com.yahoo.restapi.ErrorResponse internalServerError(java.lang.String)", + "public static com.yahoo.restapi.ErrorResponse badRequest(java.lang.String)", + "public static com.yahoo.restapi.ErrorResponse forbidden(java.lang.String)", + "public static com.yahoo.restapi.ErrorResponse unauthorized(java.lang.String)", + "public static com.yahoo.restapi.ErrorResponse methodNotAllowed(java.lang.String)" + ], + "fields": [] + }, + "com.yahoo.restapi.MessageResponse": { + "superClass": "com.yahoo.container.jdisc.HttpResponse", + "interfaces": [], + "attributes": [ + "public" + ], + "methods": [ + "public void <init>(java.lang.String)", + "public void render(java.io.OutputStream)", + "public java.lang.String getContentType()" + ], + "fields": [] + }, "com.yahoo.restapi.Path": { "superClass": "java.lang.Object", "interfaces": [], @@ -872,5 +923,62 @@ "public java.lang.String toString()" ], "fields": [] + }, + "com.yahoo.restapi.ResourceResponse": { + "superClass": "com.yahoo.container.jdisc.HttpResponse", + "interfaces": [], + "attributes": [ + "public" + ], + "methods": [ + "public varargs void <init>(com.yahoo.container.jdisc.HttpRequest, java.lang.String[])", + "public void render(java.io.OutputStream)", + "public java.lang.String getContentType()" + ], + "fields": [] + }, + "com.yahoo.restapi.SlimeJsonResponse": { + "superClass": "com.yahoo.container.jdisc.HttpResponse", + "interfaces": [], + "attributes": [ + "public" + ], + "methods": [ + "public void <init>(com.yahoo.slime.Slime)", + "public void <init>(int, com.yahoo.slime.Slime)", + "public void render(java.io.OutputStream)", + "public java.lang.String getContentType()" + ], + "fields": [] + }, + "com.yahoo.restapi.StringResponse": { + "superClass": "com.yahoo.container.jdisc.HttpResponse", + "interfaces": [], + "attributes": [ + "public" + ], + "methods": [ + "public void <init>(java.lang.String)", + "public void render(java.io.OutputStream)" + ], + "fields": [] + }, + "com.yahoo.restapi.Uri": { + "superClass": "java.lang.Object", + "interfaces": [], + "attributes": [ + "public" + ], + "methods": [ + "public void <init>(java.net.URI)", + "public void <init>(java.lang.String)", + "public com.yahoo.restapi.Uri append(java.lang.String)", + "public com.yahoo.restapi.Uri withoutParameters()", + "public com.yahoo.restapi.Uri withPath(java.lang.String)", + "public com.yahoo.restapi.Uri withTrailingSlash()", + "public java.net.URI toURI()", + "public java.lang.String toString()" + ], + "fields": [] } -} +}
\ No newline at end of file diff --git a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/ErrorResponse.java b/container-core/src/main/java/com/yahoo/restapi/ErrorResponse.java index b9e5c75fe22..d3e81a10720 100644 --- a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/ErrorResponse.java +++ b/container-core/src/main/java/com/yahoo/restapi/ErrorResponse.java @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.configserver.flags.http; +package com.yahoo.restapi; import com.yahoo.slime.Cursor; import com.yahoo.slime.Slime; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/MessageResponse.java b/container-core/src/main/java/com/yahoo/restapi/MessageResponse.java index 8b2f0e9f09d..8669d4f9b0c 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/MessageResponse.java +++ b/container-core/src/main/java/com/yahoo/restapi/MessageResponse.java @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.hosted.controller.restapi; +package com.yahoo.restapi; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.slime.JsonFormat; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/ResourceResponse.java b/container-core/src/main/java/com/yahoo/restapi/ResourceResponse.java index 550b47d8280..4852bfafa60 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/ResourceResponse.java +++ b/container-core/src/main/java/com/yahoo/restapi/ResourceResponse.java @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.hosted.controller.restapi; +package com.yahoo.restapi; import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.container.jdisc.HttpResponse; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/SlimeJsonResponse.java b/container-core/src/main/java/com/yahoo/restapi/SlimeJsonResponse.java index 81b07b81efb..2473da3578d 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/SlimeJsonResponse.java +++ b/container-core/src/main/java/com/yahoo/restapi/SlimeJsonResponse.java @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.hosted.controller.restapi; +package com.yahoo.restapi; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.slime.JsonFormat; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/StringResponse.java b/container-core/src/main/java/com/yahoo/restapi/StringResponse.java index 1fc30b7d880..55ea22880de 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/StringResponse.java +++ b/container-core/src/main/java/com/yahoo/restapi/StringResponse.java @@ -1,10 +1,11 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.hosted.controller.restapi; +package com.yahoo.restapi; import com.yahoo.container.jdisc.HttpResponse; import java.io.IOException; import java.io.OutputStream; +import java.nio.charset.StandardCharsets; /** * @author bratseth @@ -20,7 +21,7 @@ public class StringResponse extends HttpResponse { @Override public void render(OutputStream stream) throws IOException { - stream.write(message.getBytes("utf-8")); + stream.write(message.getBytes(StandardCharsets.UTF_8)); } } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/Uri.java b/container-core/src/main/java/com/yahoo/restapi/Uri.java index 479e7434f9b..c1b0d19eb3e 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/Uri.java +++ b/container-core/src/main/java/com/yahoo/restapi/Uri.java @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.hosted.controller.restapi; +package com.yahoo.restapi; import java.net.URI; import java.net.URISyntaxException; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/ErrorResponse.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/ErrorResponse.java deleted file mode 100644 index deee3357771..00000000000 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/ErrorResponse.java +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.hosted.controller.restapi; - -import com.yahoo.slime.Cursor; -import com.yahoo.slime.Slime; -import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServerException; -import com.yahoo.yolean.Exceptions; - -import static com.yahoo.jdisc.Response.Status.BAD_REQUEST; -import static com.yahoo.jdisc.Response.Status.CONFLICT; -import static com.yahoo.jdisc.Response.Status.FORBIDDEN; -import static com.yahoo.jdisc.Response.Status.INTERNAL_SERVER_ERROR; -import static com.yahoo.jdisc.Response.Status.METHOD_NOT_ALLOWED; -import static com.yahoo.jdisc.Response.Status.NOT_FOUND; -import static com.yahoo.jdisc.Response.Status.UNAUTHORIZED; - -/** - * A HTTP JSON response containing an error code and a message - * - * @author bratseth - */ -public class ErrorResponse extends SlimeJsonResponse { - - public enum errorCodes { - NOT_FOUND, - BAD_REQUEST, - FORBIDDEN, - METHOD_NOT_ALLOWED, - INTERNAL_SERVER_ERROR, - UNAUTHORIZED - } - - public ErrorResponse(int statusCode, String errorType, String message) { - super(statusCode, asSlimeMessage(errorType, message)); - } - - private static Slime asSlimeMessage(String errorType, String message) { - Slime slime = new Slime(); - Cursor root = slime.setObject(); - root.setString("error-code", errorType); - root.setString("message", message); - return slime; - } - - public static ErrorResponse notFoundError(String message) { - return new ErrorResponse(NOT_FOUND, errorCodes.NOT_FOUND.name(), message); - } - - public static ErrorResponse internalServerError(String message) { - return new ErrorResponse(INTERNAL_SERVER_ERROR, errorCodes.INTERNAL_SERVER_ERROR.name(), message); - } - - public static ErrorResponse badRequest(String message) { - return new ErrorResponse(BAD_REQUEST, errorCodes.BAD_REQUEST.name(), message); - } - - public static ErrorResponse forbidden(String message) { - return new ErrorResponse(FORBIDDEN, errorCodes.FORBIDDEN.name(), message); - } - - public static ErrorResponse unauthorized(String message) { - return new ErrorResponse(UNAUTHORIZED, errorCodes.UNAUTHORIZED.name(), message); - } - - public static ErrorResponse methodNotAllowed(String message) { - return new ErrorResponse(METHOD_NOT_ALLOWED, errorCodes.METHOD_NOT_ALLOWED.name(), message); - } - - public static ErrorResponse from(ConfigServerException e) { - switch (e.getErrorCode()) { - case NOT_FOUND: - return new ErrorResponse(NOT_FOUND, e.getErrorCode().name(), Exceptions.toMessageString(e)); - case ACTIVATION_CONFLICT: - return new ErrorResponse(CONFLICT, e.getErrorCode().name(), Exceptions.toMessageString(e)); - case INTERNAL_SERVER_ERROR: - return new ErrorResponse(INTERNAL_SERVER_ERROR, e.getErrorCode().name(), Exceptions.toMessageString(e)); - default: - return new ErrorResponse(BAD_REQUEST, e.getErrorCode().name(), Exceptions.toMessageString(e)); - } - } - -} diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java index c7b8e148e31..123da447757 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java @@ -66,10 +66,10 @@ import com.yahoo.vespa.hosted.controller.application.SystemApplication; import com.yahoo.vespa.hosted.controller.deployment.DeploymentTrigger; import com.yahoo.vespa.hosted.controller.deployment.DeploymentTrigger.ChangesToCancel; import com.yahoo.vespa.hosted.controller.deployment.TestConfigSerializer; -import com.yahoo.vespa.hosted.controller.restapi.ErrorResponse; -import com.yahoo.vespa.hosted.controller.restapi.MessageResponse; -import com.yahoo.vespa.hosted.controller.restapi.ResourceResponse; -import com.yahoo.vespa.hosted.controller.restapi.SlimeJsonResponse; +import com.yahoo.restapi.ErrorResponse; +import com.yahoo.restapi.MessageResponse; +import com.yahoo.restapi.ResourceResponse; +import com.yahoo.restapi.SlimeJsonResponse; import com.yahoo.vespa.hosted.controller.rotation.RotationId; import com.yahoo.vespa.hosted.controller.rotation.RotationState; import com.yahoo.vespa.hosted.controller.rotation.RotationStatus; @@ -108,6 +108,10 @@ import java.util.StringJoiner; import java.util.logging.Level; import java.util.stream.Collectors; +import static com.yahoo.jdisc.Response.Status.BAD_REQUEST; +import static com.yahoo.jdisc.Response.Status.CONFLICT; +import static com.yahoo.jdisc.Response.Status.INTERNAL_SERVER_ERROR; +import static com.yahoo.jdisc.Response.Status.NOT_FOUND; import static java.util.stream.Collectors.joining; /** @@ -166,7 +170,16 @@ public class ApplicationApiHandler extends LoggingRequestHandler { return ErrorResponse.badRequest(Exceptions.toMessageString(e)); } catch (ConfigServerException e) { - return ErrorResponse.from(e); + switch (e.getErrorCode()) { + case NOT_FOUND: + return new ErrorResponse(NOT_FOUND, e.getErrorCode().name(), Exceptions.toMessageString(e)); + case ACTIVATION_CONFLICT: + return new ErrorResponse(CONFLICT, e.getErrorCode().name(), Exceptions.toMessageString(e)); + case INTERNAL_SERVER_ERROR: + return new ErrorResponse(INTERNAL_SERVER_ERROR, e.getErrorCode().name(), Exceptions.toMessageString(e)); + default: + return new ErrorResponse(BAD_REQUEST, e.getErrorCode().name(), Exceptions.toMessageString(e)); + } } catch (RuntimeException e) { log.log(Level.WARNING, "Unexpected error handling '" + request.getUri() + "'", e); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java index 5f7a3e1dcc8..697e95e75b3 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java @@ -29,8 +29,8 @@ import com.yahoo.vespa.hosted.controller.deployment.RunLog; import com.yahoo.vespa.hosted.controller.deployment.RunStatus; import com.yahoo.vespa.hosted.controller.deployment.Step; import com.yahoo.vespa.hosted.controller.deployment.Versions; -import com.yahoo.vespa.hosted.controller.restapi.MessageResponse; -import com.yahoo.vespa.hosted.controller.restapi.SlimeJsonResponse; +import com.yahoo.restapi.MessageResponse; +import com.yahoo.restapi.SlimeJsonResponse; import com.yahoo.vespa.hosted.controller.versions.VespaVersion; import java.net.URI; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ServiceApiResponse.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ServiceApiResponse.java index 976919f34be..3166a380f47 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ServiceApiResponse.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ServiceApiResponse.java @@ -7,7 +7,7 @@ import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.slime.Cursor; import com.yahoo.slime.JsonFormat; import com.yahoo.slime.Slime; -import com.yahoo.vespa.hosted.controller.restapi.Uri; +import com.yahoo.restapi.Uri; import com.yahoo.vespa.serviceview.bindings.ApplicationView; import com.yahoo.vespa.serviceview.bindings.ClusterView; import com.yahoo.vespa.serviceview.bindings.ServiceView; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/athenz/AthenzApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/athenz/AthenzApiHandler.java index 61e5dc359d2..d36a7487e59 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/athenz/AthenzApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/athenz/AthenzApiHandler.java @@ -14,9 +14,9 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.Property; import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId; import com.yahoo.vespa.hosted.controller.api.integration.entity.EntityService; import com.yahoo.vespa.hosted.controller.athenz.impl.AthenzFacade; -import com.yahoo.vespa.hosted.controller.restapi.ErrorResponse; -import com.yahoo.vespa.hosted.controller.restapi.ResourceResponse; -import com.yahoo.vespa.hosted.controller.restapi.SlimeJsonResponse; +import com.yahoo.restapi.ErrorResponse; +import com.yahoo.restapi.ResourceResponse; +import com.yahoo.restapi.SlimeJsonResponse; import com.yahoo.yolean.Exceptions; import java.util.Map; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/AuditLogResponse.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/AuditLogResponse.java index 01959104491..f2c1d2917dc 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/AuditLogResponse.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/AuditLogResponse.java @@ -4,7 +4,7 @@ package com.yahoo.vespa.hosted.controller.restapi.controller; import com.yahoo.slime.Cursor; import com.yahoo.slime.Slime; import com.yahoo.vespa.hosted.controller.auditlog.AuditLog; -import com.yahoo.vespa.hosted.controller.restapi.SlimeJsonResponse; +import com.yahoo.restapi.SlimeJsonResponse; /** * @author mpolden diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiHandler.java index dde79e78850..2cadd864df1 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/ControllerApiHandler.java @@ -13,9 +13,9 @@ import com.yahoo.vespa.hosted.controller.Controller; import com.yahoo.vespa.hosted.controller.auditlog.AuditLoggingRequestHandler; import com.yahoo.vespa.hosted.controller.maintenance.ControllerMaintenance; import com.yahoo.vespa.hosted.controller.maintenance.Upgrader; -import com.yahoo.vespa.hosted.controller.restapi.ErrorResponse; -import com.yahoo.vespa.hosted.controller.restapi.MessageResponse; -import com.yahoo.vespa.hosted.controller.restapi.ResourceResponse; +import com.yahoo.restapi.ErrorResponse; +import com.yahoo.restapi.MessageResponse; +import com.yahoo.restapi.ResourceResponse; import com.yahoo.vespa.hosted.controller.versions.VespaVersion.Confidence; import com.yahoo.yolean.Exceptions; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/JobsResponse.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/JobsResponse.java index 6e872038a24..82e76ddeda4 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/JobsResponse.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/JobsResponse.java @@ -4,7 +4,7 @@ package com.yahoo.vespa.hosted.controller.restapi.controller; import com.yahoo.slime.Cursor; import com.yahoo.slime.Slime; import com.yahoo.vespa.hosted.controller.maintenance.JobControl; -import com.yahoo.vespa.hosted.controller.restapi.SlimeJsonResponse; +import com.yahoo.restapi.SlimeJsonResponse; /** * A response containing maintenance job status diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/UpgraderResponse.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/UpgraderResponse.java index fd8eb85a0ec..8968b5ecbe0 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/UpgraderResponse.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/controller/UpgraderResponse.java @@ -4,7 +4,7 @@ package com.yahoo.vespa.hosted.controller.restapi.controller; import com.yahoo.slime.Cursor; import com.yahoo.slime.Slime; import com.yahoo.vespa.hosted.controller.maintenance.Upgrader; -import com.yahoo.vespa.hosted.controller.restapi.SlimeJsonResponse; +import com.yahoo.restapi.SlimeJsonResponse; /** * @author mpolden diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/cost/CostApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/cost/CostApiHandler.java index 6ed9db7455c..8b300c10d1d 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/cost/CostApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/cost/CostApiHandler.java @@ -8,8 +8,8 @@ import com.yahoo.restapi.Path; import com.yahoo.vespa.hosted.controller.Controller; import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeRepository; import com.yahoo.vespa.hosted.controller.api.integration.resource.CostReportConsumer; -import com.yahoo.vespa.hosted.controller.restapi.ErrorResponse; -import com.yahoo.vespa.hosted.controller.restapi.StringResponse; +import com.yahoo.restapi.ErrorResponse; +import com.yahoo.restapi.StringResponse; import java.time.Clock; import java.util.Optional; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/BadgeApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/BadgeApiHandler.java index 0c5cfc539f1..f3c45ca7221 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/BadgeApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/BadgeApiHandler.java @@ -10,7 +10,7 @@ import com.yahoo.jdisc.http.HttpRequest.Method; import com.yahoo.restapi.Path; import com.yahoo.vespa.hosted.controller.Controller; import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType; -import com.yahoo.vespa.hosted.controller.restapi.ErrorResponse; +import com.yahoo.restapi.ErrorResponse; import com.yahoo.yolean.Exceptions; import java.io.OutputStream; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiHandler.java index 3eb57875dad..b2bc6d72044 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiHandler.java @@ -15,9 +15,9 @@ import com.yahoo.vespa.hosted.controller.Instance; import com.yahoo.vespa.hosted.controller.Controller; import com.yahoo.vespa.hosted.controller.application.JobList; import com.yahoo.vespa.hosted.controller.application.JobStatus; -import com.yahoo.vespa.hosted.controller.restapi.ErrorResponse; -import com.yahoo.vespa.hosted.controller.restapi.SlimeJsonResponse; -import com.yahoo.vespa.hosted.controller.restapi.Uri; +import com.yahoo.restapi.ErrorResponse; +import com.yahoo.restapi.SlimeJsonResponse; +import com.yahoo.restapi.Uri; import com.yahoo.vespa.hosted.controller.restapi.application.EmptyResponse; import com.yahoo.vespa.hosted.controller.versions.VespaVersion; import com.yahoo.yolean.Exceptions; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiHandler.java index fde013b223c..450f4481c5f 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/os/OsApiHandler.java @@ -18,9 +18,9 @@ import com.yahoo.vespa.hosted.controller.Controller; import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.config.provision.zone.ZoneList; import com.yahoo.vespa.hosted.controller.auditlog.AuditLoggingRequestHandler; -import com.yahoo.vespa.hosted.controller.restapi.ErrorResponse; -import com.yahoo.vespa.hosted.controller.restapi.MessageResponse; -import com.yahoo.vespa.hosted.controller.restapi.SlimeJsonResponse; +import com.yahoo.restapi.ErrorResponse; +import com.yahoo.restapi.MessageResponse; +import com.yahoo.restapi.SlimeJsonResponse; import com.yahoo.vespa.hosted.controller.versions.OsVersion; import com.yahoo.yolean.Exceptions; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageProxyHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageProxyHandler.java index 1aa883359ee..8c445fe3a0a 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageProxyHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageProxyHandler.java @@ -7,9 +7,9 @@ import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.container.jdisc.LoggingRequestHandler; import com.yahoo.container.jdisc.secretstore.SecretStore; import com.yahoo.slime.Slime; -import com.yahoo.vespa.hosted.controller.restapi.ErrorResponse; +import com.yahoo.restapi.ErrorResponse; import com.yahoo.restapi.Path; -import com.yahoo.vespa.hosted.controller.restapi.SlimeJsonResponse; +import com.yahoo.restapi.SlimeJsonResponse; import com.yahoo.vespa.hosted.controller.statuspage.config.StatuspageConfig; import com.yahoo.yolean.Exceptions; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiHandler.java index c32ab6726e9..410194a8ef7 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiHandler.java @@ -19,9 +19,9 @@ import com.yahoo.vespa.hosted.controller.api.integration.user.UserId; import com.yahoo.vespa.hosted.controller.api.integration.user.UserManagement; import com.yahoo.vespa.hosted.controller.api.role.Role; import com.yahoo.vespa.hosted.controller.api.role.RoleDefinition; -import com.yahoo.vespa.hosted.controller.restapi.ErrorResponse; -import com.yahoo.vespa.hosted.controller.restapi.MessageResponse; -import com.yahoo.vespa.hosted.controller.restapi.SlimeJsonResponse; +import com.yahoo.restapi.ErrorResponse; +import com.yahoo.restapi.MessageResponse; +import com.yahoo.restapi.SlimeJsonResponse; import com.yahoo.vespa.hosted.controller.restapi.application.EmptyResponse; import com.yahoo.yolean.Exceptions; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/zone/v1/ZoneApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/zone/v1/ZoneApiHandler.java index 6cfaed93fa9..53373bb228a 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/zone/v1/ZoneApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/zone/v1/ZoneApiHandler.java @@ -3,18 +3,16 @@ package com.yahoo.vespa.hosted.controller.restapi.zone.v1; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.RegionName; -import com.yahoo.config.provision.Zone; import com.yahoo.config.provision.zone.ZoneApi; -import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.container.jdisc.LoggingRequestHandler; import com.yahoo.slime.Cursor; import com.yahoo.slime.Slime; import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneRegistry; -import com.yahoo.vespa.hosted.controller.restapi.ErrorResponse; +import com.yahoo.restapi.ErrorResponse; import com.yahoo.restapi.Path; -import com.yahoo.vespa.hosted.controller.restapi.SlimeJsonResponse; +import com.yahoo.restapi.SlimeJsonResponse; import com.yahoo.yolean.Exceptions; import java.util.Comparator; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/zone/v2/ZoneApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/zone/v2/ZoneApiHandler.java index f0259fc4d51..5ce679276f7 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/zone/v2/ZoneApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/zone/v2/ZoneApiHandler.java @@ -15,8 +15,8 @@ import com.yahoo.vespa.hosted.controller.auditlog.AuditLoggingRequestHandler; import com.yahoo.vespa.hosted.controller.proxy.ConfigServerRestExecutor; import com.yahoo.vespa.hosted.controller.proxy.ProxyException; import com.yahoo.vespa.hosted.controller.proxy.ProxyRequest; -import com.yahoo.vespa.hosted.controller.restapi.ErrorResponse; -import com.yahoo.vespa.hosted.controller.restapi.SlimeJsonResponse; +import com.yahoo.restapi.ErrorResponse; +import com.yahoo.restapi.SlimeJsonResponse; import com.yahoo.yolean.Exceptions; import java.io.IOException; diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerProxyMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerProxyMock.java index 4d70987ff28..d6e1af07938 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerProxyMock.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ConfigServerProxyMock.java @@ -5,7 +5,7 @@ import com.yahoo.component.AbstractComponent; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.vespa.hosted.controller.proxy.ConfigServerRestExecutor; import com.yahoo.vespa.hosted.controller.proxy.ProxyRequest; -import com.yahoo.vespa.hosted.controller.restapi.StringResponse; +import com.yahoo.restapi.StringResponse; import java.io.InputStream; import java.util.Optional; diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java index b952ae096b0..865bcc61837 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java @@ -182,7 +182,7 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer { .withTrustStore(trustStorePath, KeyStoreType.JKS) .build(); try { - try (ZtsClient ztsClient = new DefaultZtsClient(ztsEndpoint, context.identity(), containerIdentitySslContext)) { + try (ZtsClient ztsClient = new DefaultZtsClient(ztsEndpoint, containerIdentitySslContext)) { InstanceIdentity instanceIdentity = ztsClient.refreshInstance( configserverIdentity, diff --git a/security-utils/src/main/java/com/yahoo/security/Pkcs10Csr.java b/security-utils/src/main/java/com/yahoo/security/Pkcs10Csr.java index e08ee117fcd..7bcf67b64b6 100644 --- a/security-utils/src/main/java/com/yahoo/security/Pkcs10Csr.java +++ b/security-utils/src/main/java/com/yahoo/security/Pkcs10Csr.java @@ -12,6 +12,7 @@ import org.bouncycastle.pkcs.PKCS10CertificationRequest; import javax.security.auth.x500.X500Principal; import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.Optional; import static java.util.Collections.emptyList; @@ -68,4 +69,17 @@ public class Pkcs10Csr { .map(attribute -> Extensions.getInstance(attribute.getAttrValues().getObjectAt(0))); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Pkcs10Csr pkcs10Csr = (Pkcs10Csr) o; + return Objects.equals(csr, pkcs10Csr.csr); + } + + @Override + public int hashCode() { + return Objects.hash(csr); + } + } diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/DefaultZtsClient.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/DefaultZtsClient.java index 7116bf72ec4..8bd0d0b50d4 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/DefaultZtsClient.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/DefaultZtsClient.java @@ -47,20 +47,18 @@ import static java.util.stream.Collectors.toList; public class DefaultZtsClient extends ClientBase implements ZtsClient { private final URI ztsUrl; - private final AthenzIdentity identity; - public DefaultZtsClient(URI ztsUrl, AthenzIdentity identity, SSLContext sslContext) { - this(ztsUrl, identity, () -> sslContext); + public DefaultZtsClient(URI ztsUrl, SSLContext sslContext) { + this(ztsUrl, () -> sslContext); } public DefaultZtsClient(URI ztsUrl, ServiceIdentityProvider identityProvider) { - this(ztsUrl, identityProvider.identity(), identityProvider::getIdentitySslContext); + this(ztsUrl, identityProvider::getIdentitySslContext); } - private DefaultZtsClient(URI ztsUrl, AthenzIdentity identity, Supplier<SSLContext> sslContextSupplier) { + private DefaultZtsClient(URI ztsUrl, Supplier<SSLContext> sslContextSupplier) { super("vespa-zts-client", sslContextSupplier, ZtsClientException::new); this.ztsUrl = addTrailingSlash(ztsUrl); - this.identity = identity; } @Override diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/SignedIdentityDocumentEntity.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/SignedIdentityDocumentEntity.java index 52d33f79c1d..e6b74d9df4c 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/SignedIdentityDocumentEntity.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/SignedIdentityDocumentEntity.java @@ -79,7 +79,7 @@ public class SignedIdentityDocumentEntity { Objects.equals(instanceHostname, that.instanceHostname) && Objects.equals(createdAt, that.createdAt) && Objects.equals(ipAddresses, that.ipAddresses) && - Objects.equals(identityType, identityType); + Objects.equals(identityType, that.identityType); } @Override diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzCredentialsService.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzCredentialsService.java index eccf1088cce..3b733e05708 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzCredentialsService.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzCredentialsService.java @@ -99,7 +99,7 @@ class AthenzCredentialsService { document.ipAddresses(), newKeyPair); - try (ZtsClient ztsClient = new DefaultZtsClient(ztsEndpoint, tenantIdentity, sslContext)) { + try (ZtsClient ztsClient = new DefaultZtsClient(ztsEndpoint, sslContext)) { InstanceIdentity instanceIdentity = ztsClient.refreshInstance( configserverIdentity, diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java index bff40d67fa6..d3be7829927 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java @@ -245,7 +245,7 @@ public final class AthenzIdentityProviderImpl extends AbstractComponent implemen } private DefaultZtsClient createZtsClient() { - return new DefaultZtsClient(ztsEndpoint, identity(), getIdentitySslContext()); + return new DefaultZtsClient(ztsEndpoint, getIdentitySslContext()); } @Override |