aboutsummaryrefslogtreecommitdiffstats
path: root/controller-api
diff options
context:
space:
mode:
Diffstat (limited to 'controller-api')
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/ConsoleUrls.java87
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/ServiceRegistry.java4
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentFailureMails.java12
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/zone/ZoneRegistry.java21
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Email.java2
-rw-r--r--controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/ConsoleUrlsTest.java43
6 files changed, 140 insertions, 29 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/ConsoleUrls.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/ConsoleUrls.java
new file mode 100644
index 00000000000..872cbd67780
--- /dev/null
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/ConsoleUrls.java
@@ -0,0 +1,87 @@
+// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.controller.api.integration;
+
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.ApplicationName;
+import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.Environment;
+import com.yahoo.config.provision.TenantName;
+import com.yahoo.config.provision.zone.ZoneId;
+import com.yahoo.vespa.hosted.controller.api.integration.deployment.RunId;
+
+import java.net.URI;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Generates URLs to various views in the Console. Prefer to create new methods and return
+ * String instead of URI to make it easier to track which views are linked from where.
+ *
+ * @author freva
+ */
+public class ConsoleUrls {
+ private final String root;
+ public ConsoleUrls(URI root) {
+ this.root = root.toString().replaceFirst("/$", ""); // Remove trailing slash
+ }
+
+ public String root() {
+ return root;
+ }
+
+ public String tenantOverview(TenantName tenantName) {
+ return "%s/tenant/%s".formatted(root, tenantName.value());
+ }
+
+ /** Returns URL to notification settings view for the given tenant */
+ public String tenantNotifications(TenantName tenantName) {
+ return "%s/tenant/%s/account/notifications".formatted(root, tenantName.value());
+ }
+
+ public String prodApplicationOverview(TenantName tenantName, ApplicationName applicationName) {
+ return "%s/tenant/%s/application/%s/prod/instance".formatted(root, tenantName.value(), applicationName.value());
+ }
+
+ public String instanceOverview(ApplicationId application, Environment environment) {
+ return "%s/tenant/%s/application/%s/%s/instance/%s".formatted(root,
+ application.tenant().value(),
+ application.application().value(),
+ environment.isManuallyDeployed() ? environment.value() : "prod",
+ application.instance().value());
+ }
+
+ public String clusterOverview(ApplicationId application, ZoneId zone, ClusterSpec.Id clusterId) {
+ return cluster(application, zone, clusterId, null);
+ }
+
+ public String clusterReindexing(ApplicationId application, ZoneId zone, ClusterSpec.Id clusterId) {
+ return cluster(application, zone, clusterId, "reindexing");
+ }
+
+ public String deploymentRun(RunId id) {
+ return "%s/job/%s/run/%s".formatted(
+ instanceOverview(id.application(), id.type().environment()), id.type().jobName(), id.number());
+ }
+
+ /** Returns URL used to request support from the Vespa team. */
+ public String support() {
+ return root + "/support";
+ }
+
+ /** Returns URL to verify an email address with the given verification code */
+ public String verifyEmail(String verifyCode) {
+ return "%s/verify?%s".formatted(root, queryParam("code", verifyCode));
+ }
+
+ public String termsOfService() { return root + "/terms-of-service-trial.html"; }
+
+ private String cluster(ApplicationId application, ZoneId zone, ClusterSpec.Id clusterId, String viewOrNull) {
+ return instanceOverview(application, zone.environment()) + '?' +
+ queryParam("%s.%s.%s".formatted(application.instance().value(), zone.environment().value(), zone.region().value()),
+ "clusters," + clusterId.value() + (viewOrNull == null ? "" : '=' + viewOrNull));
+ }
+
+ private static String queryParam(String key, String value) {
+ return URLEncoder.encode(key, StandardCharsets.UTF_8) + '=' + URLEncoder.encode(value, StandardCharsets.UTF_8);
+ }
+}
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 0eead322df5..e39a8cf38b7 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
@@ -32,8 +32,8 @@ import com.yahoo.vespa.hosted.controller.api.integration.organization.OwnershipI
import com.yahoo.vespa.hosted.controller.api.integration.organization.SystemMonitor;
import com.yahoo.vespa.hosted.controller.api.integration.resource.CostReportConsumer;
import com.yahoo.vespa.hosted.controller.api.integration.resource.ResourceDatabaseClient;
-import com.yahoo.vespa.hosted.controller.api.integration.secrets.GcpSecretStore;
import com.yahoo.vespa.hosted.controller.api.integration.secrets.EndpointSecretManager;
+import com.yahoo.vespa.hosted.controller.api.integration.secrets.GcpSecretStore;
import com.yahoo.vespa.hosted.controller.api.integration.secrets.TenantSecretService;
import com.yahoo.vespa.hosted.controller.api.integration.user.RoleMaintainer;
import com.yahoo.vespa.hosted.controller.api.integration.vcmr.ChangeRequestClient;
@@ -90,6 +90,8 @@ public interface ServiceRegistry {
ZoneRegistry zoneRegistry();
+ ConsoleUrls consoleUrls();
+
ResourceTagger resourceTagger();
EnclaveAccessService enclaveAccessService();
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentFailureMails.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentFailureMails.java
index ef08c3a9adc..72728966dbc 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentFailureMails.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentFailureMails.java
@@ -1,9 +1,9 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.controller.api.integration.organization;
+import com.yahoo.vespa.hosted.controller.api.integration.ConsoleUrls;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RunId;
-import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneRegistry;
import java.util.Collection;
@@ -14,10 +14,10 @@ import java.util.Collection;
*/
public class DeploymentFailureMails {
- private final ZoneRegistry registry;
+ private final ConsoleUrls consoleUrls;
- public DeploymentFailureMails(ZoneRegistry registry) {
- this.registry = registry;
+ public DeploymentFailureMails(ConsoleUrls consoleUrls) {
+ this.consoleUrls = consoleUrls;
}
public Mail nodeAllocationFailure(RunId id, Collection<String> recipients) {
@@ -66,8 +66,8 @@ public class DeploymentFailureMails {
jobToString(id.type()),
id.application(),
messageDetail,
- registry.dashboardUrl(id),
- registry.supportUrl()));
+ consoleUrls.deploymentRun(id),
+ consoleUrls.support()));
}
private String jobToString(JobType type) {
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/zone/ZoneRegistry.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/zone/ZoneRegistry.java
index 747c6b72172..92c0a6b1fbb 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/zone/ZoneRegistry.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/zone/ZoneRegistry.java
@@ -1,8 +1,6 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.controller.api.integration.zone;
-import com.yahoo.config.provision.ApplicationId;
-import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.AthenzDomain;
import com.yahoo.config.provision.CloudAccount;
import com.yahoo.config.provision.CloudName;
@@ -18,7 +16,6 @@ import com.yahoo.config.provision.zone.ZoneFilter;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.vespa.athenz.api.AthenzIdentity;
import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId;
-import com.yahoo.vespa.hosted.controller.api.integration.deployment.RunId;
import java.net.URI;
import java.time.Duration;
@@ -97,24 +94,6 @@ public interface ZoneRegistry {
/** Returns the routing method used by given zone */
RoutingMethod routingMethod(ZoneId zone);
- /** Returns a URL where an informative dashboard can be found. */
- URI dashboardUrl();
-
- /** Returns a URL which displays information about the given tenant. */
- URI dashboardUrl(TenantName id);
-
- /** Returns a URL which displays information about the given application. */
- URI dashboardUrl(TenantName tenantName, ApplicationName applicationName);
-
- /** Returns a URL which displays information about the given application instance. */
- URI dashboardUrl(ApplicationId id);
-
- /** Returns a URL which displays information about the given job run. */
- URI dashboardUrl(RunId id);
-
- /** Returns a URL used to request support from the Vespa team. */
- URI supportUrl();
-
/** Returns a URL to the controller's api endpoint */
URI apiUrl();
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Email.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Email.java
index 995f1b1864f..c1c8a780df1 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Email.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Email.java
@@ -25,7 +25,7 @@ public class Email {
}
public static Email empty() {
- return new Email("", true);
+ return new Email("", false);
}
public Email withEmailAddress(String emailAddress) {
diff --git a/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/ConsoleUrlsTest.java b/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/ConsoleUrlsTest.java
new file mode 100644
index 00000000000..62e79c3be50
--- /dev/null
+++ b/controller-api/src/test/java/com/yahoo/vespa/hosted/controller/api/integration/ConsoleUrlsTest.java
@@ -0,0 +1,43 @@
+// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.controller.api.integration;
+
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.Environment;
+import com.yahoo.config.provision.zone.ZoneId;
+import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType;
+import com.yahoo.vespa.hosted.controller.api.integration.deployment.RunId;
+import org.junit.jupiter.api.Test;
+
+import java.net.URI;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * @author freva
+ */
+class ConsoleUrlsTest {
+
+ private final ConsoleUrls urls = new ConsoleUrls(URI.create("https://console.tld/"));
+
+ @Test
+ void urls() {
+ ApplicationId app = ApplicationId.from("t1", "a1", "i1");
+ ZoneId prod = ZoneId.from("prod", "us-north-1");
+ ZoneId dev = ZoneId.from("dev", "eu-west-2");
+ ZoneId test = ZoneId.from("test", "ap-east-3");
+ ClusterSpec.Id cluster = ClusterSpec.Id.from("c1");
+
+ assertEquals("https://console.tld", urls.root());
+ assertEquals("https://console.tld/tenant/t1", urls.tenantOverview(app.tenant()));
+ assertEquals("https://console.tld/tenant/t1/account/notifications", urls.tenantNotifications(app.tenant()));
+ assertEquals("https://console.tld/tenant/t1/application/a1/prod/instance", urls.prodApplicationOverview(app.tenant(), app.application()));
+ assertEquals("https://console.tld/tenant/t1/application/a1/prod/instance/i1", urls.instanceOverview(app, Environment.test));
+ assertEquals("https://console.tld/tenant/t1/application/a1/dev/instance/i1?i1.dev.eu-west-2=clusters%2Cc1", urls.clusterOverview(app, dev, cluster));
+ assertEquals("https://console.tld/tenant/t1/application/a1/prod/instance/i1?i1.prod.us-north-1=clusters%2Cc1%3Dreindexing", urls.clusterReindexing(app, prod, cluster));
+ assertEquals("https://console.tld/tenant/t1/application/a1/prod/instance/i1/job/production-us-north-1/run/1", urls.deploymentRun(new RunId(app, JobType.deploymentTo(prod), 1)));
+ assertEquals("https://console.tld/tenant/t1/application/a1/prod/instance/i1/job/system-test/run/1", urls.deploymentRun(new RunId(app, JobType.deploymentTo(test), 1)));
+ assertEquals("https://console.tld/tenant/t1/application/a1/dev/instance/i1/job/dev-eu-west-2/run/1", urls.deploymentRun(new RunId(app, JobType.deploymentTo(dev), 1)));
+ assertEquals("https://console.tld/verify?code=test123", urls.verifyEmail("test123"));
+ }
+}