From 3642b85d61e219809f79689f392f3dc78d18be0d Mon Sep 17 00:00:00 2001 From: Ola Aunrønning Date: Wed, 21 Oct 2020 13:41:52 +0200 Subject: Create maintainer tracking host repair status Extended ZmsClient to add/delete policy rules Extended controller's node repo client with patchNode function --- .../api/integration/ServiceRegistry.java | 2 + .../api/integration/athenz/ZmsClientMock.java | 11 +++++ .../api/integration/configserver/Node.java | 15 +++++- .../integration/configserver/NodeRepository.java | 5 +- .../api/integration/repair/HostRepairClient.java | 19 ++++++++ .../api/integration/repair/MockRepairClient.java | 26 ++++++++++ .../api/integration/repair/RepairTicketReport.java | 56 ++++++++++++++++++++++ .../api/integration/repair/package-info.java | 5 ++ 8 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/HostRepairClient.java create mode 100644 controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/MockRepairClient.java create mode 100644 controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/RepairTicketReport.java create mode 100644 controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/package-info.java (limited to 'controller-api') 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 a522e26a46d..7b4d82a9f53 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 @@ -18,6 +18,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueHandl import com.yahoo.vespa.hosted.controller.api.integration.organization.Mailer; import com.yahoo.vespa.hosted.controller.api.integration.organization.OwnershipIssues; import com.yahoo.vespa.hosted.controller.api.integration.organization.SystemMonitor; +import com.yahoo.vespa.hosted.controller.api.integration.repair.HostRepairClient; import com.yahoo.vespa.hosted.controller.api.integration.resource.CostReportConsumer; import com.yahoo.vespa.hosted.controller.api.integration.resource.MeteringClient; import com.yahoo.vespa.hosted.controller.api.integration.routing.GlobalRoutingService; @@ -79,4 +80,5 @@ public interface ServiceRegistry { BillingController billingController(); + HostRepairClient hostRepairClient(); } 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 ec5d62569f6..942f0f35f58 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 @@ -135,6 +135,17 @@ public class ZmsClientMock implements ZmsClient { } } + @Override + public void addPolicyRule(AthenzDomain athenzDomain, String athenzPolicy, String action, AthenzResourceName resourceName, AthenzRole athenzRole) { + + } + + @Override + public boolean deletePolicyRule(AthenzDomain athenzDomain, String athenzPolicy, String action, AthenzResourceName resourceName, AthenzRole athenzRole) { + return false; + } + + @Override public void close() {} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Node.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Node.java index 07e411cd5cd..b57b2dbc496 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Node.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Node.java @@ -1,6 +1,7 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.controller.api.integration.configserver; +import com.fasterxml.jackson.databind.JsonNode; import com.yahoo.component.Version; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.DockerImage; @@ -10,6 +11,8 @@ import com.yahoo.config.provision.NodeType; import com.yahoo.config.provision.TenantName; import java.time.Instant; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -48,13 +51,14 @@ public class Node { private final boolean wantToRetire; private final boolean wantToDeprovision; private final Optional reservedTo; + private final Map reports; public Node(HostName hostname, Optional parentHostname, State state, NodeType type, NodeResources resources, Optional owner, Version currentVersion, Version wantedVersion, Version currentOsVersion, Version wantedOsVersion, Optional currentFirmwareCheck, Optional wantedFirmwareCheck, ServiceState serviceState, Optional suspendedSince, long restartGeneration, long wantedRestartGeneration, long rebootGeneration, long wantedRebootGeneration, int cost, String flavor, String clusterId, ClusterType clusterType, boolean wantToRetire, boolean wantToDeprovision, - Optional reservedTo, DockerImage wantedDockerImage, DockerImage currentDockerImage) { + Optional reservedTo, DockerImage wantedDockerImage, DockerImage currentDockerImage, Map reports) { this.hostname = hostname; this.parentHostname = parentHostname; this.state = state; @@ -82,6 +86,7 @@ public class Node { this.reservedTo = reservedTo; this.wantedDockerImage = wantedDockerImage; this.currentDockerImage = currentDockerImage; + this.reports = reports; } public HostName hostname() { @@ -188,6 +193,10 @@ public class Node { public Optional reservedTo() { return reservedTo; } + public Map reports() { + return reports; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -258,6 +267,7 @@ public class Node { private boolean wantToRetire; private boolean wantToDeprovision; private Optional reservedTo = Optional.empty(); + private Map reports = new HashMap<>(); public Builder() { } @@ -289,6 +299,7 @@ public class Node { this.wantToRetire = node.wantToRetire; this.wantToDeprovision = node.wantToDeprovision; this.reservedTo = node.reservedTo; + this.reports = node.reports; } public Builder hostname(HostName hostname) { @@ -431,7 +442,7 @@ public class Node { currentOsVersion, wantedOsVersion, currentFirmwareCheck, wantedFirmwareCheck, serviceState, suspendedSince, restartGeneration, wantedRestartGeneration, rebootGeneration, wantedRebootGeneration, cost, flavor, clusterId, clusterType, wantToRetire, wantToDeprovision, reservedTo, - wantedDockerImage, currentDockerImage); + wantedDockerImage, currentDockerImage, reports); } } 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 aebfab7cbff..6f4b39ac9b9 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 @@ -90,6 +90,8 @@ public interface NodeRepository { void retireAndDeprovision(ZoneId zoneId, String hostName); + void patchNode(ZoneId zoneId, String hostName, NodeRepositoryNode node); + private static Node toNode(NodeRepositoryNode node) { var application = Optional.ofNullable(node.getOwner()) .map(owner -> ApplicationId.from(owner.getTenant(), owner.getApplication(), @@ -128,7 +130,8 @@ public interface NodeRepository { node.getWantToDeprovision(), Optional.ofNullable(node.getReservedTo()).map(TenantName::from), dockerImageFrom(node.getWantedDockerImage()), - dockerImageFrom(node.getCurrentDockerImage())); + dockerImageFrom(node.getCurrentDockerImage()), + node.getReports()); } private static String clusterIdOf(NodeMembership nodeMembership) { diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/HostRepairClient.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/HostRepairClient.java new file mode 100644 index 00000000000..e79928f59d4 --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/HostRepairClient.java @@ -0,0 +1,19 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.api.integration.repair; + +import com.yahoo.config.provision.zone.ZoneApi; +import com.yahoo.config.provision.zone.ZoneId; +import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node; + +import java.util.List; +import java.util.Map; + +/** + * @author olaa + */ +public interface HostRepairClient { + + /* Checks current ticket status and takes appropriate action */ + void updateRepairStatus(ZoneApi zone, Map nodes); + +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/MockRepairClient.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/MockRepairClient.java new file mode 100644 index 00000000000..307ba7408c5 --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/MockRepairClient.java @@ -0,0 +1,26 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.api.integration.repair; + +import com.yahoo.config.provision.zone.ZoneApi; +import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author olaa + */ +public class MockRepairClient implements HostRepairClient { + + List updatedNodes = new ArrayList<>(); + + @Override + public void updateRepairStatus(ZoneApi zone, Map nodes) { + updatedNodes.addAll(nodes.keySet()); + } + + public List getUpdatedNodes() { + return updatedNodes; + } +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/RepairTicketReport.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/RepairTicketReport.java new file mode 100644 index 00000000000..c44e00706e2 --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/RepairTicketReport.java @@ -0,0 +1,56 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.api.integration.repair; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import static com.yahoo.yolean.Exceptions.uncheck; + +/** + * @author olaa + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class RepairTicketReport { + + private static final String REPORT_ID = "repair-ticket"; + private static final ObjectMapper objectMapper = new ObjectMapper();@JsonIgnore + + public String status; + public String ticketNumber; + public long createdMillis; + + public RepairTicketReport(@JsonProperty("status") String status, + @JsonProperty("ticketNumber") String ticketNumber, + @JsonProperty("createdMillis") long createdMillis) { + this.status = status; + this.ticketNumber = ticketNumber; + this.createdMillis = createdMillis; + } + + public String getStatus() { + return status; + } + + public String getTicketNumber() { + return ticketNumber; + } + + public long getCreatedMillis() { + return createdMillis; + } + + public static String getReportId() { + return REPORT_ID; + } + + public static RepairTicketReport fromJsonNode(JsonNode node) { + return uncheck(() -> objectMapper.treeToValue(node, RepairTicketReport.class)); + } + + public JsonNode toJsonNode() { + return uncheck(() -> objectMapper.valueToTree(this)); + } +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/package-info.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/package-info.java new file mode 100644 index 00000000000..f53cb1ee43c --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/package-info.java @@ -0,0 +1,5 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +@ExportPackage +package com.yahoo.vespa.hosted.controller.api.integration.repair; + +import com.yahoo.osgi.annotation.ExportPackage; -- cgit v1.2.3 From 85609870b4efb0029c202ef2730547f8c3faa32f Mon Sep 17 00:00:00 2001 From: Ola Aunrønning Date: Fri, 23 Oct 2020 15:56:23 +0200 Subject: Add lastUpdated field to report. Report ID uses camel case. Remove unnecessary JsonIgnore. Reverse String comparison --- .../api/integration/repair/RepairTicketReport.java | 13 ++++++++++--- .../hosted/controller/maintenance/HostRepairMaintainer.java | 2 +- .../controller/maintenance/HostRepairMaintainerTest.java | 6 ++++-- 3 files changed, 15 insertions(+), 6 deletions(-) (limited to 'controller-api') diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/RepairTicketReport.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/RepairTicketReport.java index c44e00706e2..c2425fe0f72 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/RepairTicketReport.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/repair/RepairTicketReport.java @@ -15,19 +15,22 @@ import static com.yahoo.yolean.Exceptions.uncheck; @JsonIgnoreProperties(ignoreUnknown = true) public class RepairTicketReport { - private static final String REPORT_ID = "repair-ticket"; - private static final ObjectMapper objectMapper = new ObjectMapper();@JsonIgnore + private static final String REPORT_ID = "repairTicket"; + private static final ObjectMapper objectMapper = new ObjectMapper(); public String status; public String ticketNumber; public long createdMillis; + public long updatedMillis; public RepairTicketReport(@JsonProperty("status") String status, @JsonProperty("ticketNumber") String ticketNumber, - @JsonProperty("createdMillis") long createdMillis) { + @JsonProperty("createdMillis") long createdMillis, + @JsonProperty("updatedMillis") long updatedMillis) { this.status = status; this.ticketNumber = ticketNumber; this.createdMillis = createdMillis; + this.updatedMillis = updatedMillis; } public String getStatus() { @@ -42,6 +45,10 @@ public class RepairTicketReport { return createdMillis; } + public long getUpdatedMillis() { + return updatedMillis; + } + public static String getReportId() { return REPORT_ID; } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/HostRepairMaintainer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/HostRepairMaintainer.java index c3c5f902dff..e3c6862384f 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/HostRepairMaintainer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/HostRepairMaintainer.java @@ -72,7 +72,7 @@ public class HostRepairMaintainer extends ControllerMaintainer { if (!reports.containsKey(RepairTicketReport.getReportId())) { return false; } - return getTicketReport(node).getStatus().equals("OPEN"); + return "OPEN".equals(getTicketReport(node).getStatus()); } private RepairTicketReport getTicketReport(Node node) { diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/HostRepairMaintainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/HostRepairMaintainerTest.java index 24094892640..556755581fe 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/HostRepairMaintainerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/HostRepairMaintainerTest.java @@ -10,6 +10,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.repair.RepairTicketRepo import org.junit.Test; import java.time.Duration; +import java.time.Instant; import java.util.List; import static org.junit.Assert.*; @@ -27,8 +28,9 @@ public class HostRepairMaintainerTest { var zoneId = ZoneId.from("dev.us-east-1"); var hostname1 = HostName.from("node-1-tenant-host-dev.us-east-1"); var hostname2 = HostName.from("node-2-tenant-host-dev.us-east-1"); - var openTicket = new RepairTicketReport("OPEN", "ticket-1", 123l); - var closedTicket = new RepairTicketReport("CLOSED", "ticket-2", 123l); + var timestamp = Instant.now().toEpochMilli(); + var openTicket = new RepairTicketReport("OPEN", "ticket-1", timestamp, timestamp); + var closedTicket = new RepairTicketReport("CLOSED", "ticket-2", timestamp, timestamp); tester.configServer().nodeRepository().addReport( zoneId, -- cgit v1.2.3