diff options
author | jonmv <venstad@gmail.com> | 2022-12-06 14:07:13 +0100 |
---|---|---|
committer | jonmv <venstad@gmail.com> | 2022-12-06 14:07:13 +0100 |
commit | 7225c5e1b7136d481c5dc104008c668859b90ff3 (patch) | |
tree | 60e9b2bfc6e9971414dd4834e46bb7c717a8e3bd | |
parent | e9df2e33f0192e0461c690146b2f8a3d85fa99cc (diff) |
Get and show vpc endpoints for clusters with service
5 files changed, 46 insertions, 18 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 e4f14c7a7b6..f101339ed06 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 @@ -4,6 +4,7 @@ import ai.vespa.http.DomainName; import com.yahoo.config.provision.CloudAccount; import com.yahoo.vespa.hosted.controller.api.identifiers.ClusterId; +import java.util.List; import java.util.Optional; /** @@ -11,13 +12,24 @@ import java.util.Optional; */ public class MockVpcEndpointService implements VpcEndpointService { - public static final VpcEndpointService empty = (name, cluster, account) -> Optional.empty(); + public interface Stub extends VpcEndpointService { + @Override default List<VpcEndpoint> getConnections(ClusterId clusterId, Optional<CloudAccount> account) { + return List.of(new VpcEndpoint("endpoint-1", "available")); + } + } + + public static final Stub empty = (name, cluster, account) -> Optional.empty(); - public VpcEndpointService delegate = empty; + public Stub delegate = empty; @Override public Optional<DnsChallenge> setPrivateDns(DomainName privateDnsName, ClusterId clusterId, Optional<CloudAccount> account) { return delegate.setPrivateDns(privateDnsName, clusterId, account); } + @Override + public 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 109b084f672..5069a429b27 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,6 +4,7 @@ import ai.vespa.http.DomainName; import com.yahoo.config.provision.CloudAccount; import com.yahoo.vespa.hosted.controller.api.identifiers.ClusterId; +import java.util.List; import java.util.Optional; /** @@ -11,10 +12,16 @@ import java.util.Optional; */ 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) { } + /** 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); - /** 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) { } + /** A connection made to an endpoint service. */ + record VpcEndpoint(String endpointId, String state) { } + + /** 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/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java index 7b9e4530aaa..001c0b8e522 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 @@ -55,6 +55,7 @@ import com.yahoo.vespa.hosted.controller.LockedTenant; import com.yahoo.vespa.hosted.controller.NotExistsException; import com.yahoo.vespa.hosted.controller.api.application.v4.EnvironmentResource; import com.yahoo.vespa.hosted.controller.api.application.v4.model.ProtonMetrics; +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.identifiers.TenantId; import com.yahoo.vespa.hosted.controller.api.integration.aws.TenantRoles; @@ -73,6 +74,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType; import com.yahoo.vespa.hosted.controller.api.integration.deployment.RevisionId; import com.yahoo.vespa.hosted.controller.api.integration.deployment.RunId; import com.yahoo.vespa.hosted.controller.api.integration.deployment.SourceRevision; +import com.yahoo.vespa.hosted.controller.api.integration.dns.VpcEndpointService.VpcEndpoint; import com.yahoo.vespa.hosted.controller.api.integration.noderepository.RestartFilter; import com.yahoo.vespa.hosted.controller.api.integration.secrets.TenantSecretStore; import com.yahoo.vespa.hosted.controller.api.role.Role; @@ -1963,16 +1965,26 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler { } private HttpResponse getPrivateServiceInfo(String tenantName, String applicationName, String instanceName, String environment, String region) { - List<LoadBalancer> lbs = controller.serviceRegistry().configServer().getLoadBalancers(ApplicationId.from(tenantName, applicationName, instanceName), - ZoneId.from(environment, region)); + DeploymentId id = new DeploymentId(ApplicationId.from(tenantName, applicationName, instanceName), + ZoneId.from(environment, region)); + List<LoadBalancer> lbs = controller.serviceRegistry().configServer().getLoadBalancers(id.applicationId(), id.zoneId()); Slime slime = new Slime(); Cursor lbArray = slime.setObject().setArray("loadBalancers"); for (LoadBalancer lb : lbs) { Cursor lbObject = lbArray.addObject(); lbObject.setString("cluster", lb.cluster().value()); lb.service().ifPresent(service -> { - lbObject.setString("serviceId", service.id()); + lbObject.setString("serviceId", service.id()); // Really the "serviceName", but this is what the user needs >_< service.allowedUrns().forEach(lbObject.setArray("allowedUrns")::addString); + Cursor endpointsArray = lbObject.setArray("endpoints"); + controller.serviceRegistry().vpcEndpointService() + .getConnections(new ClusterId(id, lb.cluster()), + controller.applications().decideCloudAccountOf(id, controller.applications().requireApplication(TenantAndApplicationId.from(tenantName, applicationName)).deploymentSpec())) + .forEach(endpoint -> { + Cursor endpointObject = endpointsArray.addObject(); + endpointObject.setString("endpointId", endpoint.endpointId()); + endpointObject.setString("state", endpoint.state()); + }); }); } return new SlimeJsonResponse(slime); 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 0c9f290c257..40d96f716ae 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 @@ -700,7 +700,8 @@ public class ApplicationApiTest extends ControllerContainerTest { // GET private service info tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/environment/prod/region/us-central-1/private-service", GET) .userIdentity(USER_ID), - "{\"loadBalancers\":[{\"cluster\":\"default\",\"serviceId\":\"service\",\"allowedUrns\":[\"arne\"]}]}"); + """ + {"loadBalancers":[{"cluster":"default","serviceId":"service","allowedUrns":["arne"],"endpoints":[{"endpointId":"endpoint-1","state":"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 edf53090e50..da9ea3babe2 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 @@ -25,7 +25,6 @@ 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; import com.yahoo.vespa.hosted.controller.api.integration.dns.VpcEndpointService.DnsChallenge; import com.yahoo.vespa.hosted.controller.application.Endpoint; import com.yahoo.vespa.hosted.controller.application.EndpointId; @@ -52,8 +51,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.TreeSet; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; @@ -518,13 +515,12 @@ public class RoutingPoliciesTest { // Challenge answered for endpoint RoutingPoliciesTester tester = new RoutingPoliciesTester(); Map<RecordName, RecordData> challenges = new ConcurrentHashMap<>(); - tester.tester.controllerTester().serviceRegistry().vpcEndpointService().delegate = - (name, cluster, account) -> { - RecordName recordName = RecordName.from("challenge--" + name.value()); - if (challenges.containsKey(recordName)) return Optional.empty(); - RecordData recordData = RecordData.from(account.map(CloudAccount::value).orElse("system")); - return Optional.of(new DnsChallenge(recordName, recordData, () -> challenges.put(recordName, recordData))); - }; + tester.tester.controllerTester().serviceRegistry().vpcEndpointService().delegate = (name, cluster, account) -> { + RecordName recordName = RecordName.from("challenge--" + name.value()); + if (challenges.containsKey(recordName)) return Optional.empty(); + RecordData recordData = RecordData.from(account.map(CloudAccount::value).orElse("system")); + return Optional.of(new DnsChallenge(recordName, recordData, () -> challenges.put(recordName, recordData))); + }; DeploymentContext app = tester.newDeploymentContext("t", "a", "default"); ApplicationPackage appPackage = applicationPackageBuilder().region(zone3.region()).build(); |