summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@verizonmedia.com>2021-10-01 15:54:15 +0200
committerGitHub <noreply@github.com>2021-10-01 15:54:15 +0200
commit84a50ce02432a34177d0f0355bf7ffb19ba5580d (patch)
tree2655dc600dd0113637e799d0c473d6898001c113
parent999556d9c93331b169f00ee28fd5095eae98c362 (diff)
parent9ce8e3121ba0c5fe36792e930c438f081dd0445d (diff)
Merge pull request #19401 from vespa-engine/bjorncs/reduce-modifying-operations-zms
Add ZmsClient.getPolicy()
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/AthenzDbMock.java7
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/ZmsClientMock.java16
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/api/AthenzAssertion.java80
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/api/AthenzPolicy.java42
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zms/DefaultZmsClient.java32
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zms/ZmsClient.java3
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zms/bindings/AssertionEntity.java6
7 files changed, 178 insertions, 8 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 a9b20040f20..0f50ff4e198 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
@@ -150,7 +150,12 @@ public class AthenzDbMock {
this.resource = resource;
}
- public Assertion(String role, String action, String resource) { this("grant", role, action, resource); }
+ public Assertion(String role, String action, String resource) { this("allow", role, action, resource); }
+
+ public String effect() { return effect; }
+ public String role() { return role; }
+ public String action() { return action; }
+ public String resource() { return resource; }
public boolean matches(AthenzIdentity principal, String action, String resource) {
return Pattern.compile(this.role).matcher(principal.getFullName()).matches()
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 b362a0c7a47..7960e5e8df7 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
@@ -1,9 +1,11 @@
// Copyright 2017 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.athenz;
+import com.yahoo.vespa.athenz.api.AthenzAssertion;
import com.yahoo.vespa.athenz.api.AthenzDomain;
import com.yahoo.vespa.athenz.api.AthenzGroup;
import com.yahoo.vespa.athenz.api.AthenzIdentity;
+import com.yahoo.vespa.athenz.api.AthenzPolicy;
import com.yahoo.vespa.athenz.api.AthenzResourceName;
import com.yahoo.vespa.athenz.api.AthenzRole;
import com.yahoo.vespa.athenz.api.AthenzService;
@@ -184,6 +186,20 @@ public class ZmsClientMock implements ZmsClient {
}
@Override
+ public Optional<AthenzPolicy> getPolicy(AthenzDomain domain, String name) {
+ AthenzDbMock.Policy policy = athenz.getOrCreateDomain(domain).policies.get(name);
+ if (policy == null) return Optional.empty();
+ List<AthenzAssertion> assertions = policy.assertions.stream()
+ .map(a -> AthenzAssertion.newBuilder(
+ new AthenzRole(domain, a.role()),
+ AthenzResourceName.fromString(a.resource()),
+ a.action())
+ .build())
+ .collect(Collectors.toList());
+ return Optional.of(new AthenzPolicy(policy.name(), assertions));
+ }
+
+ @Override
public Map<AthenzUser,String> listPendingRoleApprovals(AthenzRole athenzRole) {
return Map.of();
}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/api/AthenzAssertion.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/api/AthenzAssertion.java
new file mode 100644
index 00000000000..23d1b4dfc7e
--- /dev/null
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/api/AthenzAssertion.java
@@ -0,0 +1,80 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.athenz.api;
+
+import java.util.Objects;
+import java.util.Optional;
+import java.util.OptionalLong;
+
+/**
+ * @author bjorncs
+ */
+public class AthenzAssertion {
+
+ public enum Effect { ALLOW, DENY }
+
+ private final Long id;
+ private final Effect effect;
+ private final AthenzRole role;
+ private final AthenzResourceName resource;
+ private final String action;
+
+ private AthenzAssertion(Builder builder) {
+ this.id = builder.id;
+ this.effect = builder.effect;
+ this.role = builder.role;
+ this.resource = builder.resource;
+ this.action = builder.action;
+ }
+
+ public OptionalLong id() { return id == null ? OptionalLong.empty() : OptionalLong.of(id); }
+ public Optional<Effect> effect() { return Optional.ofNullable(effect); }
+ public AthenzRole role() { return role; }
+ public AthenzResourceName resource() { return resource; }
+ public String action() { return action; }
+
+ public static Builder newBuilder(AthenzRole role, AthenzResourceName resource, String action) {
+ return new Builder(role, resource, action);
+ }
+
+ public static class Builder {
+ private Long id;
+ private Effect effect;
+ private AthenzRole role;
+ private AthenzResourceName resource;
+ private String action;
+
+ private Builder(AthenzRole role, AthenzResourceName resource, String action) {
+ this.role = role;
+ this.resource = resource;
+ this.action = action;
+ }
+
+ public Builder id(long id) { this.id = id; return this; }
+ public Builder effect(Effect effect) { this.effect = effect; return this; }
+ public AthenzAssertion build() { return new AthenzAssertion(this); }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ AthenzAssertion that = (AthenzAssertion) o;
+ return Objects.equals(id, that.id) && effect == that.effect && Objects.equals(role, that.role) && Objects.equals(resource, that.resource) && Objects.equals(action, that.action);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, effect, role, resource, action);
+ }
+
+ @Override
+ public String toString() {
+ return "AthenzAssertion{" +
+ "id=" + id +
+ ", effect=" + effect +
+ ", role=" + role +
+ ", resource=" + resource +
+ ", action='" + action + '\'' +
+ '}';
+ }
+}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/api/AthenzPolicy.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/api/AthenzPolicy.java
new file mode 100644
index 00000000000..40436432c47
--- /dev/null
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/api/AthenzPolicy.java
@@ -0,0 +1,42 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.athenz.api;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author bjorncs
+ */
+public class AthenzPolicy {
+ private final String name;
+ private final List<AthenzAssertion> assertions;
+
+ public AthenzPolicy(String name, List<AthenzAssertion> assertions) {
+ this.assertions = List.copyOf(assertions);
+ this.name = name;
+ }
+
+ public String name() { return name; }
+ public List<AthenzAssertion> assertions() { return assertions; }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ AthenzPolicy that = (AthenzPolicy) o;
+ return Objects.equals(name, that.name) && Objects.equals(assertions, that.assertions);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, assertions);
+ }
+
+ @Override
+ public String toString() {
+ return "AthenzPolicy{" +
+ "name='" + name + '\'' +
+ ", assertions=" + assertions +
+ '}';
+ }
+}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zms/DefaultZmsClient.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zms/DefaultZmsClient.java
index 769a2a54c95..09d02715fa0 100644
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zms/DefaultZmsClient.java
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zms/DefaultZmsClient.java
@@ -1,9 +1,11 @@
// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.athenz.client.zms;
+import com.yahoo.vespa.athenz.api.AthenzAssertion;
import com.yahoo.vespa.athenz.api.AthenzDomain;
import com.yahoo.vespa.athenz.api.AthenzGroup;
import com.yahoo.vespa.athenz.api.AthenzIdentity;
+import com.yahoo.vespa.athenz.api.AthenzPolicy;
import com.yahoo.vespa.athenz.api.AthenzResourceName;
import com.yahoo.vespa.athenz.api.AthenzRole;
import com.yahoo.vespa.athenz.api.AthenzService;
@@ -39,7 +41,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import java.util.OptionalInt;
+import java.util.OptionalLong;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@@ -242,18 +244,18 @@ public class DefaultZmsClient extends ClientBase implements ZmsClient {
.build();
PolicyEntity policyEntity = execute(request, response -> readEntity(response, PolicyEntity.class));
- OptionalInt assertionId = policyEntity.getAssertions().stream()
+ OptionalLong assertionId = policyEntity.getAssertions().stream()
.filter(assertionEntity -> assertionEntity.getAction().equals(action) &&
assertionEntity.getResource().equals(resourceName.toResourceNameString()) &&
assertionEntity.getRole().equals(athenzRole.toResourceNameString()))
- .mapToInt(AssertionEntity::getId).findFirst();
+ .mapToLong(AssertionEntity::getId).findFirst();
if (assertionId.isEmpty()) {
return false;
}
uri = zmsUrl.resolve(String.format("domain/%s/policy/%s/assertion/%d",
- athenzDomain.getName(), athenzPolicy, assertionId.getAsInt()));
+ athenzDomain.getName(), athenzPolicy, assertionId.getAsLong()));
request = RequestBuilder.delete()
.setUri(uri)
@@ -264,6 +266,28 @@ public class DefaultZmsClient extends ClientBase implements ZmsClient {
}
@Override
+ public Optional<AthenzPolicy> getPolicy(AthenzDomain domain, String name) {
+ var uri = zmsUrl.resolve(String.format("domain/%s/policy/%s", domain.getName(), name));
+ HttpUriRequest request = RequestBuilder.get().setUri(uri).build();
+ PolicyEntity entity;
+ try {
+ entity = execute(request, response -> readEntity(response, PolicyEntity.class));
+ } catch (ZmsClientException e) {
+ if (e.getErrorCode() == 404) return Optional.empty();
+ throw e;
+ }
+ List<AthenzAssertion> assertions = entity.getAssertions().stream()
+ .map(a -> AthenzAssertion.newBuilder(
+ AthenzRole.fromResourceNameString(a.getRole()),
+ AthenzResourceName.fromString(a.getResource()),
+ a.getAction())
+ .id(a.getId())
+ .build())
+ .collect(toList());
+ return Optional.of(new AthenzPolicy(entity.getName(), assertions));
+ }
+
+ @Override
public Map<AthenzUser, String> listPendingRoleApprovals(AthenzRole athenzRole) {
URI uri = zmsUrl.resolve(String.format("domain/%s/role/%s?pending=true", athenzRole.domain().getName(), athenzRole.roleName()));
HttpUriRequest request = RequestBuilder.get()
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zms/ZmsClient.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zms/ZmsClient.java
index b1c26923113..34f1f4d891f 100644
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zms/ZmsClient.java
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zms/ZmsClient.java
@@ -4,6 +4,7 @@ package com.yahoo.vespa.athenz.client.zms;
import com.yahoo.vespa.athenz.api.AthenzDomain;
import com.yahoo.vespa.athenz.api.AthenzGroup;
import com.yahoo.vespa.athenz.api.AthenzIdentity;
+import com.yahoo.vespa.athenz.api.AthenzPolicy;
import com.yahoo.vespa.athenz.api.AthenzResourceName;
import com.yahoo.vespa.athenz.api.AthenzRole;
import com.yahoo.vespa.athenz.api.AthenzService;
@@ -58,6 +59,8 @@ public interface ZmsClient extends AutoCloseable {
boolean deletePolicyRule(AthenzDomain athenzDomain, String athenzPolicy, String action, AthenzResourceName resourceName, AthenzRole athenzRole);
+ Optional<AthenzPolicy> getPolicy(AthenzDomain domain, String name);
+
Map<AthenzUser, String> listPendingRoleApprovals(AthenzRole athenzRole);
void approvePendingRoleMembership(AthenzRole athenzRole, AthenzUser athenzUser, Instant expiry, Optional<String> reason);
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zms/bindings/AssertionEntity.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zms/bindings/AssertionEntity.java
index 824aa3b4606..77f9af957aa 100644
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zms/bindings/AssertionEntity.java
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zms/bindings/AssertionEntity.java
@@ -16,7 +16,7 @@ public class AssertionEntity {
private final String role;
private final String resource;
private final String action;
- private final Integer id;
+ private final Long id;
public AssertionEntity(String role, String resource, String action) {
@@ -26,7 +26,7 @@ public class AssertionEntity {
public AssertionEntity(@JsonProperty("role") String role,
@JsonProperty("resource") String resource,
@JsonProperty("action") String action,
- @JsonProperty("id") Integer id) {
+ @JsonProperty("id") Long id) {
this.role = role;
this.resource = resource;
this.action = action;
@@ -46,7 +46,7 @@ public class AssertionEntity {
}
@JsonIgnore
- public int getId() {
+ public long getId() {
return id;
}
}