summaryrefslogtreecommitdiffstats
path: root/controller-api
diff options
context:
space:
mode:
authorØyvind Grønnesby <oyving@yahooinc.com>2023-07-25 10:02:13 +0200
committerØyvind Grønnesby <oyving@yahooinc.com>2023-07-25 10:20:48 +0200
commitd678b4e8fe80c25118fd5aa1cf6353ef7a327eb7 (patch)
treea344fbd628a8ca6958ffd25d0607319f2c5e0f27 /controller-api
parentb4126b644d2214564a9ed76c1c006b09454dbb6f (diff)
parent78a211072a21ec5f368b99bce19c1b703d98152d (diff)
Merge branch 'master' into ogronnesby/billing-reporting
Diffstat (limited to 'controller-api')
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/DeploymentData.java12
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/AthenzDbMock.java68
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/ZmsClientMock.java4
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/MockRoleService.java3
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/NoopRoleService.java2
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/RoleService.java2
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificate.java (renamed from controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateMetadata.java)46
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateDetails.java32
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateException.java3
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateMock.java94
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateProvider.java4
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateProviderMock.java94
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateRequest.java18
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateRequestMetadata.java175
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateValidator.java5
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateValidatorImpl.java4
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateValidatorMock.java2
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepository.java2
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dataplanetoken/DataplaneToken.java5
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dataplanetoken/DataplaneTokenVersions.java4
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/maven/Metadata.java20
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/secrets/GcpSecretStore.java10
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/secrets/NoopGcpSecretStore.java13
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockMavenRepository.java19
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/ChangeRequestSource.java87
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VcmrReport.java7
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VespaChangeRequest.java1
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java3
-rw-r--r--controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/maven/MetadataTest.java11
29 files changed, 327 insertions, 423 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/DeploymentData.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/DeploymentData.java
index b23b93cba78..f73aeb89f0e 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/DeploymentData.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/DeploymentData.java
@@ -8,7 +8,7 @@ import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.vespa.athenz.api.AthenzDomain;
import com.yahoo.vespa.hosted.controller.api.integration.billing.Quota;
-import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata;
+import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificate;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.ContainerEndpoint;
import com.yahoo.vespa.hosted.controller.api.integration.dataplanetoken.DataplaneTokenVersions;
import com.yahoo.vespa.hosted.controller.api.integration.secrets.TenantSecretStore;
@@ -36,7 +36,7 @@ public class DeploymentData {
private final Supplier<InputStream> applicationPackage;
private final Version platform;
private final Set<ContainerEndpoint> containerEndpoints;
- private final Supplier<Optional<EndpointCertificateMetadata>> endpointCertificateMetadata;
+ private final Supplier<Optional<EndpointCertificate>> endpointCertificate;
private final Optional<DockerImage> dockerImageRepo;
private final Optional<AthenzDomain> athenzDomain;
private final Supplier<Quota> quota;
@@ -48,7 +48,7 @@ public class DeploymentData {
public DeploymentData(ApplicationId instance, ZoneId zone, Supplier<InputStream> applicationPackage, Version platform,
Set<ContainerEndpoint> containerEndpoints,
- Supplier<Optional<EndpointCertificateMetadata>> endpointCertificateMetadata,
+ Supplier<Optional<EndpointCertificate>> endpointCertificate,
Optional<DockerImage> dockerImageRepo,
Optional<AthenzDomain> athenzDomain,
Supplier<Quota> quota,
@@ -62,7 +62,7 @@ public class DeploymentData {
this.applicationPackage = requireNonNull(applicationPackage);
this.platform = requireNonNull(platform);
this.containerEndpoints = Set.copyOf(requireNonNull(containerEndpoints));
- this.endpointCertificateMetadata = new Memoized<>(requireNonNull(endpointCertificateMetadata));
+ this.endpointCertificate = new Memoized<>(requireNonNull(endpointCertificate));
this.dockerImageRepo = requireNonNull(dockerImageRepo);
this.athenzDomain = athenzDomain;
this.quota = new Memoized<>(requireNonNull(quota));
@@ -93,8 +93,8 @@ public class DeploymentData {
return containerEndpoints;
}
- public Optional<EndpointCertificateMetadata> endpointCertificateMetadata() {
- return endpointCertificateMetadata.get();
+ public Optional<EndpointCertificate> endpointCertificate() {
+ return endpointCertificate.get();
}
public Optional<DockerImage> dockerImageRepo() {
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/AthenzDbMock.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/AthenzDbMock.java
index 9a9c2af2d5d..820dc2ac573 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/AthenzDbMock.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/AthenzDbMock.java
@@ -96,6 +96,35 @@ public class AthenzDbMock {
public boolean checkAccess(AthenzIdentity principal, String action, String resource) {
return policies.values().stream().anyMatch(a -> a.matches(principal, action, resource));
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Domain domain = (Domain) o;
+ return isVespaTenant == domain.isVespaTenant && Objects.equals(name, domain.name) && Objects.equals(admins, domain.admins) && Objects.equals(tenantAdmins, domain.tenantAdmins) && Objects.equals(applications, domain.applications) && Objects.equals(services, domain.services) && Objects.equals(roles, domain.roles) && Objects.equals(policies, domain.policies) && Objects.equals(attributes, domain.attributes);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, admins, tenantAdmins, applications, services, roles, policies, isVespaTenant, attributes);
+ }
+
+ @Override
+ public String toString() {
+ return "Domain{" +
+ "name=" + name +
+ ", admins=" + admins +
+ ", tenantAdmins=" + tenantAdmins +
+ ", applications=" + applications +
+ ", services=" + services +
+ ", roles=" + roles +
+ ", policies=" + policies +
+ ", isVespaTenant=" + isVespaTenant +
+ ", attributes=" + attributes +
+ '}';
+ }
+
}
public static class Application {
@@ -121,11 +150,30 @@ public class AthenzDbMock {
public Service(boolean allowLaunch) {
this.allowLaunch = allowLaunch;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Service service = (Service) o;
+ return allowLaunch == service.allowLaunch;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(allowLaunch);
+ }
+
+ @Override
+ public String toString() {
+ return allowLaunch ? "allowed" : "denied";
+ }
+
}
public static class Policy {
private final String name;
- final List<Assertion> assertions = new ArrayList<>();
+ public final List<Assertion> assertions = new ArrayList<>();
public Policy(String name, String principal, String action, String resource) {
this(name);
@@ -158,6 +206,12 @@ public class AthenzDbMock {
public int hashCode() {
return Objects.hash(name, assertions);
}
+
+ @Override
+ public String toString() {
+ return name + ": " + assertions;
+ }
+
}
public static class Assertion {
@@ -203,6 +257,12 @@ public class AthenzDbMock {
public int hashCode() {
return Objects.hash(effect, role, action, resource);
}
+
+ @Override
+ public String toString() {
+ return asString();
+ }
+
}
public static class Role {
@@ -228,5 +288,11 @@ public class AthenzDbMock {
public int hashCode() {
return Objects.hash(name);
}
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
}
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/ZmsClientMock.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/ZmsClientMock.java
index 94ed28778d7..9681b2b7326 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/ZmsClientMock.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/ZmsClientMock.java
@@ -145,7 +145,7 @@ public class ZmsClientMock implements ZmsClient {
.map(d -> d.attributes)
.map(attrs -> {
if (attrs.containsKey("account")) {
- return new AthenzDomainMeta((String)attrs.get("account"), domain.getName());
+ return new AthenzDomainMeta((String) attrs.get("account"), (String) attrs.get("gcpProject"), domain.getName());
}
return null;
})
@@ -153,7 +153,7 @@ public class ZmsClientMock implements ZmsClient {
}
@Override
- public void updateDomain(AthenzDomain domain, Map<String, Object> attributes) {
+ public void updateDomain(AthenzDomain domain, String mainKey, Map<String, Object> attributes) {
if (!athenz.domains.containsKey(domain)) throw new IllegalStateException("Domain does not exist: " + domain.getName());
athenz.domains.get(domain).withAttributes(attributes);
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/MockRoleService.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/MockRoleService.java
index aa0d9c75b81..75789c0989b 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/MockRoleService.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/MockRoleService.java
@@ -11,8 +11,9 @@ public class MockRoleService extends NoopRoleService {
private List<TenantName> maintainedTenants;
@Override
- public void maintainRoles(List<TenantName> tenants) {
+ public double maintainRoles(List<TenantName> tenants) {
maintainedTenants = List.copyOf(tenants);
+ return 1;
}
public List<TenantName> maintainedTenants() {
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/NoopRoleService.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/NoopRoleService.java
index 1ef1bc5106c..93a09b6c6bc 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/NoopRoleService.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/NoopRoleService.java
@@ -34,7 +34,7 @@ public class NoopRoleService implements RoleService {
public void deleteTenantPolicy(TenantName tenant, String policyName, String role) { }
@Override
- public void maintainRoles(List<TenantName> tenants) { }
+ public double maintainRoles(List<TenantName> tenants) { return 1; }
@Override
public void cleanupRoles(List<TenantName> tenants) {
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/RoleService.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/RoleService.java
index 0a35893a7c4..345545ab6f7 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/RoleService.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/RoleService.java
@@ -26,7 +26,7 @@ public interface RoleService {
/*
* Maintain roles for the tenants in the system. Create missing roles, update trust.
*/
- void maintainRoles(List<TenantName> tenants);
+ double maintainRoles(List<TenantName> tenants);
void cleanupRoles(List<TenantName> deletedTenants);
}
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/EndpointCertificate.java
index 02afbb6ace6..53d807b0139 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/EndpointCertificate.java
@@ -5,20 +5,18 @@ import java.util.List;
import java.util.Optional;
/**
- * This class is used for metadata about an application's endpoint certificate on the controller.
- * <p>
- * It has more properties than com.yahoo.config.model.api.EndpointCertificateMetadata.
+ * This holds information about an application's endpoint certificate.
*
* @author andreer
*/
-public record EndpointCertificateMetadata(String keyName, String certName, int version, long lastRequested,
- String rootRequestId, // The id of the first request made for this certificate. Should not change.
- Optional<String> leafRequestId, // The id of the last known request made for this certificate. Changes on refresh, may be outdated!
- List<String> requestedDnsSans, String issuer, Optional<Long> expiry,
- Optional<Long> lastRefreshed, Optional<String> randomizedId) {
+public record EndpointCertificate(String keyName, String certName, int version, long lastRequested,
+ String rootRequestId, // The id of the first request made for this certificate. Should not change.
+ Optional<String> leafRequestId, // The id of the last known request made for this certificate. Changes on refresh, may be outdated!
+ List<String> requestedDnsSans, String issuer, Optional<Long> expiry,
+ Optional<Long> lastRefreshed, Optional<String> randomizedId) {
- public EndpointCertificateMetadata withRandomizedId(String randomizedId) {
- return new EndpointCertificateMetadata(
+ public EndpointCertificate withRandomizedId(String randomizedId) {
+ return new EndpointCertificate(
this.keyName,
this.certName,
this.version,
@@ -32,8 +30,8 @@ public record EndpointCertificateMetadata(String keyName, String certName, int v
Optional.of(randomizedId));
}
- public EndpointCertificateMetadata withKeyName(String keyName) {
- return new EndpointCertificateMetadata(
+ public EndpointCertificate withKeyName(String keyName) {
+ return new EndpointCertificate(
keyName,
this.certName,
this.version,
@@ -47,8 +45,8 @@ public record EndpointCertificateMetadata(String keyName, String certName, int v
this.randomizedId);
}
- public EndpointCertificateMetadata withCertName(String certName) {
- return new EndpointCertificateMetadata(
+ public EndpointCertificate withCertName(String certName) {
+ return new EndpointCertificate(
this.keyName,
certName,
this.version,
@@ -62,8 +60,8 @@ public record EndpointCertificateMetadata(String keyName, String certName, int v
this.randomizedId);
}
- public EndpointCertificateMetadata withVersion(int version) {
- return new EndpointCertificateMetadata(
+ public EndpointCertificate withVersion(int version) {
+ return new EndpointCertificate(
this.keyName,
this.certName,
version,
@@ -77,8 +75,8 @@ public record EndpointCertificateMetadata(String keyName, String certName, int v
this.randomizedId);
}
- public EndpointCertificateMetadata withLastRequested(long lastRequested) {
- return new EndpointCertificateMetadata(
+ public EndpointCertificate withLastRequested(long lastRequested) {
+ return new EndpointCertificate(
this.keyName,
this.certName,
this.version,
@@ -92,8 +90,8 @@ public record EndpointCertificateMetadata(String keyName, String certName, int v
this.randomizedId);
}
- public EndpointCertificateMetadata withLastRefreshed(long lastRefreshed) {
- return new EndpointCertificateMetadata(
+ public EndpointCertificate withLastRefreshed(long lastRefreshed) {
+ return new EndpointCertificate(
this.keyName,
this.certName,
this.version,
@@ -107,8 +105,8 @@ public record EndpointCertificateMetadata(String keyName, String certName, int v
this.randomizedId);
}
- public EndpointCertificateMetadata withRootRequestId(String rootRequestId) {
- return new EndpointCertificateMetadata(
+ public EndpointCertificate withRootRequestId(String rootRequestId) {
+ return new EndpointCertificate(
this.keyName,
this.certName,
this.version,
@@ -122,8 +120,8 @@ public record EndpointCertificateMetadata(String keyName, String certName, int v
this.randomizedId);
}
- public EndpointCertificateMetadata withLeafRequestId(Optional<String> leafRequestId) {
- return new EndpointCertificateMetadata(
+ public EndpointCertificate withLeafRequestId(Optional<String> leafRequestId) {
+ return new EndpointCertificate(
this.keyName,
this.certName,
this.version,
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
index 3f5514dce8c..18565011d25 100644
--- 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
@@ -4,28 +4,28 @@ package com.yahoo.vespa.hosted.controller.api.integration.certificates;
import java.util.List;
/**
- * This record is used when requesting additional metadata about an application's endpoint certificate from the provider.
+ * This record is used when requesting additional details about an application's endpoint certificate from the provider.
*
* @author andreer
*/
public record EndpointCertificateDetails(
- String request_id,
+ String requestId,
String requestor,
String status,
- String ticket_id,
- String athenz_domain,
- List<EndpointCertificateRequestMetadata.DnsNameStatus> dnsnames,
- String duration_sec,
+ String ticketId,
+ String athenzDomain,
+ List<EndpointCertificateRequest.DnsNameStatus> dnsNames,
+ String durationSec,
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 privateKeyKgname,
+ String privateKeyKeyname,
+ String privateKeyVersion,
+ String certKeyKgname,
+ String certKeyKeyname,
+ String certKeyVersion,
+ String createTime,
+ boolean expiryProtection,
+ String publicKeyAlgo,
String issuer,
String serial
-) { } \ No newline at end of file
+) { }
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateException.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateException.java
index a446a5382fb..7f4f22ced40 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateException.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateException.java
@@ -1,6 +1,9 @@
// 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;
+/**
+ * @author andreer
+ */
public class EndpointCertificateException extends RuntimeException {
private final Type type;
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
deleted file mode 100644
index a0448e41b68..00000000000
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateMock.java
+++ /dev/null
@@ -1,94 +0,0 @@
-// 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.time.Instant;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.UUID;
-
-/**
- * @author tokle
- * @author andreer
- */
-public class EndpointCertificateMock implements EndpointCertificateProvider {
-
- private final Map<String, List<String>> dnsNames = new HashMap<>();
- private final Map<String, EndpointCertificateMetadata> providerMetadata = new HashMap<>();
-
- public List<String> dnsNamesOf(String rootRequestId) {
- return Collections.unmodifiableList(dnsNames.getOrDefault(rootRequestId, List.of()));
- }
-
- @Override
- public EndpointCertificateMetadata requestCaSignedCertificate(String key, List<String> dnsNames, Optional<EndpointCertificateMetadata> currentMetadata, String algo, boolean useAlternativeProvider) {
- String endpointCertificatePrefix = "vespa.tls.%s".formatted(key);
- long epochSecond = Instant.now().getEpochSecond();
- long inAnHour = epochSecond + 3600;
- String requestId = UUID.randomUUID().toString();
- this.dnsNames.put(requestId, dnsNames);
- 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), Optional.empty());
- currentMetadata.ifPresent(c -> providerMetadata.remove(c.leafRequestId().orElseThrow()));
- providerMetadata.put(requestId, metadata);
- return metadata;
- }
-
- @Override
- public List<EndpointCertificateRequestMetadata> listCertificates() {
-
- return providerMetadata.values().stream()
- .map(p -> new EndpointCertificateRequestMetadata(
- p.leafRequestId().orElse(p.rootRequestId()),
- "requestor",
- "ticketId",
- "athenzDomain",
- p.requestedDnsSans().stream()
- .map(san -> new EndpointCertificateRequestMetadata.DnsNameStatus(san, "done"))
- .toList(),
- 3600,
- "ok",
- "2021-09-28T00:14:31.946562037Z",
- p.expiry().orElseThrow(),
- p.issuer(),
- "rsa_2048"
- ))
- .toList();
- }
-
- @Override
- public void deleteCertificate(String requestId) {
- dnsNames.remove(requestId);
- 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")).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 7c5268ea353..865abeac031 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
@@ -11,9 +11,9 @@ import java.util.Optional;
*/
public interface EndpointCertificateProvider {
- EndpointCertificateMetadata requestCaSignedCertificate(String endpointCertificatePrefix, List<String> dnsNames, Optional<EndpointCertificateMetadata> currentMetadata, String algo, boolean useAlternativeProvider);
+ EndpointCertificate requestCaSignedCertificate(String endpointCertificatePrefix, List<String> dnsNames, Optional<EndpointCertificate> currentCert, String algo, boolean useAlternativeProvider);
- List<EndpointCertificateRequestMetadata> listCertificates();
+ List<EndpointCertificateRequest> listCertificates();
void deleteCertificate(String requestId);
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateProviderMock.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateProviderMock.java
new file mode 100644
index 00000000000..223eeb19a86
--- /dev/null
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateProviderMock.java
@@ -0,0 +1,94 @@
+// 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.time.Instant;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+
+/**
+ * @author tokle
+ * @author andreer
+ */
+public class EndpointCertificateProviderMock implements EndpointCertificateProvider {
+
+ private final Map<String, List<String>> dnsNames = new HashMap<>();
+ private final Map<String, EndpointCertificate> certificates = new HashMap<>();
+
+ public List<String> dnsNamesOf(String rootRequestId) {
+ return Collections.unmodifiableList(dnsNames.getOrDefault(rootRequestId, List.of()));
+ }
+
+ @Override
+ public EndpointCertificate requestCaSignedCertificate(String key, List<String> dnsNames, Optional<EndpointCertificate> currentCert, String algo, boolean useAlternativeProvider) {
+ String endpointCertificatePrefix = "vespa.tls.%s".formatted(key);
+ long epochSecond = Instant.now().getEpochSecond();
+ long inAnHour = epochSecond + 3600;
+ String requestId = UUID.randomUUID().toString();
+ this.dnsNames.put(requestId, dnsNames);
+ int version = currentCert.map(c -> currentCert.get().version() + 1).orElse(0);
+ EndpointCertificate cert = new EndpointCertificate(endpointCertificatePrefix + "-key", endpointCertificatePrefix + "-cert", version, 0,
+ currentCert.map(EndpointCertificate::rootRequestId).orElse(requestId), Optional.of(requestId), dnsNames, "mockCa", Optional.of(inAnHour), Optional.of(epochSecond), Optional.empty());
+ currentCert.ifPresent(c -> certificates.remove(c.leafRequestId().orElseThrow()));
+ certificates.put(requestId, cert);
+ return cert;
+ }
+
+ @Override
+ public List<EndpointCertificateRequest> listCertificates() {
+ return certificates.values().stream()
+ .map(p -> new EndpointCertificateRequest(
+ p.leafRequestId().orElse(p.rootRequestId()),
+ "requestor",
+ "ticketId",
+ "athenzDomain",
+ p.requestedDnsSans().stream()
+ .map(san -> new EndpointCertificateRequest.DnsNameStatus(san, "done"))
+ .toList(),
+ 3600,
+ "ok",
+ "2021-09-28T00:14:31.946562037Z",
+ p.expiry().orElseThrow(),
+ p.issuer(),
+ "rsa_2048"
+ ))
+ .toList();
+ }
+
+ @Override
+ public void deleteCertificate(String requestId) {
+ dnsNames.remove(requestId);
+ certificates.remove(requestId);
+ }
+
+ @Override
+ public EndpointCertificateDetails certificateDetails(String requestId) {
+ var request = certificates.get(requestId);
+
+ if (request == null) throw new IllegalArgumentException("Unknown certificate request");
+
+ return new EndpointCertificateDetails(requestId,
+ "requestor",
+ "ok",
+ "ticket_id",
+ "athenz_domain",
+ request.requestedDnsSans().stream().map(name -> new EndpointCertificateRequest.DnsNameStatus(name, "done")).toList(),
+ "duration_sec",
+ "expiry",
+ request.keyName(),
+ request.keyName(),
+ "0",
+ request.certName(),
+ request.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/EndpointCertificateRequest.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateRequest.java
new file mode 100644
index 00000000000..877f7ed64b0
--- /dev/null
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateRequest.java
@@ -0,0 +1,18 @@
+// 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;
+
+/**
+ * This class is used for details about an application's endpoint certificate received from the certificate provider.
+ *
+ * @param createTime ISO 8601
+ * @author andreer
+ */
+public record EndpointCertificateRequest(String requestId, String requestor, String ticketId, String athenzDomain,
+ List<DnsNameStatus> dnsNames, long durationSec, String status,
+ String createTime, long expiry, String issuer, String publicKeyAlgo) {
+
+ public record DnsNameStatus(String dnsName, String status) {}
+
+}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateRequestMetadata.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateRequestMetadata.java
deleted file mode 100644
index 339389105e6..00000000000
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateRequestMetadata.java
+++ /dev/null
@@ -1,175 +0,0 @@
-// 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;
-
-/**
- * This class is used for metadata about an application's endpoint certificate received from the certificate provider.
- *
- * @author andreer
- */
-public class EndpointCertificateRequestMetadata {
-
- public EndpointCertificateRequestMetadata(String requestId,
- String requestor,
- String ticketId,
- String athenzDomain,
- List<DnsNameStatus> dnsNames,
- long durationSec,
- String status,
- String createTime,
- long expiry,
- String issuer,
- String publicKeyAlgo) {
- this.requestId = requestId;
- this.requestor = requestor;
- this.ticketId = ticketId;
- this.athenzDomain = athenzDomain;
- this.dnsNames = dnsNames;
- this.durationSec = durationSec;
- this.status = status;
- this.createTime = createTime;
- this.expiry = expiry;
- this.issuer = issuer;
- this.publicKeyAlgo = publicKeyAlgo;
- }
-
- public static class DnsNameStatus {
- public final String dnsName;
- public final String status;
-
- public DnsNameStatus(String dnsName, String status) {
- this.dnsName = dnsName;
- this.status = status;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- DnsNameStatus that = (DnsNameStatus) o;
- return dnsName.equals(that.dnsName) && status.equals(that.status);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(dnsName, status);
- }
-
- @Override
- public String toString() {
- return "DnsNameStatus{" +
- "dnsName='" + dnsName + '\'' +
- ", status='" + status + '\'' +
- '}';
- }
- }
-
- private final String requestId;
- private final String requestor;
- private final String ticketId;
- private final String athenzDomain;
- private final List<DnsNameStatus> dnsNames;
- private final long durationSec;
- private final String status;
- private final String createTime; // ISO 8601
- private final long expiry;
- private final String issuer;
- private final String publicKeyAlgo;
-
- public String requestId() {
- return requestId;
- }
-
- public String requestor() {
- return requestor;
- }
-
- public String ticketId() {
- return ticketId;
- }
-
- public String athenzDomain() {
- return athenzDomain;
- }
-
- public List<DnsNameStatus> dnsNames() {
- return dnsNames;
- }
-
- public long durationSec() {
- return durationSec;
- }
-
- public String status() {
- return status;
- }
-
- public String createTime() {
- return createTime;
- }
-
- public long expiry() {
- return expiry;
- }
-
- public String issuer() {
- return issuer;
- }
-
- public String publicKeyAlgo() {
- return publicKeyAlgo;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- EndpointCertificateRequestMetadata that = (EndpointCertificateRequestMetadata) o;
- return durationSec == that.durationSec &&
- expiry == that.expiry &&
- requestId.equals(that.requestId) &&
- requestor.equals(that.requestor) &&
- ticketId.equals(that.ticketId) &&
- athenzDomain.equals(that.athenzDomain) &&
- dnsNames.equals(that.dnsNames) &&
- status.equals(that.status) &&
- createTime.equals(that.createTime) &&
- issuer.equals(that.issuer) &&
- publicKeyAlgo.equals(that.publicKeyAlgo);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(
- requestId,
- requestor,
- ticketId,
- athenzDomain,
- dnsNames,
- durationSec,
- status,
- createTime,
- expiry,
- issuer,
- publicKeyAlgo);
- }
-
- @Override
- public String toString() {
- return "EndpointCertificateRequestMetadata{" +
- "requestId='" + requestId + '\'' +
- ", requestor='" + requestor + '\'' +
- ", ticketId='" + ticketId + '\'' +
- ", athenzDomain='" + athenzDomain + '\'' +
- ", dnsNames=" + dnsNames +
- ", durationSec=" + durationSec +
- ", status='" + status + '\'' +
- ", createTime='" + createTime + '\'' +
- ", expiry=" + expiry +
- ", issuer='" + issuer + '\'' +
- ", publicKeyAlgo='" + publicKeyAlgo + '\'' +
- '}';
- }
-}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateValidator.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateValidator.java
index 0952fe587f9..b6bc8b9f129 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateValidator.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateValidator.java
@@ -5,6 +5,9 @@ import com.yahoo.config.provision.zone.ZoneId;
import java.util.List;
+/**
+ * @author andreer
+ */
public interface EndpointCertificateValidator {
- void validate(EndpointCertificateMetadata endpointCertificateMetadata, String serializedInstanceId, ZoneId zone, List<String> requiredNamesForZone);
+ void validate(EndpointCertificate endpointCertificate, String serializedInstanceId, ZoneId zone, List<String> requiredNamesForZone);
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateValidatorImpl.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateValidatorImpl.java
index cff61f1a50a..e09e2d096c2 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateValidatorImpl.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateValidatorImpl.java
@@ -31,9 +31,9 @@ public class EndpointCertificateValidatorImpl implements EndpointCertificateVali
}
@Override
- public void validate(EndpointCertificateMetadata endpointCertificateMetadata, String serializedInstanceId, ZoneId zone, List<String> requiredNamesForZone) {
+ public void validate(EndpointCertificate endpointCertificate, String serializedInstanceId, ZoneId zone, List<String> requiredNamesForZone) {
try {
- var pemEncodedEndpointCertificate = secretStore.getSecret(endpointCertificateMetadata.certName(), endpointCertificateMetadata.version());
+ var pemEncodedEndpointCertificate = secretStore.getSecret(endpointCertificate.certName(), endpointCertificate.version());
if (pemEncodedEndpointCertificate == null)
throw new EndpointCertificateException(EndpointCertificateException.Type.CERT_NOT_AVAILABLE, "Secret store returned null for certificate");
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateValidatorMock.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateValidatorMock.java
index 6bdf9037dc1..428058315c9 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateValidatorMock.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/certificates/EndpointCertificateValidatorMock.java
@@ -12,7 +12,7 @@ public class EndpointCertificateValidatorMock implements EndpointCertificateVali
@Override
public void validate(
- EndpointCertificateMetadata endpointCertificateMetadata,
+ EndpointCertificate endpointCertificate,
String serializedApplicationId,
ZoneId zone,
List<String> requiredNamesForZone) {
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepository.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepository.java
index 485bf627c87..71003b9d86e 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepository.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepository.java
@@ -55,7 +55,7 @@ public interface NodeRepository {
void upgrade(ZoneId zone, NodeType type, Version version, boolean allowDowngrade);
/** Upgrade OS for all nodes of given type to a new version */
- void upgradeOs(ZoneId zone, NodeType type, Version version);
+ void upgradeOs(ZoneId zone, NodeType type, Version version, boolean allowDowngrade);
/** Get target versions for upgrades in given zone */
TargetVersions targetVersionsOf(ZoneId zone);
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dataplanetoken/DataplaneToken.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dataplanetoken/DataplaneToken.java
index f0cc87df1fe..76df5ce13dd 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dataplanetoken/DataplaneToken.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dataplanetoken/DataplaneToken.java
@@ -1,6 +1,9 @@
// 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.dataplanetoken;
+import java.time.Instant;
+import java.util.Optional;
+
/**
* Represents a generated data plane token.
*
@@ -8,5 +11,5 @@ package com.yahoo.vespa.hosted.controller.api.integration.dataplanetoken;
*
* @author mortent
*/
-public record DataplaneToken(TokenId tokenId, FingerPrint fingerPrint, String tokenValue) {
+public record DataplaneToken(TokenId tokenId, FingerPrint fingerPrint, String tokenValue, Optional<Instant> expiration) {
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dataplanetoken/DataplaneTokenVersions.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dataplanetoken/DataplaneTokenVersions.java
index 618bfbc8a41..1ce558bd84e 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dataplanetoken/DataplaneTokenVersions.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dataplanetoken/DataplaneTokenVersions.java
@@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.controller.api.integration.dataplanetoken;
import java.time.Instant;
import java.util.List;
+import java.util.Optional;
/**
* List of dataplane token versions of a token id.
@@ -10,6 +11,7 @@ import java.util.List;
* @author mortent
*/
public record DataplaneTokenVersions(TokenId tokenId, List<Version> tokenVersions) {
- public record Version(FingerPrint fingerPrint, String checkAccessHash, Instant creationTime, String author) {
+ public record Version(FingerPrint fingerPrint, String checkAccessHash, Instant creationTime,
+ Optional<Instant> expiration, String author) {
}
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/maven/Metadata.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/maven/Metadata.java
index dd80a2b3a9a..a0d3614ffc5 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/maven/Metadata.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/maven/Metadata.java
@@ -5,9 +5,11 @@ import com.yahoo.component.Version;
import com.yahoo.text.XML;
import org.w3c.dom.Element;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
-import java.util.stream.Collectors;
import static java.util.Objects.requireNonNull;
@@ -19,10 +21,12 @@ import static java.util.Objects.requireNonNull;
public class Metadata {
private final ArtifactId id;
+ private final Instant lastUpdated;
private final List<Version> versions;
- public Metadata(ArtifactId id, List<Version> versions) {
+ public Metadata(ArtifactId id, Instant lastUpdated, List<Version> versions) {
this.id = requireNonNull(id);
+ this.lastUpdated = requireNonNull(lastUpdated);
this.versions = versions.stream().sorted().toList();
}
@@ -31,17 +35,25 @@ public class Metadata {
Element metadata = XML.getDocument(xml).getDocumentElement();
ArtifactId id = new ArtifactId(XML.getValue(XML.getChild(metadata, "groupId")),
XML.getValue(XML.getChild(metadata, "artifactId")));
+ String lastUpdatedTimestamp = XML.getValue(XML.getChild(XML.getChild(metadata, "versioning"), "lastUpdated"));
+ Instant lastUpdated = Instant.from(DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneId.of("UTC"))
+ .parse(lastUpdatedTimestamp));
List<Version> versions = new ArrayList<>();
for (Element version : XML.getChildren(XML.getChild(XML.getChild(metadata, "versioning"), "versions")))
versions.add(Version.fromString(XML.getValue(version)));
- return new Metadata(id, versions);
+ return new Metadata(id, lastUpdated, versions);
}
/** Id of the metadata this concerns. */
public ArtifactId id() { return id; }
+ /** When the list of versions was last updated. */
+ Instant lastUpdated() { return lastUpdated; }
+
/** List of available versions of this, sorted by ascending version order. */
- public List<Version> versions() { return versions; }
+ public List<Version> versions(Instant availableAt) {
+ return versions.size() == 1 || availableAt.isAfter(lastUpdated.plusSeconds(10800)) ? versions : versions.subList(0, versions.size() - 1);
+ }
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/secrets/GcpSecretStore.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/secrets/GcpSecretStore.java
index 312bec1fd98..8432a582cad 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/secrets/GcpSecretStore.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/secrets/GcpSecretStore.java
@@ -1,8 +1,14 @@
package com.yahoo.vespa.hosted.controller.api.integration.secrets;
+import java.time.Duration;
+import java.util.Optional;
+
public interface GcpSecretStore {
- void createSecret(String secretName, String secret);
+ void setSecret(String secretName, Optional<Duration> expiry, String... accessorServiceAccounts);
+
+ void addSecretVersion(String secretName, String secretValue);
+
+ String getLatestSecretVersion(String secretName);
- String getSecret(String secretName, int version);
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/secrets/NoopGcpSecretStore.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/secrets/NoopGcpSecretStore.java
index 9335a814f6c..ef35127e933 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/secrets/NoopGcpSecretStore.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/secrets/NoopGcpSecretStore.java
@@ -1,18 +1,21 @@
// 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.secrets;
+import java.time.Duration;
+import java.util.Optional;
+
/**
* @author olaa
*/
public class NoopGcpSecretStore implements GcpSecretStore {
@Override
- public void createSecret(String secretName, String secret) {
+ public void setSecret(String secretName, Optional<Duration> expiry, String... accessorServiceAccounts) { }
- }
+ @Override
+ public void addSecretVersion(String secretName, String secretValue) { }
@Override
- public String getSecret(String secretName, int version) {
- return "";
- }
+ public String getLatestSecretVersion(String secretName) { return ""; }
+
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockMavenRepository.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockMavenRepository.java
index aad6b306662..f43ec795f92 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockMavenRepository.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockMavenRepository.java
@@ -2,12 +2,17 @@
package com.yahoo.vespa.hosted.controller.api.integration.stubs;
import com.yahoo.component.Version;
+import com.yahoo.component.annotation.Inject;
import com.yahoo.vespa.hosted.controller.api.integration.maven.ArtifactId;
-import com.yahoo.vespa.hosted.controller.api.integration.maven.Metadata;
import com.yahoo.vespa.hosted.controller.api.integration.maven.MavenRepository;
+import com.yahoo.vespa.hosted.controller.api.integration.maven.Metadata;
+import java.time.Clock;
+import java.time.Instant;
+import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
/**
* Mock repository for maven artifacts, that returns a static metadata.
@@ -18,21 +23,31 @@ public class MockMavenRepository implements MavenRepository {
public static final ArtifactId id = new ArtifactId("ai.vespa", "search");
+ private final Clock clock;
+ private AtomicReference<Instant> lastUpdated;
private final List<Version> versions = new ArrayList<>();
+ @Inject
public MockMavenRepository() {
+ this(Clock.fixed(Instant.EPOCH, ZoneId.of("UTC")));
+ }
+
+ public MockMavenRepository(Clock clock) {
+ this.clock = clock;
+ this.lastUpdated = new AtomicReference<>(clock.instant().minusSeconds(10801));
versions.addAll(List.of(Version.fromString("6.0"),
Version.fromString("6.1"),
Version.fromString("6.2")));
}
public void addVersion(Version version) {
+ lastUpdated.set(clock.instant());
versions.add(version);
}
@Override
public Metadata metadata() {
- return new Metadata(id, versions);
+ return new Metadata(id, lastUpdated.get(), versions);
}
@Override
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/ChangeRequestSource.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/ChangeRequestSource.java
index e5b3422b79b..0c43a3704df 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/ChangeRequestSource.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/ChangeRequestSource.java
@@ -10,78 +10,13 @@ import static com.yahoo.vespa.hosted.controller.api.integration.vcmr.ChangeReque
/**
* @author olaa
*/
-public class ChangeRequestSource {
-
- private final String system;
- private final String id;
- private final Status status;
- private final String url;
- private final ZonedDateTime plannedStartTime;
- private final ZonedDateTime plannedEndTime;
-
-
- public ChangeRequestSource(String system, String id, String url, Status status, ZonedDateTime plannedStartTime, ZonedDateTime plannedEndTime) {
- this.system = Objects.requireNonNull(system);
- this.id = Objects.requireNonNull(id);
- this.url = Objects.requireNonNull(url);
- this.status = Objects.requireNonNull(status);
- this.plannedStartTime = Objects.requireNonNull(plannedStartTime);
- this.plannedEndTime = Objects.requireNonNull(plannedEndTime);
- }
-
- public String getSystem() {
- return system;
- }
-
- public String getId() {
- return id;
- }
-
- public Status getStatus() {
- return status;
- }
-
- public String getUrl() {
- return url;
- }
-
- public ZonedDateTime getPlannedStartTime() {
- return plannedStartTime;
- }
-
- public ZonedDateTime getPlannedEndTime() {
- return plannedEndTime;
- }
-
- @Override
- public String toString() {
- return "ChangeRequestSource{" +
- "system='" + system + '\'' +
- ", id='" + id + '\'' +
- ", status=" + status +
- ", url='" + url + '\'' +
- ", plannedStartTime=" + plannedStartTime +
- ", plannedEndTime=" + plannedEndTime +
- '}';
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- ChangeRequestSource that = (ChangeRequestSource) o;
- return Objects.equals(system, that.system) &&
- Objects.equals(id, that.id) &&
- status == that.status &&
- Objects.equals(url, that.url) &&
- Objects.equals(plannedStartTime, that.plannedStartTime) &&
- Objects.equals(plannedEndTime, that.plannedEndTime);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(system, id, status, url, plannedStartTime, plannedEndTime);
- }
+public record ChangeRequestSource(String system,
+ String id,
+ String url,
+ Status status,
+ ZonedDateTime plannedStartTime,
+ ZonedDateTime plannedEndTime,
+ String category) {
public boolean isClosed() {
return List.of(CLOSED, CANCELED, COMPLETE).contains(status);
@@ -105,6 +40,7 @@ public class ChangeRequestSource {
private Status status;
private ZonedDateTime plannedStartTime;
private ZonedDateTime plannedEndTime;
+ private String category;
public Builder system(String system) {
this.system = system;
@@ -136,8 +72,13 @@ public class ChangeRequestSource {
return this;
}
+ public Builder category(String category) {
+ this.category = category;
+ return this;
+ }
+
public ChangeRequestSource build() {
- return new ChangeRequestSource(system, id, url, status, plannedStartTime, plannedEndTime);
+ return new ChangeRequestSource(system, id, url, status, plannedStartTime, plannedEndTime, category);
}
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VcmrReport.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VcmrReport.java
index 660f3c50556..89cf6f4b28d 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VcmrReport.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VcmrReport.java
@@ -47,12 +47,12 @@ public class VcmrReport {
* @return true if list of VCMRs is changed
*/
public boolean addVcmr(ChangeRequestSource source) {
- var vcmr = new Vcmr(source.getId(), source.getStatus().name(), source.getPlannedStartTime(), source.getPlannedEndTime());
+ var vcmr = new Vcmr(source.id(), source.status().name(), source.plannedStartTime(), source.plannedEndTime(), source.category());
if (vcmrs.contains(vcmr))
return false;
// Remove to catch any changes in start/end time
- removeVcmr(source.getId());
+ removeVcmr(source.id());
return vcmrs.add(vcmr);
}
@@ -95,6 +95,7 @@ public class VcmrReport {
public record Vcmr (@JsonProperty("id") String id,
@JsonProperty("status") String status,
@JsonProperty("plannedStartTime") ZonedDateTime plannedStartTime,
- @JsonProperty("plannedEndTime") ZonedDateTime plannedEndTime) {}
+ @JsonProperty("plannedEndTime") ZonedDateTime plannedEndTime,
+ @JsonProperty("category") String category) {}
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VespaChangeRequest.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VespaChangeRequest.java
index e0f867b97be..2771520e7fc 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VespaChangeRequest.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/vcmr/VespaChangeRequest.java
@@ -3,7 +3,6 @@ package com.yahoo.vespa.hosted.controller.api.integration.vcmr;
import com.yahoo.config.provision.zone.ZoneId;
-import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java
index 1a8f4103659..6c603a1da7b 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java
@@ -38,7 +38,8 @@ enum PathGroup {
"/provision/v2/{*}",
"/zone/v2/{*}",
"/state/v1/{*}",
- "/changemanagement/v1/{*}"),
+ "/changemanagement/v1/{*}",
+ "/application/v4/search/{*}"),
/** Paths used for creating and reading user resources. */
user("/application/v4/user",
diff --git a/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/maven/MetadataTest.java b/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/maven/MetadataTest.java
index 4cec90eb48d..a6f7a5ee069 100644
--- a/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/maven/MetadataTest.java
+++ b/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/maven/MetadataTest.java
@@ -1,9 +1,12 @@
// 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.maven;
+import com.yahoo.collections.Iterables;
import com.yahoo.component.Version;
import org.junit.jupiter.api.Test;
+import java.time.Instant;
+
import static org.junit.jupiter.api.Assertions.assertEquals;
public class MetadataTest {
@@ -13,8 +16,12 @@ public class MetadataTest {
Metadata metadata = Metadata.fromXml(metadataXml);
assertEquals("com.yahoo.vespa", metadata.id().groupId());
assertEquals("tenant-base", metadata.id().artifactId());
- assertEquals(Version.fromString("6.297.80"), metadata.versions().get(0));
- assertEquals(Version.fromString("7.61.10"), metadata.versions().get(metadata.versions().size() - 1));
+ assertEquals(Instant.parse("2019-06-19T05:42:45.00Z"), metadata.lastUpdated());
+ assertEquals(Version.fromString("6.297.80"), metadata.versions(metadata.lastUpdated()).get(0));
+ assertEquals(Version.fromString("7.61.10"), Iterables.reversed(metadata.versions(metadata.lastUpdated().plusSeconds(10801)))
+ .iterator().next());
+ assertEquals(Version.fromString("7.60.51"), Iterables.reversed(metadata.versions(metadata.lastUpdated().plusSeconds(10800)))
+ .iterator().next());
}
private static final String metadataXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +