diff options
author | jonmv <venstad@gmail.com> | 2023-03-07 10:40:45 +0100 |
---|---|---|
committer | jonmv <venstad@gmail.com> | 2023-03-07 10:40:45 +0100 |
commit | d4644f2712d1196c99df925f8c24759e0a11b708 (patch) | |
tree | 03536efaf2095fd07a7f40634335d5df3da7500e | |
parent | e5e8a097195ac5866f4dffccf9fdd938b564af9f (diff) |
Normalise connection status for UI display
8 files changed, 32 insertions, 42 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 563b343dab5..39975138140 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 @@ -18,7 +18,7 @@ import java.util.concurrent.atomic.AtomicBoolean; public class MockVpcEndpointService implements VpcEndpointService { public final AtomicBoolean enabled = new AtomicBoolean(); - public final Map<RecordName, State> outcomes = new ConcurrentHashMap<>(); + public final Map<RecordName, ChallengeState> outcomes = new ConcurrentHashMap<>(); private final Clock clock; private final NameService nameService; @@ -36,20 +36,20 @@ public class MockVpcEndpointService implements VpcEndpointService { "service-id", account, clock.instant(), - State.pending); + ChallengeState.pending); return Optional.ofNullable(enabled.get() && nameService.findRecords(Type.TXT, challenge.name()).isEmpty() ? challenge : null); } @Override - public synchronized State process(DnsChallenge challenge) { + public synchronized ChallengeState 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; + return ChallengeState.done; } @Override public synchronized List<VpcEndpoint> getConnections(ClusterId cluster, Optional<CloudAccount> account) { - return List.of(new VpcEndpoint("endpoint-1", "available")); + return List.of(new VpcEndpoint("endpoint-1", "available", EndpointState.open)); } } 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 74459792987..a3ee7681e2a 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 @@ -17,7 +17,7 @@ public interface VpcEndpointService { /** 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) { + Optional<CloudAccount> account, Instant createdAt, ChallengeState state) { public DnsChallenge { requireNonNull(name, "name must be non-null"); @@ -29,22 +29,24 @@ public interface VpcEndpointService { requireNonNull(state, "state must be non-null"); } - public DnsChallenge withState(State state) { + public DnsChallenge withState(ChallengeState state) { return new DnsChallenge(name, data, clusterId, serviceId, account, createdAt, state); } } - enum State { pending, ready, running, done } + enum ChallengeState { 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); + ChallengeState process(DnsChallenge challenge); /** A connection made to an endpoint service. */ - record VpcEndpoint(String endpointId, String state) { } + record VpcEndpoint(String endpointId, String stateString, EndpointState stateValue) { } + + enum EndpointState { pending, open, failed, closed } /** Lists all endpoints connected to an endpoint service (owned by account) for the given cluster. */ List<VpcEndpoint> getConnections(ClusterId cluster, Optional<CloudAccount> account); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/DnsChallengeSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/DnsChallengeSerializer.java index 2518fe48508..bb3b2c5035f 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/DnsChallengeSerializer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/DnsChallengeSerializer.java @@ -1,18 +1,14 @@ package com.yahoo.vespa.hosted.controller.persistence; -import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.CloudAccount; -import com.yahoo.config.provision.ClusterSpec; -import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.slime.Cursor; import com.yahoo.slime.Slime; import com.yahoo.slime.SlimeUtils; import com.yahoo.vespa.hosted.controller.api.identifiers.ClusterId; -import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId; import com.yahoo.vespa.hosted.controller.api.integration.dns.RecordData; import com.yahoo.vespa.hosted.controller.api.integration.dns.RecordName; import com.yahoo.vespa.hosted.controller.api.integration.dns.VpcEndpointService.DnsChallenge; -import com.yahoo.vespa.hosted.controller.api.integration.dns.VpcEndpointService.State; +import com.yahoo.vespa.hosted.controller.api.integration.dns.VpcEndpointService.ChallengeState; import java.time.Instant; @@ -53,17 +49,17 @@ class DnsChallengeSerializer { return uncheck(() -> SlimeUtils.toJsonBytes(slime)); } - private static State toState(String value) { + private static ChallengeState toState(String value) { return switch (value) { - case "pending" -> State.pending; - case "ready" -> State.ready; - case "running" -> State.running; - case "done" -> State.done; + case "pending" -> ChallengeState.pending; + case "ready" -> ChallengeState.ready; + case "running" -> ChallengeState.running; + case "done" -> ChallengeState.done; default -> throw new IllegalArgumentException("invalid serialized state: " + value); }; } - private static String toString(State state) { + private static String toString(ChallengeState state) { return switch (state) { case pending -> "pending"; case ready -> "ready"; 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 616df377cc4..2d7dff5a891 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 @@ -2000,7 +2000,8 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler { .forEach(endpoint -> { Cursor endpointObject = endpointsArray.addObject(); endpointObject.setString("endpointId", endpoint.endpointId()); - endpointObject.setString("state", endpoint.state()); + endpointObject.setString("state", endpoint.stateValue().name()); + endpointObject.setString("detail", endpoint.stateString()); }); }); } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicies.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicies.java index 61c71e964f6..637393d71cb 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicies.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/routing/RoutingPolicies.java @@ -2,10 +2,8 @@ package com.yahoo.vespa.hosted.controller.routing; import ai.vespa.http.DomainName; -import com.yahoo.concurrent.UncheckedTimeoutException; import com.yahoo.config.application.api.DeploymentSpec; import com.yahoo.config.provision.ApplicationId; -import com.yahoo.config.provision.CloudAccount; import com.yahoo.config.provision.zone.RoutingMethod; import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.transaction.Mutex; @@ -22,7 +20,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.dns.Record.Type; import com.yahoo.vespa.hosted.controller.api.integration.dns.RecordData; import com.yahoo.vespa.hosted.controller.api.integration.dns.RecordName; import com.yahoo.vespa.hosted.controller.api.integration.dns.VpcEndpointService.DnsChallenge; -import com.yahoo.vespa.hosted.controller.api.integration.dns.VpcEndpointService.State; +import com.yahoo.vespa.hosted.controller.api.integration.dns.VpcEndpointService.ChallengeState; import com.yahoo.vespa.hosted.controller.api.integration.dns.WeightedAliasTarget; import com.yahoo.vespa.hosted.controller.api.integration.dns.WeightedDirectTarget; import com.yahoo.vespa.hosted.controller.application.Endpoint; @@ -30,13 +28,10 @@ import com.yahoo.vespa.hosted.controller.application.EndpointId; import com.yahoo.vespa.hosted.controller.application.EndpointList; import com.yahoo.vespa.hosted.controller.application.TenantAndApplicationId; import com.yahoo.vespa.hosted.controller.dns.NameServiceForwarder; -import com.yahoo.vespa.hosted.controller.dns.NameServiceQueue; import com.yahoo.vespa.hosted.controller.dns.NameServiceQueue.Priority; import com.yahoo.vespa.hosted.controller.dns.NameServiceRequest; import com.yahoo.vespa.hosted.controller.persistence.CuratorDb; -import com.yahoo.yolean.UncheckedInterruptedException; -import java.time.Instant; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -415,12 +410,12 @@ public class RoutingPolicies { .collect(Collectors.toSet()); try { challenges.removeIf(challenge -> { - if (challenge.state() == State.pending) { + if (challenge.state() == ChallengeState.pending) { if (pendingRequests.contains(challenge.name())) return false; - challenge = challenge.withState(State.ready); + challenge = challenge.withState(ChallengeState.ready); } - State state = controller.serviceRegistry().vpcEndpointService().process(challenge); - if (state == State.done) { + ChallengeState state = controller.serviceRegistry().vpcEndpointService().process(challenge); + if (state == ChallengeState.done) { removeDnsChallenge(challenge); return true; } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/DnsChallengeSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/DnsChallengeSerializerTest.java index 674cc29e91c..b224975fe05 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/DnsChallengeSerializerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/DnsChallengeSerializerTest.java @@ -9,7 +9,7 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId; import com.yahoo.vespa.hosted.controller.api.integration.dns.RecordData; import com.yahoo.vespa.hosted.controller.api.integration.dns.RecordName; import com.yahoo.vespa.hosted.controller.api.integration.dns.VpcEndpointService.DnsChallenge; -import com.yahoo.vespa.hosted.controller.api.integration.dns.VpcEndpointService.State; +import com.yahoo.vespa.hosted.controller.api.integration.dns.VpcEndpointService.ChallengeState; import org.junit.jupiter.api.Test; import java.time.Instant; @@ -32,13 +32,13 @@ class DnsChallengeSerializerTest { "deadbeef", Optional.of(CloudAccount.from("123321123321")), Instant.ofEpochMilli(123), - State.pending); + ChallengeState.pending); @Test void testSerialization() { DnsChallenge deserialized = serializer.fromJson(serializer.toJson(challenge), clusterId); assertEquals(challenge, deserialized); - for (State state : State.values()) + for (ChallengeState state : ChallengeState.values()) assertEquals(challenge.withState(state), serializer.fromJson(serializer.toJson(challenge.withState(state)), clusterId)); } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java index f1b061da58b..14771906852 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java @@ -701,7 +701,7 @@ public class ApplicationApiTest extends ControllerContainerTest { tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/private-services", GET) .userIdentity(USER_ID), """ - {"privateServices":[{"cluster":"default","serviceId":"service","type":"unknown","allowedUrns":[{"type":"aws-private-link","urn":"arne"}],"endpoints":[{"endpointId":"endpoint-1","state":"available"}]}]}"""); + {"privateServices":[{"cluster":"default","serviceId":"service","type":"unknown","allowedUrns":[{"type":"aws-private-link","urn":"arne"}],"endpoints":[{"endpointId":"endpoint-1","state":"open","detail":"available"}]}]}"""); // GET service/state/v1 tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/service/storagenode/host.com/state/v1/?foo=bar", GET) diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/RoutingPoliciesTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/RoutingPoliciesTest.java index 94cffb94184..a90d942bd09 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/RoutingPoliciesTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/routing/RoutingPoliciesTest.java @@ -9,7 +9,6 @@ import com.yahoo.config.application.api.ValidationId; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.AthenzDomain; import com.yahoo.config.provision.AthenzService; -import com.yahoo.config.provision.CloudAccount; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.HostName; @@ -25,8 +24,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.dns.Record; import com.yahoo.vespa.hosted.controller.api.integration.dns.Record.Type; import com.yahoo.vespa.hosted.controller.api.integration.dns.RecordData; import com.yahoo.vespa.hosted.controller.api.integration.dns.RecordName; -import com.yahoo.vespa.hosted.controller.api.integration.dns.VpcEndpointService.DnsChallenge; -import com.yahoo.vespa.hosted.controller.api.integration.dns.VpcEndpointService.State; +import com.yahoo.vespa.hosted.controller.api.integration.dns.VpcEndpointService.ChallengeState; import com.yahoo.vespa.hosted.controller.application.Endpoint; import com.yahoo.vespa.hosted.controller.application.EndpointId; import com.yahoo.vespa.hosted.controller.application.EndpointList; @@ -52,8 +50,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -537,7 +533,7 @@ public class RoutingPoliciesTest { tester.tester.controllerTester().serviceRegistry().vpcEndpointService().outcomes - .put(RecordName.from("challenge--a.t.aws-us-east-1a.vespa.oath.cloud"), State.running); + .put(RecordName.from("challenge--a.t.aws-us-east-1a.vespa.oath.cloud"), ChallengeState.running); // Deployment fails because challenge is not answered (immediately). assertEquals("Status of run 2 of production-aws-us-east-1a for t.a ==> expected: <succeeded> but was: <unfinished>", |