aboutsummaryrefslogtreecommitdiffstats
path: root/controller-api
diff options
context:
space:
mode:
authorjonmv <venstad@gmail.com>2023-02-01 16:27:48 +0100
committerjonmv <venstad@gmail.com>2023-02-01 16:27:48 +0100
commit4f76988e35d72006f29db1ba16e9610d70fe4864 (patch)
tree899ee2d768f690a755971a5e60ccd1ddb0266a3b /controller-api
parentf6fdb2f2a5385881af69de5e760c11bc4ddae7c1 (diff)
Run DNS challenges asynchronously, and check from job runner
Diffstat (limited to 'controller-api')
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/MockVpcEndpointService.java40
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/VpcEndpointService.java29
2 files changed, 57 insertions, 12 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/MockVpcEndpointService.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/MockVpcEndpointService.java
index f101339ed06..563b343dab5 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/MockVpcEndpointService.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/MockVpcEndpointService.java
@@ -3,32 +3,52 @@ package com.yahoo.vespa.hosted.controller.api.integration.dns;
import ai.vespa.http.DomainName;
import com.yahoo.config.provision.CloudAccount;
import com.yahoo.vespa.hosted.controller.api.identifiers.ClusterId;
+import com.yahoo.vespa.hosted.controller.api.integration.dns.Record.Type;
+import java.time.Clock;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author jonmv
*/
public class MockVpcEndpointService implements VpcEndpointService {
- public interface Stub extends VpcEndpointService {
- @Override default List<VpcEndpoint> getConnections(ClusterId clusterId, Optional<CloudAccount> account) {
- return List.of(new VpcEndpoint("endpoint-1", "available"));
- }
- }
+ public final AtomicBoolean enabled = new AtomicBoolean();
+ public final Map<RecordName, State> outcomes = new ConcurrentHashMap<>();
+
+ private final Clock clock;
+ private final NameService nameService;
- public static final Stub empty = (name, cluster, account) -> Optional.empty();
+ public MockVpcEndpointService(Clock clock, NameService nameService) {
+ this.clock = clock;
+ this.nameService = nameService;
+ }
- public Stub delegate = empty;
+ @Override
+ public synchronized Optional<DnsChallenge> setPrivateDns(DomainName privateDnsName, ClusterId clusterId, Optional<CloudAccount> account) {
+ DnsChallenge challenge = new DnsChallenge(RecordName.from("challenge--" + privateDnsName.value()),
+ RecordData.from(account.map(CloudAccount::value).orElse("system")),
+ clusterId,
+ "service-id",
+ account,
+ clock.instant(),
+ State.pending);
+ return Optional.ofNullable(enabled.get() && nameService.findRecords(Type.TXT, challenge.name()).isEmpty() ? challenge : null);
+ }
@Override
- public Optional<DnsChallenge> setPrivateDns(DomainName privateDnsName, ClusterId clusterId, Optional<CloudAccount> account) {
- return delegate.setPrivateDns(privateDnsName, clusterId, account);
+ public synchronized State process(DnsChallenge challenge) {
+ if (outcomes.containsKey(challenge.name())) return outcomes.get(challenge.name());
+ if (nameService.findRecords(Type.TXT, challenge.name()).isEmpty()) throw new RuntimeException("No TXT record found for " + challenge.name());
+ return State.done;
}
@Override
- public List<VpcEndpoint> getConnections(ClusterId cluster, Optional<CloudAccount> account) {
+ public synchronized List<VpcEndpoint> getConnections(ClusterId cluster, Optional<CloudAccount> account) {
return List.of(new VpcEndpoint("endpoint-1", "available"));
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/VpcEndpointService.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/VpcEndpointService.java
index 5069a429b27..74459792987 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/VpcEndpointService.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/VpcEndpointService.java
@@ -4,20 +4,45 @@ import ai.vespa.http.DomainName;
import com.yahoo.config.provision.CloudAccount;
import com.yahoo.vespa.hosted.controller.api.identifiers.ClusterId;
+import java.time.Instant;
import java.util.List;
import java.util.Optional;
+import static java.util.Objects.requireNonNull;
+
/**
* @author jonmv
*/
public interface VpcEndpointService {
- /** Create a TXT record with this name and token, then run the trigger, to pass this challenge. */
- record DnsChallenge(RecordName name, RecordData data, Runnable trigger) { }
+ /** Create a TXT record with this name and token, and then complete the challenge. */
+ record DnsChallenge(RecordName name, RecordData data, ClusterId clusterId, String serviceId,
+ Optional<CloudAccount> account, Instant createdAt, State state) {
+
+ public DnsChallenge {
+ requireNonNull(name, "name must be non-null");
+ requireNonNull(data, "data must be non-null");
+ requireNonNull(clusterId, "clusterId must be non-null");
+ requireNonNull(serviceId, "serviceId must be non-null");
+ requireNonNull(account, "account must be non-null");
+ requireNonNull(createdAt, "createdAt must be non-null");
+ requireNonNull(state, "state must be non-null");
+ }
+
+ public DnsChallenge withState(State state) {
+ return new DnsChallenge(name, data, clusterId, serviceId, account, createdAt, state);
+ }
+
+ }
+
+ enum State { pending, ready, running, done }
/** Sets the private DNS name for any VPC endpoint for the given cluster, potentially guarded by a challenge. */
Optional<DnsChallenge> setPrivateDns(DomainName privateDnsName, ClusterId clusterId, Optional<CloudAccount> account);
+ /** Attempts to complete the challenge, and returns the updated challenge state. */
+ State process(DnsChallenge challenge);
+
/** A connection made to an endpoint service. */
record VpcEndpoint(String endpointId, String state) { }