diff options
Diffstat (limited to 'controller-api')
4 files changed, 321 insertions, 34 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateDetails.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateDetails.java new file mode 100644 index 00000000000..bf1c9333e84 --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateDetails.java @@ -0,0 +1,224 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.api.integration.certificates; + +import java.util.List; +import java.util.Objects; +import java.util.StringJoiner; + +/** + * This class is used when requesting additional metadata about an application's endpoint certificate from the provider. + * + * @author andreer + */ +public class EndpointCertificateDetails { + + private final String request_id; + private final String requestor; + private final String status; + private final String ticket_id; + private final String athenz_domain; + private final List<EndpointCertificateRequestMetadata.DnsNameStatus> dnsnames; + private final String duration_sec; + private final String expiry; + private final String private_key_kgname; + private final String private_key_keyname; + private final String private_key_version; + private final String cert_key_kgname; + private final String cert_key_keyname; + private final String cert_key_version; + private final String create_time; + private final boolean expiry_protection; + private final String public_key_algo; + private final String issuer; + private final String serial; + + public EndpointCertificateDetails(String request_id, + String requestor, + String status, + String ticket_id, + String athenz_domain, + List<EndpointCertificateRequestMetadata.DnsNameStatus> dnsnames, + String duration_sec, + String expiry, + String private_key_kgname, + String private_key_keyname, + String private_key_version, + String cert_key_kgname, + String cert_key_keyname, + String cert_key_version, + String create_time, + boolean expiry_protection, + String public_key_algo, + String issuer, + String serial) { + this.request_id = request_id; + this.requestor = requestor; + this.status = status; + this.ticket_id = ticket_id; + this.athenz_domain = athenz_domain; + this.dnsnames = dnsnames; + this.duration_sec = duration_sec; + this.expiry = expiry; + this.private_key_kgname = private_key_kgname; + this.private_key_keyname = private_key_keyname; + this.private_key_version = private_key_version; + this.cert_key_kgname = cert_key_kgname; + this.cert_key_keyname = cert_key_keyname; + this.cert_key_version = cert_key_version; + this.create_time = create_time; + this.expiry_protection = expiry_protection; + this.public_key_algo = public_key_algo; + this.issuer = issuer; + this.serial = serial; + } + + public String request_id() { + return request_id; + } + + public String requestor() { + return requestor; + } + + public String status() { + return status; + } + + public String ticket_id() { + return ticket_id; + } + + public String athenz_domain() { + return athenz_domain; + } + + public List<EndpointCertificateRequestMetadata.DnsNameStatus> dnsnames() { + return dnsnames; + } + + public String duration_sec() { + return duration_sec; + } + + public String expiry() { + return expiry; + } + + public String private_key_kgname() { + return private_key_kgname; + } + + public String private_key_keyname() { + return private_key_keyname; + } + + public String private_key_version() { + return private_key_version; + } + + public String cert_key_kgname() { + return cert_key_kgname; + } + + public String cert_key_keyname() { + return cert_key_keyname; + } + + public String cert_key_version() { + return cert_key_version; + } + + public String create_time() { + return create_time; + } + + public boolean expiry_protection() { + return expiry_protection; + } + + public String public_key_algo() { + return public_key_algo; + } + + public String issuer() { + return issuer; + } + + public String serial() { + return serial; + } + + @Override + public String toString() { + return new StringJoiner(", ", EndpointCertificateDetails.class.getSimpleName() + "[", "]") + .add("request_id='" + request_id + "'") + .add("requestor='" + requestor + "'") + .add("status='" + status + "'") + .add("ticket_id='" + ticket_id + "'") + .add("athenz_domain='" + athenz_domain + "'") + .add("dnsnames=" + dnsnames) + .add("duration_sec='" + duration_sec + "'") + .add("expiry='" + expiry + "'") + .add("private_key_kgname='" + private_key_kgname + "'") + .add("private_key_keyname='" + private_key_keyname + "'") + .add("private_key_version='" + private_key_version + "'") + .add("cert_key_kgname='" + cert_key_kgname + "'") + .add("cert_key_keyname='" + cert_key_keyname + "'") + .add("cert_key_version='" + cert_key_version + "'") + .add("create_time='" + create_time + "'") + .add("expiry_protection=" + expiry_protection) + .add("public_key_algo='" + public_key_algo + "'") + .add("issuer='" + issuer + "'") + .add("serial='" + serial + "'") + .toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + EndpointCertificateDetails that = (EndpointCertificateDetails) o; + return expiry_protection == that.expiry_protection + && request_id.equals(that.request_id) + && requestor.equals(that.requestor) + && status.equals(that.status) + && ticket_id.equals(that.ticket_id) + && athenz_domain.equals(that.athenz_domain) + && dnsnames.equals(that.dnsnames) + && duration_sec.equals(that.duration_sec) + && expiry.equals(that.expiry) + && private_key_kgname.equals(that.private_key_kgname) + && private_key_keyname.equals(that.private_key_keyname) + && private_key_version.equals(that.private_key_version) + && cert_key_kgname.equals(that.cert_key_kgname) + && cert_key_keyname.equals(that.cert_key_keyname) + && cert_key_version.equals(that.cert_key_version) + && create_time.equals(that.create_time) + && public_key_algo.equals(that.public_key_algo) + && issuer.equals(that.issuer) + && serial.equals(that.serial); + } + + @Override + public int hashCode() { + return Objects.hash(request_id, + requestor, + status, + ticket_id, + athenz_domain, + dnsnames, + duration_sec, + expiry, + private_key_kgname, + private_key_keyname, + private_key_version, + cert_key_kgname, + cert_key_keyname, + cert_key_version, + create_time, + expiry_protection, + public_key_algo, + issuer, + serial); + } +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateMetadata.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateMetadata.java index 12ff5388eb1..1b36a573bf1 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateMetadata.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateMetadata.java @@ -18,18 +18,20 @@ public class EndpointCertificateMetadata { private final String certName; private final int version; private final long lastRequested; - private final String requestId; + private final String rootRequestId; + private final Optional<String> leafRequestId; private final List<String> requestedDnsSans; private final String issuer; private final Optional<Long> expiry; private final Optional<Long> lastRefreshed; - public EndpointCertificateMetadata(String keyName, String certName, int version, long lastRequested, String requestId, List<String> requestedDnsSans, String issuer, Optional<Long> expiry, Optional<Long> lastRefreshed) { + public EndpointCertificateMetadata(String keyName, String certName, int version, long lastRequested, String rootRequestId, Optional<String> leafRequestId, List<String> requestedDnsSans, String issuer, Optional<Long> expiry, Optional<Long> lastRefreshed) { this.keyName = keyName; this.certName = certName; this.version = version; this.lastRequested = lastRequested; - this.requestId = requestId; + this.rootRequestId = rootRequestId; + this.leafRequestId = leafRequestId; this.requestedDnsSans = requestedDnsSans; this.issuer = issuer; this.expiry = expiry; @@ -52,8 +54,18 @@ public class EndpointCertificateMetadata { return lastRequested; } - public String requestId() { - return requestId; + /** + * @return The request id of the first request made for this certificate. Should not change. + */ + public String rootRequestId() { + return rootRequestId; + } + + /** + * @return The request id of the last known request made for this certificate. Changes on refresh, may be outdated! + */ + public Optional<String> leafRequestId() { + return leafRequestId; } public List<String> requestedDnsSans() { @@ -78,7 +90,8 @@ public class EndpointCertificateMetadata { this.certName, version, this.lastRequested, - this.requestId, + this.rootRequestId, + this.leafRequestId, this.requestedDnsSans, this.issuer, this.expiry, @@ -91,7 +104,8 @@ public class EndpointCertificateMetadata { this.certName, this.version, lastRequested, - this.requestId, + this.rootRequestId, + this.leafRequestId, this.requestedDnsSans, this.issuer, this.expiry, @@ -104,20 +118,36 @@ public class EndpointCertificateMetadata { this.certName, this.version, this.lastRequested, - this.requestId, + this.rootRequestId, + this.leafRequestId, this.requestedDnsSans, this.issuer, this.expiry, Optional.of(lastRefreshed)); } - public EndpointCertificateMetadata withRequestId(String requestId) { + public EndpointCertificateMetadata withRootRequestId(String rootRequestId) { + return new EndpointCertificateMetadata( + this.keyName, + this.certName, + this.version, + this.lastRequested, + rootRequestId, + this.leafRequestId, + this.requestedDnsSans, + this.issuer, + this.expiry, + lastRefreshed); + } + + public EndpointCertificateMetadata withLeafRequestId(Optional<String> leafRequestId) { return new EndpointCertificateMetadata( this.keyName, this.certName, this.version, this.lastRequested, - requestId, + this.rootRequestId, + leafRequestId, this.requestedDnsSans, this.issuer, this.expiry, @@ -127,16 +157,17 @@ public class EndpointCertificateMetadata { @Override public String toString() { return "EndpointCertificateMetadata{" + - "keyName='" + keyName + '\'' + - ", certName='" + certName + '\'' + - ", version=" + version + - ", lastRequested=" + lastRequested + - ", requestId=" + requestId + - ", requestedDnsSans=" + requestedDnsSans + - ", issuer=" + issuer + - ", expiry=" + expiry + - ", lastRefreshed=" + lastRefreshed + - '}'; + "keyName='" + keyName + '\'' + + ", certName='" + certName + '\'' + + ", version=" + version + + ", lastRequested=" + lastRequested + + ", rootRequestId=" + rootRequestId + + ", leafRequestId=" + leafRequestId + + ", requestedDnsSans=" + requestedDnsSans + + ", issuer=" + issuer + + ", expiry=" + expiry + + ", lastRefreshed=" + lastRefreshed + + '}'; } @Override @@ -146,18 +177,19 @@ public class EndpointCertificateMetadata { EndpointCertificateMetadata that = (EndpointCertificateMetadata) o; return version == that.version && lastRequested == that.lastRequested && - keyName.equals(that.keyName) && - certName.equals(that.certName) && - requestId.equals(that.requestId) && - requestedDnsSans.equals(that.requestedDnsSans) && - issuer.equals(that.issuer) && - expiry.equals(that.expiry) && - lastRefreshed.equals(that.lastRefreshed); + keyName.equals(that.keyName) && + certName.equals(that.certName) && + rootRequestId.equals(that.rootRequestId) && + leafRequestId.equals(that.leafRequestId) && + requestedDnsSans.equals(that.requestedDnsSans) && + issuer.equals(that.issuer) && + expiry.equals(that.expiry) && + lastRefreshed.equals(that.lastRefreshed); } @Override public int hashCode() { - return Objects.hash(keyName, certName, version, lastRequested, requestId, requestedDnsSans, issuer, expiry, lastRefreshed); + return Objects.hash(keyName, certName, version, lastRequested, rootRequestId, leafRequestId, requestedDnsSans, issuer, expiry, lastRefreshed); } } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateMock.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateMock.java index 3e484a5669b..19dc852da21 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateMock.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateMock.java @@ -33,8 +33,10 @@ public class EndpointCertificateMock implements EndpointCertificateProvider { long epochSecond = Instant.now().getEpochSecond(); long inAnHour = epochSecond + 3600; String requestId = UUID.randomUUID().toString(); - EndpointCertificateMetadata metadata = new EndpointCertificateMetadata(endpointCertificatePrefix + "-key", endpointCertificatePrefix + "-cert", 0, 0, - requestId, dnsNames, "mockCa", Optional.of(inAnHour), Optional.of(epochSecond)); + int version = currentMetadata.map(c -> currentMetadata.get().version()+1).orElse(0); + EndpointCertificateMetadata metadata = new EndpointCertificateMetadata(endpointCertificatePrefix + "-key", endpointCertificatePrefix + "-cert", version, 0, + currentMetadata.map(EndpointCertificateMetadata::rootRequestId).orElse(requestId), Optional.of(requestId), dnsNames, "mockCa", Optional.of(inAnHour), Optional.of(epochSecond)); + currentMetadata.ifPresent(c -> providerMetadata.remove(c.leafRequestId().orElseThrow())); providerMetadata.put(requestId, metadata); return metadata; } @@ -44,10 +46,10 @@ public class EndpointCertificateMock implements EndpointCertificateProvider { return providerMetadata.values().stream() .map(p -> new EndpointCertificateRequestMetadata( - p.requestId(), - "mock", - "mock", - "mock", + p.leafRequestId().orElse(p.rootRequestId()), + "requestor", + "ticketId", + "athenzDomain", p.requestedDnsSans().stream() .map(san -> new EndpointCertificateRequestMetadata.DnsNameStatus(san, "done")) .collect(Collectors.toUnmodifiableList()), @@ -67,4 +69,30 @@ public class EndpointCertificateMock implements EndpointCertificateProvider { providerMetadata.remove(requestId); } + @Override + public EndpointCertificateDetails certificateDetails(String requestId) { + var metadata = providerMetadata.get(requestId); + + if(metadata==null) throw new RuntimeException("Unknown certificate request"); + + return new EndpointCertificateDetails(requestId, + "requestor", + "ok", + "ticket_id", + "athenz_domain", + metadata.requestedDnsSans().stream().map(name -> new EndpointCertificateRequestMetadata.DnsNameStatus(name, "done")).collect(Collectors.toList()), + "duration_sec", + "expiry", + metadata.keyName(), + metadata.keyName(), + "0", + metadata.certName(), + metadata.certName(), + "0", + "2021-09-28T00:14:31.946562037Z", + true, + "public_key_algo", + "issuer", + "serial"); + } } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateProvider.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateProvider.java index f4e41a25b79..26db25bd848 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateProvider.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateProvider.java @@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.controller.api.integration.certificates; import com.yahoo.config.provision.ApplicationId; +import java.io.IOException; import java.util.List; import java.util.Optional; @@ -18,4 +19,6 @@ public interface EndpointCertificateProvider { List<EndpointCertificateRequestMetadata> listCertificates(); void deleteCertificate(ApplicationId applicationId, String requestId); + + EndpointCertificateDetails certificateDetails(String requestId); } |