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/athenz/AthenzDbMock.java5
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/ZmsClientMock.java14
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/Node.java204
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/NodeRepository.java36
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/JobType.java2
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepositoryNode.java91
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeResources.java87
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/resource/ResourceSnapshot.java7
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/User.java12
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java16
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java10
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java3
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/systemflags/v1/wire/WireSystemFlagsDeployResult.java15
13 files changed, 360 insertions, 142 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/AthenzDbMock.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/AthenzDbMock.java
index 7ab1ba36aa6..8e21d8cbf20 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/AthenzDbMock.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/AthenzDbMock.java
@@ -57,6 +57,11 @@ public class AthenzDbMock {
return this;
}
+ public Domain deleteTenantAdmin(AthenzIdentity identity) {
+ tenantAdmins.remove(identity);
+ return this;
+ }
+
/**
* Simulates establishing Vespa tenancy in Athens.
*/
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 a80843ad252..096a1af2824 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
@@ -74,6 +74,20 @@ public class ZmsClientMock implements ZmsClient {
}
@Override
+ public void addRoleMember(AthenzRole role, AthenzIdentity member) {
+ if ( ! role.roleName().equals("tenancy.vespa.hosting.admin"))
+ throw new IllegalArgumentException("Mock only supports adding tenant admins, not " + role.roleName());
+ getDomainOrThrow(role.domain(), true).tenantAdmin(member);
+ }
+
+ @Override
+ public void deleteRoleMember(AthenzRole role, AthenzIdentity member) {
+ if ( ! role.roleName().equals("tenancy.vespa.hosting.admin"))
+ throw new IllegalArgumentException("Mock only supports deleting tenant admins, not " + role.roleName());
+ getDomainOrThrow(role.domain(), true).deleteTenantAdmin(member);
+ }
+
+ @Override
public boolean getMembership(AthenzRole role, AthenzIdentity identity) {
if (role.roleName().equals("admin")) {
return getDomainOrThrow(role.domain(), false).admins.contains(identity);
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 e8ae7c181d8..43fea2b76fd 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
@@ -4,8 +4,8 @@ package com.yahoo.vespa.hosted.controller.api.integration.configserver;
import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.HostName;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
-import org.jetbrains.annotations.TestOnly;
import java.util.Objects;
import java.util.Optional;
@@ -22,6 +22,7 @@ public class Node {
private final Optional<HostName> parentHostname;
private final State state;
private final NodeType type;
+ private final NodeResources resources;
private final Optional<ApplicationId> owner;
private final Version currentVersion;
private final Version wantedVersion;
@@ -32,24 +33,20 @@ public class Node {
private final long wantedRestartGeneration;
private final long rebootGeneration;
private final long wantedRebootGeneration;
- private final double vcpu;
- private final double memoryGb;
- private final double diskGb;
- private final double bandwidthGbps;
- private final boolean fastDisk;
private final int cost;
- private final String canonicalFlavor;
+ private final String flavor;
private final String clusterId;
private final ClusterType clusterType;
- public Node(HostName hostname, Optional<HostName> parentHostname, State state, NodeType type, Optional<ApplicationId> owner,
+ public Node(HostName hostname, Optional<HostName> parentHostname, State state, NodeType type, NodeResources resources, Optional<ApplicationId> owner,
Version currentVersion, Version wantedVersion, Version currentOsVersion, Version wantedOsVersion, ServiceState serviceState,
long restartGeneration, long wantedRestartGeneration, long rebootGeneration, long wantedRebootGeneration,
- double vcpu, double memoryGb, double diskGb, double bandwidthGbps, boolean fastDisk, int cost, String canonicalFlavor, String clusterId, ClusterType clusterType) {
+ int cost, String flavor, String clusterId, ClusterType clusterType) {
this.hostname = hostname;
this.parentHostname = parentHostname;
this.state = state;
this.type = type;
+ this.resources = resources;
this.owner = owner;
this.currentVersion = currentVersion;
this.wantedVersion = wantedVersion;
@@ -60,25 +57,12 @@ public class Node {
this.wantedRestartGeneration = wantedRestartGeneration;
this.rebootGeneration = rebootGeneration;
this.wantedRebootGeneration = wantedRebootGeneration;
- this.vcpu = vcpu;
- this.memoryGb = memoryGb;
- this.diskGb = diskGb;
- this.bandwidthGbps = bandwidthGbps;
- this.fastDisk = fastDisk;
this.cost = cost;
- this.canonicalFlavor = canonicalFlavor;
+ this.flavor = flavor;
this.clusterId = clusterId;
this.clusterType = clusterType;
}
- @TestOnly
- public Node(HostName hostname, Optional<HostName> parentHostname, State state, NodeType type, Optional<ApplicationId> owner,
- Version currentVersion, Version wantedVersion) {
- this(hostname, parentHostname, state, type, owner, currentVersion, wantedVersion,
- Version.emptyVersion, Version.emptyVersion, ServiceState.unorchestrated, 0, 0, 0, 0,
- 2, 8, 50, 1, true, 0, "d-2-8-50", "cluster", ClusterType.container);
- }
-
public HostName hostname() {
return hostname;
}
@@ -93,6 +77,10 @@ public class Node {
return type;
}
+ public NodeResources resources() {
+ return resources;
+ }
+
public Optional<ApplicationId> owner() {
return owner;
}
@@ -133,32 +121,12 @@ public class Node {
return wantedRebootGeneration;
}
- public double vcpu() {
- return vcpu;
- }
-
- public double memoryGb() {
- return memoryGb;
- }
-
- public double diskGb() {
- return diskGb;
- }
-
- public double bandwidthGbps() {
- return bandwidthGbps;
- }
-
- public boolean fastDisk() {
- return fastDisk;
- }
-
public int cost() {
return cost;
}
- public String canonicalFlavor() {
- return canonicalFlavor;
+ public String flavor() {
+ return flavor;
}
public String clusterId() {
@@ -210,4 +178,150 @@ public class Node {
unknown
}
+ public static class Builder {
+ private HostName hostname;
+ private Optional<HostName> parentHostname = Optional.empty();
+ private State state;
+ private NodeType type;
+ private NodeResources resources;
+ private Optional<ApplicationId> owner = Optional.empty();
+ private Version currentVersion;
+ private Version wantedVersion;
+ private Version currentOsVersion;
+ private Version wantedOsVersion;
+ private ServiceState serviceState;
+ private long restartGeneration;
+ private long wantedRestartGeneration;
+ private long rebootGeneration;
+ private long wantedRebootGeneration;
+ private int cost;
+ private String flavor;
+ private String clusterId;
+ private ClusterType clusterType;
+
+ public Builder() { }
+
+ public Builder(Node node) {
+ this.hostname = node.hostname;
+ this.parentHostname = node.parentHostname;
+ this.state = node.state;
+ this.type = node.type;
+ this.resources = node.resources;
+ this.owner = node.owner;
+ this.currentVersion = node.currentVersion;
+ this.wantedVersion = node.wantedVersion;
+ this.currentOsVersion = node.currentOsVersion;
+ this.wantedOsVersion = node.wantedOsVersion;
+ this.serviceState = node.serviceState;
+ this.restartGeneration = node.restartGeneration;
+ this.wantedRestartGeneration = node.wantedRestartGeneration;
+ this.rebootGeneration = node.rebootGeneration;
+ this.wantedRebootGeneration = node.wantedRebootGeneration;
+ this.cost = node.cost;
+ this.flavor = node.flavor;
+ this.clusterId = node.clusterId;
+ this.clusterType = node.clusterType;
+ }
+
+ public Builder hostname(HostName hostname) {
+ this.hostname = hostname;
+ return this;
+ }
+
+ public Builder parentHostname(HostName parentHostname) {
+ this.parentHostname = Optional.ofNullable(parentHostname);
+ return this;
+ }
+
+ public Builder state(State state) {
+ this.state = state;
+ return this;
+ }
+
+ public Builder type(NodeType type) {
+ this.type = type;
+ return this;
+ }
+
+ public Builder resources(NodeResources resources) {
+ this.resources = resources;
+ return this;
+ }
+
+ public Builder owner(ApplicationId owner) {
+ this.owner = Optional.ofNullable(owner);
+ return this;
+ }
+
+ public Builder currentVersion(Version currentVersion) {
+ this.currentVersion = currentVersion;
+ return this;
+ }
+
+ public Builder wantedVersion(Version wantedVersion) {
+ this.wantedVersion = wantedVersion;
+ return this;
+ }
+
+ public Builder currentOsVersion(Version currentOsVersion) {
+ this.currentOsVersion = currentOsVersion;
+ return this;
+ }
+
+ public Builder wantedOsVersion(Version wantedOsVersion) {
+ this.wantedOsVersion = wantedOsVersion;
+ return this;
+ }
+
+ public Builder serviceState(ServiceState serviceState) {
+ this.serviceState = serviceState;
+ return this;
+ }
+
+ public Builder restartGeneration(long restartGeneration) {
+ this.restartGeneration = restartGeneration;
+ return this;
+ }
+
+ public Builder wantedRestartGeneration(long wantedRestartGeneration) {
+ this.wantedRestartGeneration = wantedRestartGeneration;
+ return this;
+ }
+
+ public Builder rebootGeneration(long rebootGeneration) {
+ this.rebootGeneration = rebootGeneration;
+ return this;
+ }
+
+ public Builder wantedRebootGeneration(long wantedRebootGeneration) {
+ this.wantedRebootGeneration = wantedRebootGeneration;
+ return this;
+ }
+
+ public Builder cost(int cost) {
+ this.cost = cost;
+ return this;
+ }
+
+ public Builder flavor(String flavor) {
+ this.flavor = flavor;
+ return this;
+ }
+
+ public Builder clusterId(String clusterId) {
+ this.clusterId = clusterId;
+ return this;
+ }
+
+ public Builder clusterType(ClusterType clusterType) {
+ this.clusterType = clusterType;
+ return this;
+ }
+
+ public Node build() {
+ return new Node(hostname, parentHostname, state, type, resources, owner, currentVersion, wantedVersion, currentOsVersion,
+ wantedOsVersion, serviceState, restartGeneration, wantedRestartGeneration, rebootGeneration, wantedRebootGeneration,
+ cost, flavor, clusterId, clusterType);
+ }
+ }
}
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 2dcbf4ca930..94616fd27b2 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
@@ -4,6 +4,7 @@ package com.yahoo.vespa.hosted.controller.api.integration.configserver;
import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.HostName;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.vespa.hosted.controller.api.integration.noderepository.NodeList;
@@ -77,10 +78,18 @@ public interface NodeRepository {
.map(owner -> ApplicationId.from(owner.getTenant(), owner.getApplication(),
owner.getInstance()));
var parentHostname = Optional.ofNullable(node.getParentHostname()).map(HostName::from);
+ var resources = new NodeResources(
+ toDouble(node.getResources().getVcpu()),
+ toDouble(node.getResources().getMemoryGb()),
+ toDouble(node.getResources().getDiskGb()),
+ toDouble(node.getResources().getBandwidthGbps()),
+ diskSpeedFromString(node.getResources().getDiskSpeed()),
+ storageTypeFromString(node.getResources().getStorageType()));
return new Node(HostName.from(node.getHostname()),
parentHostname,
fromJacksonState(node.getState()),
fromJacksonType(node.getType()),
+ resources,
application,
versionFrom(node.getVespaVersion()),
versionFrom(node.getWantedVespaVersion()),
@@ -91,13 +100,8 @@ public interface NodeRepository {
toInt(node.getRestartGeneration()),
toInt(node.getCurrentRebootGeneration()),
toInt(node.getRebootGeneration()),
- toDouble(node.getMinCpuCores()),
- toDouble(node.getMinMainMemoryAvailableGb()),
- toDouble(node.getMinDiskAvailableGb()),
- toDouble(node.getBandwidthGbps()),
- toBoolean(node.getFastDisk()),
toInt(node.getCost()),
- node.getCanonicalFlavor(),
+ node.getFlavor(),
clusterIdOf(node.getMembership()),
clusterTypeOf(node.getMembership()));
}
@@ -143,6 +147,26 @@ public interface NodeRepository {
return Node.State.unknown;
}
+ private static NodeResources.DiskSpeed diskSpeedFromString(String diskSpeed) {
+ if (diskSpeed == null) return NodeResources.DiskSpeed.getDefault();
+ switch (diskSpeed) {
+ case "fast": return NodeResources.DiskSpeed.fast;
+ case "slow": return NodeResources.DiskSpeed.slow;
+ case "any": return NodeResources.DiskSpeed.any;
+ default: throw new IllegalArgumentException("Unknown disk speed '" + diskSpeed + "'");
+ }
+ }
+
+ private static NodeResources.StorageType storageTypeFromString(String storageType) {
+ if (storageType == null) return NodeResources.StorageType.getDefault();
+ switch (storageType) {
+ case "remote": return NodeResources.StorageType.remote;
+ case "local": return NodeResources.StorageType.local;
+ case "any": return NodeResources.StorageType.any;
+ default: throw new IllegalArgumentException("Unknown storage type '" + storageType + "'");
+ }
+ }
+
private static Node.ServiceState fromBoolean(Boolean allowedDown) {
return (allowedDown == null)
? Node.ServiceState.unorchestrated
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/JobType.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/JobType.java
index ec742698540..8eb217f6d4b 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/JobType.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/JobType.java
@@ -70,7 +70,7 @@ public enum JobType {
Map.of(main, ZoneId.from("dev" , "us-east-1"))),
devAwsUsEast2a ("dev-aws-us-east-2a",
- Map.of(main, ZoneId.from("dev" , "us-east-1"))),
+ Map.of(main, ZoneId.from("dev" , "aws-us-east-2a"))),
productionCdAwsUsEast1a("production-cd-aws-us-east-1a",
Map.of(cd , ZoneId.from("prod" , "cd-aws-us-east-1a"))),
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepositoryNode.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepositoryNode.java
index 227f35498ce..78a64b98e2b 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepositoryNode.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeRepositoryNode.java
@@ -30,8 +30,10 @@ public class NodeRepositoryNode {
private String openStackId;
@JsonProperty("flavor")
private String flavor;
- @JsonProperty("canonicalFlavor")
- private String canonicalFlavor;
+ @JsonProperty("resources")
+ private NodeResources resources;
+ @JsonProperty("requestedResources")
+ private NodeResources requestedResources;
@JsonProperty("membership")
private NodeMembership membership;
@JsonProperty("owner")
@@ -68,20 +70,8 @@ public class NodeRepositoryNode {
private Boolean wantToRetire;
@JsonProperty("wantToDeprovision")
private Boolean wantToDeprovision;
- @JsonProperty("minDiskAvailableGb")
- private Double minDiskAvailableGb;
- @JsonProperty("minMainMemoryAvailableGb")
- private Double minMainMemoryAvailableGb;
@JsonProperty("cost")
private Integer cost;
- @JsonProperty("minCpuCores")
- private Double minCpuCores;
- @JsonProperty("bandwidthGbps")
- private Double bandwidthGbps;
- @JsonProperty("fastDisk")
- private Boolean fastDisk;
- @JsonProperty("description")
- private String description;
@JsonProperty("history")
private NodeHistory[] history;
@JsonProperty("allowedToBeDown")
@@ -155,12 +145,20 @@ public class NodeRepositoryNode {
this.flavor = flavor;
}
- public String getCanonicalFlavor() {
- return canonicalFlavor;
+ public NodeResources getResources() {
+ return resources;
}
- public void setCanonicalFlavor(String canonicalFlavor) {
- this.canonicalFlavor = canonicalFlavor;
+ public void setResources(NodeResources resources) {
+ this.resources = resources;
+ }
+
+ public NodeResources getRequestedResources() {
+ return requestedResources;
+ }
+
+ public void setRequestedResources(NodeResources requestedResources) {
+ this.requestedResources = requestedResources;
}
public NodeMembership getMembership() {
@@ -289,22 +287,6 @@ public class NodeRepositoryNode {
this.wantToDeprovision = wantToDeprovision;
}
- public Double getMinDiskAvailableGb() {
- return minDiskAvailableGb;
- }
-
- public void setMinDiskAvailableGb(Double minDiskAvailableGb) {
- this.minDiskAvailableGb = minDiskAvailableGb;
- }
-
- public Double getMinMainMemoryAvailableGb() {
- return minMainMemoryAvailableGb;
- }
-
- public void setMinMainMemoryAvailableGb(Double minMainMemoryAvailableGb) {
- this.minMainMemoryAvailableGb = minMainMemoryAvailableGb;
- }
-
public Integer getCost() {
return cost;
}
@@ -313,38 +295,6 @@ public class NodeRepositoryNode {
this.cost = cost;
}
- public Double getMinCpuCores() {
- return minCpuCores;
- }
-
- public void setMinCpuCores(Double minCpuCores) {
- this.minCpuCores = minCpuCores;
- }
-
- public Double getBandwidthGbps() {
- return bandwidthGbps;
- }
-
- public void setBandwidthGbps(Double bandwidthGbps) {
- this.bandwidthGbps = bandwidthGbps;
- }
-
- public Boolean getFastDisk() {
- return fastDisk;
- }
-
- public void setFastDisk(Boolean fastDisk) {
- this.fastDisk = fastDisk;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
public NodeHistory[] getHistory() {
return history;
}
@@ -400,7 +350,8 @@ public class NodeRepositoryNode {
", additionalIpAddresses=" + additionalIpAddresses +
", openStackId='" + openStackId + '\'' +
", flavor='" + flavor + '\'' +
- ", canonicalFlavor='" + canonicalFlavor + '\'' +
+ ", resources=" + resources +
+ ", requestedResources=" + requestedResources +
", membership=" + membership +
", owner=" + owner +
", restartGeneration=" + restartGeneration +
@@ -419,13 +370,7 @@ public class NodeRepositoryNode {
", parentHostname='" + parentHostname + '\'' +
", wantToRetire=" + wantToRetire +
", wantToDeprovision=" + wantToDeprovision +
- ", minDiskAvailableGb=" + minDiskAvailableGb +
- ", minMainMemoryAvailableGb=" + minMainMemoryAvailableGb +
", cost=" + cost +
- ", minCpuCores=" + minCpuCores +
- ", bandwidthGbps=" + bandwidthGbps +
- ", fastDisk=" + fastDisk +
- ", description='" + description + '\'' +
", history=" + Arrays.toString(history) +
", allowedToBeDown=" + allowedToBeDown +
", reports=" + reports +
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeResources.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeResources.java
new file mode 100644
index 00000000000..ded61c7a94e
--- /dev/null
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/noderepository/NodeResources.java
@@ -0,0 +1,87 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.controller.api.integration.noderepository;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * @author freva
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class NodeResources {
+
+ @JsonProperty
+ private Double vcpu;
+ @JsonProperty
+ private Double memoryGb;
+ @JsonProperty
+ private Double diskGb;
+ @JsonProperty
+ private Double bandwidthGbps;
+ @JsonProperty
+ private String diskSpeed;
+ @JsonProperty
+ private String storageType;
+
+ public Double getVcpu() {
+ return vcpu;
+ }
+
+ public void setVcpu(Double vcpu) {
+ this.vcpu = vcpu;
+ }
+
+ public Double getMemoryGb() {
+ return memoryGb;
+ }
+
+ public void setMemoryGb(Double memoryGb) {
+ this.memoryGb = memoryGb;
+ }
+
+ public Double getDiskGb() {
+ return diskGb;
+ }
+
+ public void setDiskGb(Double diskGb) {
+ this.diskGb = diskGb;
+ }
+
+ public Double getBandwidthGbps() {
+ return bandwidthGbps;
+ }
+
+ public void setBandwidthGbps(Double bandwidthGbps) {
+ this.bandwidthGbps = bandwidthGbps;
+ }
+
+ public String getDiskSpeed() {
+ return diskSpeed;
+ }
+
+ public void setDiskSpeed(String diskSpeed) {
+ this.diskSpeed = diskSpeed;
+ }
+
+ public String getStorageType() {
+ return storageType;
+ }
+
+ public void setStorageType(String storageType) {
+ this.storageType = storageType;
+ }
+
+ @Override
+ public String toString() {
+ return "NodeResources{" +
+ "vcpu=" + vcpu +
+ ", memoryGb=" + memoryGb +
+ ", diskGb=" + diskGb +
+ ", bandwidthGbps=" + bandwidthGbps +
+ ", diskSpeed='" + diskSpeed + '\'' +
+ ", storageType='" + storageType + '\'' +
+ '}';
+ }
+}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/resource/ResourceSnapshot.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/resource/ResourceSnapshot.java
index 5ee6df9f034..cfe0f18260a 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/resource/ResourceSnapshot.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/resource/ResourceSnapshot.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.hosted.controller.api.integration.resource;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node;
@@ -37,9 +38,9 @@ public class ResourceSnapshot {
return new ResourceSnapshot(
applicationIds.iterator().next(),
- nodes.stream().mapToDouble(Node::vcpu).sum(),
- nodes.stream().mapToDouble(Node::memoryGb).sum(),
- nodes.stream().mapToDouble(Node::diskGb).sum(),
+ nodes.stream().map(Node::resources).mapToDouble(NodeResources::vcpu).sum(),
+ nodes.stream().map(Node::resources).mapToDouble(NodeResources::memoryGb).sum(),
+ nodes.stream().map(Node::resources).mapToDouble(NodeResources::diskGb).sum(),
timestamp,
zoneId
);
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/User.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/User.java
index 35dcd54799b..ac64df7713f 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/User.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/User.java
@@ -2,19 +2,21 @@ package com.yahoo.vespa.hosted.controller.api.integration.user;
import java.util.Objects;
+/**
+ * @author smorgrav
+ */
public class User {
- private final String name;
+ public static final String ATTRIBUTE_NAME = User.class.getName();
+
private final String email;
+ private final String name;
private final String nickname;
private final String picture;
public User(String email, String name, String nickname, String picture) {
- Objects.requireNonNull(email);
- Objects.requireNonNull(name);
-
+ this.email = Objects.requireNonNull(email);
this.name = name;
- this.email = email;
this.nickname = nickname;
this.picture = picture;
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java
index bf89d072b75..95669f7f05d 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java
@@ -32,8 +32,9 @@ enum PathGroup {
"/provision/v2/{*}",
"/zone/v2/{*}"),
- /** Paths used for creating user tenants. */
- user("/application/v4/user"),
+ /** Paths used for creating and reading user resources. */
+ user("/application/v4/user",
+ "/athenz/v1/{*}"),
/** Paths used for creating tenants with proper access control. */
tenant(Matcher.tenant,
@@ -95,6 +96,7 @@ enum PathGroup {
"/application/v4/tenant/{tenant}/application/{application}/environment/{environment}/region/{region}/instance/{ignored}/global-rotation/{*}",
"/application/v4/tenant/{tenant}/application/{application}/metering"),
+ // TODO jonmv: remove
/** Path used to restart development nodes. */
developmentRestart(Matcher.tenant,
Matcher.application,
@@ -105,6 +107,7 @@ enum PathGroup {
"/application/v4/tenant/{tenant}/application/{application}/environment/dev/region/{region}/instance/{instance}/restart",
"/application/v4/tenant/{tenant}/application/{application}/environment/perf/region/{region}/instance/{instance}/restart"),
+ // TODO jonmv: remove
/** Path used to restart production nodes. */
productionRestart(Matcher.tenant,
Matcher.application,
@@ -131,6 +134,7 @@ enum PathGroup {
"/application/v4/tenant/{tenant}/application/{application}/environment/perf/region/{region}/instance/{instance}",
"/application/v4/tenant/{tenant}/application/{application}/environment/perf/region/{region}/instance/{instance}/deploy"),
+ // TODO jonmv: remove
/** Paths used for production deployments. */
productionDeployment(Matcher.tenant,
Matcher.application,
@@ -168,13 +172,17 @@ enum PathGroup {
"/application/v4/tenant/"),
/** Paths which contain (not very strictly) classified information about, e.g., customers. */
- classifiedInfo("/athenz/v1/{*}",
- "/cost/v1/{*}",
+ classifiedInfo("/cost/v1/{*}",
"/deployment/v1/{*}",
"/",
"/d/{*}",
+ "/static/{*}",
"/statuspage/v1/{*}"),
+ /** Same as classifiedInfo, but with optional /api prefix */
+ classifiedApiInfo(Optional.of("/api"),
+ "/user/v1/user"),
+
/** Paths providing public information. */
publicInfo(Optional.of("/api"),
"/badge/v1/{*}",
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java
index 074d3ef7e95..e27fb0fbf27 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java
@@ -34,9 +34,9 @@ enum Policy {
.in(SystemName.all())),
/** Access to create a user tenant in select systems. */
- userCreate(Privilege.grant(Action.update)
- .on(PathGroup.user)
- .in(SystemName.main, SystemName.cd, SystemName.dev)),
+ user(Privilege.grant(Action.create, Action.update)
+ .on(PathGroup.user)
+ .in(SystemName.main, SystemName.cd, SystemName.dev)),
/** Access to create a tenant in select systems. */
tenantCreate(Privilege.grant(Action.create)
@@ -118,6 +118,10 @@ enum Policy {
.on(PathGroup.allExcept(PathGroup.classifiedOperator))
.in(SystemName.main, SystemName.cd, SystemName.dev)),
+ classifiedApiRead(Privilege.grant(Action.read)
+ .on(PathGroup.classifiedApiInfo)
+ .in(SystemName.all())),
+
/** Read access to public info. */
publicRead(Privilege.grant(Action.read)
.on(PathGroup.publicInfo)
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java
index 67efdc3017d..10df7604667 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java
@@ -22,8 +22,9 @@ public enum RoleDefinition {
/** Base role which every user is part of. */
everyone(Policy.classifiedRead,
+ Policy.classifiedApiRead,
Policy.publicRead,
- Policy.userCreate,
+ Policy.user,
Policy.tenantCreate),
/** Application reader which can see all information about an application, its tenant and deployments. */
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/systemflags/v1/wire/WireSystemFlagsDeployResult.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/systemflags/v1/wire/WireSystemFlagsDeployResult.java
index bd54fd15d15..69070d86ef7 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/systemflags/v1/wire/WireSystemFlagsDeployResult.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/systemflags/v1/wire/WireSystemFlagsDeployResult.java
@@ -9,7 +9,7 @@ import com.yahoo.vespa.flags.json.wire.WireFlagData;
import java.util.List;
/**
- *
+ * Note: This class is only annotated for serialization, deserialization is not supported.
*
* @author bjorncs
*/
@@ -17,6 +17,7 @@ import java.util.List;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class WireSystemFlagsDeployResult {
@JsonProperty("changes") public List<WireFlagDataChange> changes;
+ @JsonProperty("errors") public List<WireOperationFailure> errors;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@@ -27,6 +28,18 @@ public class WireSystemFlagsDeployResult {
@JsonProperty("data") public WireFlagData data;
@JsonProperty("previous-data") public WireFlagData previousData;
}
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ @JsonInclude(JsonInclude.Include.NON_NULL)
+ public static class WireOperationFailure {
+ @JsonProperty("flag-id") public String flagId;
+ @JsonProperty("message") public String message;
+ @JsonProperty("targets") public List<String> targets;
+ @JsonProperty("operation") public String operation;
+ @JsonProperty("data") public WireFlagData data;
+ }
+
+ public boolean hasErrors() { return errors != null && !errors.isEmpty(); }
}