diff options
9 files changed, 1 insertions, 311 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/ServiceRegistry.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/ServiceRegistry.java index 52f687e5708..c0adb7389c8 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/ServiceRegistry.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/ServiceRegistry.java @@ -7,7 +7,6 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.ControllerVersion; import com.yahoo.vespa.hosted.controller.api.integration.archive.ArchiveService; import com.yahoo.vespa.hosted.controller.api.integration.artifact.ArtifactRegistry; import com.yahoo.vespa.hosted.controller.api.integration.athenz.AccessControlService; -import com.yahoo.vespa.hosted.controller.api.integration.aws.CloudEventFetcher; import com.yahoo.vespa.hosted.controller.api.integration.aws.ResourceTagger; import com.yahoo.vespa.hosted.controller.api.integration.aws.RoleService; import com.yahoo.vespa.hosted.controller.api.integration.billing.BillingController; @@ -77,8 +76,6 @@ public interface ServiceRegistry { CostReportConsumer costReportConsumer(); - CloudEventFetcher eventFetcherService(); - ArtifactRepository artifactRepository(); TesterCloud testerCloud(); diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/CloudEvent.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/CloudEvent.java deleted file mode 100644 index b5445791bf0..00000000000 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/CloudEvent.java +++ /dev/null @@ -1,36 +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.aws; - -import java.util.Date; -import java.util.Optional; -import java.util.Set; - -/** - * A maintenance event in a cloud service. - * - * @author freva - */ -public class CloudEvent { - - public final String instanceEventId; - public final String code; - public final String description; - public final Optional<Date> notBefore; - public final Optional<Date> notBeforeDeadline; - public final Optional<Date> notAfter; - public final String awsRegionName; - public final Set<String> affectedInstances; - - public CloudEvent(String instanceEventId, String code, String description, Date notAfter, Date notBefore, - Date notBeforeDeadline, String awsRegionName, Set<String> affectedInstances) { - this.instanceEventId = instanceEventId; - this.code = code; - this.description = description; - this.notBefore = Optional.ofNullable(notBefore); - this.notBeforeDeadline = Optional.ofNullable(notBeforeDeadline); - this.notAfter = Optional.ofNullable(notAfter); - this.awsRegionName = awsRegionName; - this.affectedInstances = Set.copyOf(affectedInstances); - } - -} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/CloudEventFetcher.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/CloudEventFetcher.java deleted file mode 100644 index 0d08a5a8cb6..00000000000 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/CloudEventFetcher.java +++ /dev/null @@ -1,13 +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.aws; - -import java.util.List; - -/** - * @author freva - */ -public interface CloudEventFetcher { - - List<CloudEvent> getEvents(String regionName); - -} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/MockCloudEventFetcher.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/MockCloudEventFetcher.java deleted file mode 100644 index 3300d8879ce..00000000000 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/MockCloudEventFetcher.java +++ /dev/null @@ -1,25 +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.aws; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author freva - */ -public class MockCloudEventFetcher implements CloudEventFetcher { - - private final Map<String, List<CloudEvent>> mockedEvents = new HashMap<>(); - - @Override - public List<CloudEvent> getEvents(String regionName) { - return mockedEvents.getOrDefault(regionName, new ArrayList<>()); - } - - public void addEvent(String regionName, CloudEvent cloudEvent) { - mockedEvents.computeIfAbsent(regionName, i -> new ArrayList<>()).add(cloudEvent); - } - -} diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CloudEventTracker.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CloudEventTracker.java deleted file mode 100644 index 021c02fb6a0..00000000000 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CloudEventTracker.java +++ /dev/null @@ -1,77 +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.maintenance; - -import com.yahoo.config.provision.CloudName; -import com.yahoo.config.provision.zone.ZoneApi; -import com.yahoo.vespa.hosted.controller.Controller; -import com.yahoo.vespa.hosted.controller.api.integration.aws.CloudEvent; -import com.yahoo.vespa.hosted.controller.api.integration.aws.CloudEventFetcher; -import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node; -import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeFilter; -import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeRepository; - -import java.time.Duration; -import java.util.List; -import java.util.Map; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -/** - * This tracks maintenance events from cloud providers and deprovisions any affected hosts. - * - * @author mgimle - */ -public class CloudEventTracker extends ControllerMaintainer { - - private static final Logger log = Logger.getLogger(CloudEventTracker.class.getName()); - - private final CloudEventFetcher eventFetcher; - private final Map<String, List<ZoneApi>> zonesByCloudNativeRegion; - private final NodeRepository nodeRepository; - - CloudEventTracker(Controller controller, Duration interval) { - super(controller, interval); - this.eventFetcher = controller.serviceRegistry().eventFetcherService(); - this.nodeRepository = controller.serviceRegistry().configServer().nodeRepository(); - this.zonesByCloudNativeRegion = supportedZonesByRegion(); - } - - @Override - protected double maintain() { - for (var region : zonesByCloudNativeRegion.keySet()) { - for (var event : eventFetcher.getEvents(region)) { - deprovisionAffectedHosts(region, event); - } - } - return 1.0; - } - - /** Deprovision any host affected by given event */ - private void deprovisionAffectedHosts(String region, CloudEvent event) { - for (var zone : zonesByCloudNativeRegion.get(region)) { - for (var node : nodeRepository.list(zone.getId(), NodeFilter.all())) { - if (!deprovision(node, event)) continue; - log.info("Retiring and deprovisioning " + node.hostname().value() + " in " + zone.getId() + - ": Affected by maintenance event " + event.instanceEventId); - nodeRepository.retire(zone.getId(), node.hostname().value(), true, true); - } - } - } - - private static boolean deprovision(Node node, CloudEvent event) { - if (!node.type().isHost()) return false; // Non-hosts are never affected - if (node.wantToRetire() && node.wantToDeprovision()) return false; // Already deprovisioning - return event.affectedInstances.stream() - .anyMatch(instance -> node.hostname().value().contains(instance)); - } - - /** Returns zones supported by this, grouped by their native region name */ - private Map<String, List<ZoneApi>> supportedZonesByRegion() { - return controller().zoneRegistry().zones() - .ofCloud(CloudName.from("aws")) - .reachable() - .zones().stream() - .collect(Collectors.groupingBy(ZoneApi::getCloudNativeRegionName)); - } - -} diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ControllerMaintenance.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ControllerMaintenance.java index 193d171e334..795f14bbde1 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ControllerMaintenance.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ControllerMaintenance.java @@ -59,7 +59,6 @@ public class ControllerMaintenance extends AbstractComponent { maintainers.add(new NameServiceDispatcher(controller, intervals.nameServiceDispatcher)); maintainers.add(new CostReportMaintainer(controller, intervals.costReportMaintainer, controller.serviceRegistry().costReportConsumer())); maintainers.add(new ResourceMeterMaintainer(controller, intervals.resourceMeterMaintainer, metric, controller.serviceRegistry().meteringService())); - maintainers.add(new CloudEventTracker(controller, intervals.cloudEventReporter)); maintainers.add(new ResourceTagMaintainer(controller, intervals.resourceTagMaintainer, controller.serviceRegistry().resourceTagger())); maintainers.add(new SystemRoutingPolicyMaintainer(controller, intervals.systemRoutingPolicyMaintainer)); maintainers.add(new ApplicationMetaDataGarbageCollector(controller, intervals.applicationMetaDataGarbageCollector)); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ServiceRegistryMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ServiceRegistryMock.java index a91d81bb0c5..596335baeb5 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ServiceRegistryMock.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ServiceRegistryMock.java @@ -1,10 +1,10 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.controller.integration; -import com.yahoo.component.annotation.Inject; import com.yahoo.cloud.config.ConfigserverConfig; import com.yahoo.component.AbstractComponent; import com.yahoo.component.Version; +import com.yahoo.component.annotation.Inject; import com.yahoo.config.provision.CloudName; import com.yahoo.config.provision.HostName; import com.yahoo.config.provision.SystemName; @@ -15,7 +15,6 @@ import com.yahoo.vespa.hosted.controller.api.integration.archive.ArchiveService; import com.yahoo.vespa.hosted.controller.api.integration.archive.MockArchiveService; import com.yahoo.vespa.hosted.controller.api.integration.athenz.AccessControlService; import com.yahoo.vespa.hosted.controller.api.integration.athenz.MockAccessControlService; -import com.yahoo.vespa.hosted.controller.api.integration.aws.MockCloudEventFetcher; import com.yahoo.vespa.hosted.controller.api.integration.aws.MockResourceTagger; import com.yahoo.vespa.hosted.controller.api.integration.aws.MockRoleService; import com.yahoo.vespa.hosted.controller.api.integration.aws.ResourceTagger; @@ -76,7 +75,6 @@ public class ServiceRegistryMock extends AbstractComponent implements ServiceReg private final MemoryEntityService memoryEntityService = new MemoryEntityService(); private final DummySystemMonitor systemMonitor = new DummySystemMonitor(); private final CostReportConsumerMock costReportConsumerMock = new CostReportConsumerMock(); - private final MockCloudEventFetcher mockAwsEventFetcher = new MockCloudEventFetcher(); private final ArtifactRepositoryMock artifactRepositoryMock = new ArtifactRepositoryMock(); private final MockTesterCloud mockTesterCloud; private final ApplicationStoreMock applicationStoreMock = new ApplicationStoreMock(); @@ -183,11 +181,6 @@ public class ServiceRegistryMock extends AbstractComponent implements ServiceReg } @Override - public MockCloudEventFetcher eventFetcherService() { - return mockAwsEventFetcher; - } - - @Override public ArtifactRepositoryMock artifactRepository() { return artifactRepositoryMock; } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CloudEventTrackerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CloudEventTrackerTest.java deleted file mode 100644 index 6ccd307f0d9..00000000000 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/CloudEventTrackerTest.java +++ /dev/null @@ -1,145 +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.maintenance; - -import com.yahoo.config.provision.HostName; -import com.yahoo.config.provision.NodeType; -import com.yahoo.config.provision.zone.ZoneId; -import com.yahoo.vespa.hosted.controller.ControllerTester; -import com.yahoo.vespa.hosted.controller.api.integration.aws.CloudEvent; -import com.yahoo.vespa.hosted.controller.api.integration.aws.MockCloudEventFetcher; -import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node; -import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeFilter; -import com.yahoo.vespa.hosted.controller.integration.ZoneApiMock; -import org.junit.Test; - -import java.time.Duration; -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import static org.junit.Assert.assertEquals; - -/** - * @author olaa - */ -public class CloudEventTrackerTest { - - private final ControllerTester tester = new ControllerTester(); - private final ZoneApiMock unsupportedZone = createZone("prod.zone3", "region-1", "other"); - private final ZoneApiMock zone1 = createZone("prod.zone1", "region-1", "aws"); - private final ZoneApiMock zone2 = createZone("prod.zone2", "region-2", "aws"); - - /** - * Test scenario: Consider three zones, two of which are supported - * - * We want to test the following: - * 1. Unsupported zone is completely ignored - * 2. Hosts affected by cloud event are deprovisioned - */ - @Test - public void maintain() { - setUpZones(); - CloudEventTracker cloudEventTracker = new CloudEventTracker(tester.controller(), Duration.ofMinutes(15)); - assertEquals(Set.of("host1.com", "host2.com", "host3.com"), hostsNotDeprovisioning(unsupportedZone.getId())); - assertEquals(Set.of("host1.com", "host2.com", "host3.com"), hostsNotDeprovisioning(zone1.getId())); - assertEquals(Set.of("host4.com", "host5.com", "confighost.com"), hostsNotDeprovisioning(zone2.getId())); - - mockEvents(); - cloudEventTracker.maintain(); - assertEquals(Set.of("host1.com", "host2.com", "host3.com"), hostsNotDeprovisioning(unsupportedZone.getId())); - assertEquals(Set.of("host3.com"), hostsNotDeprovisioning(zone1.getId())); - assertEquals(Set.of("host4.com"), hostsNotDeprovisioning(zone2.getId())); - } - - private void mockEvents() { - MockCloudEventFetcher eventFetcher = (MockCloudEventFetcher) tester.controller().serviceRegistry().eventFetcherService(); - - Date date = new Date(); - CloudEvent event1 = new CloudEvent("event 1", - "instance code", - "description", - date, - date, - date, - "region-1", - Set.of("host1", "host2")); - - CloudEvent event2 = new CloudEvent("event 2", - "instance code", - "description", - date, - date, - date, - "region-2", - Set.of("host5", "confighost")); - - eventFetcher.addEvent("region-1", event1); - eventFetcher.addEvent("region-2", event2); - } - - private void setUpZones() { - tester.zoneRegistry().setZones( - unsupportedZone, - zone1, - zone2); - - tester.configServer().nodeRepository().putNodes( - unsupportedZone.getId(), - createNodesWithHostnames( - "host1.com", - "host2.com", - "host3.com" - ) - ); - tester.configServer().nodeRepository().putNodes( - zone1.getId(), - createNodesWithHostnames( - "host1.com", - "host2.com", - "host3.com" - ) - ); - tester.configServer().nodeRepository().putNodes( - zone2.getId(), - createNodesWithHostnames( - "host4.com", - "host5.com" - ) - ); - tester.configServer().nodeRepository().putNodes( - zone2.getId(), - List.of(createNode("confighost.com", NodeType.confighost)) - ); - } - - private List<Node> createNodesWithHostnames(String... hostnames) { - return Arrays.stream(hostnames) - .map(hostname -> createNode(hostname, NodeType.host)) - .collect(Collectors.toUnmodifiableList()); - } - - private Node createNode(String hostname, NodeType nodeType) { - return Node.builder() - .hostname(HostName.of(hostname)) - .type(nodeType) - .build(); - } - - private Set<String> hostsNotDeprovisioning(ZoneId zoneId) { - return tester.configServer().nodeRepository().list(zoneId, NodeFilter.all()) - .stream() - .filter(node -> !node.wantToDeprovision()) - .map(node -> node.hostname().value()) - .collect(Collectors.toSet()); - } - - private ZoneApiMock createZone(String zoneId, String cloudNativeRegionName, String cloud) { - return ZoneApiMock.newBuilder().withId(zoneId) - .withCloudNativeRegionName(cloudNativeRegionName) - .withCloud(cloud) - .build(); - } - -} diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/maintenance.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/maintenance.json index 8b2e5578ae0..7110cbbd738 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/maintenance.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/maintenance.json @@ -22,9 +22,6 @@ "name": "ChangeRequestMaintainer" }, { - "name": "CloudEventTracker" - }, - { "name": "CloudTrialExpirer" }, { |