diff options
author | Morten Tokle <mortent@yahooinc.com> | 2023-04-28 12:50:43 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-28 12:50:43 +0200 |
commit | 2e8ce5dae6330774ca69b679370f56447b129c89 (patch) | |
tree | 0b37afbda72121c529e320d5a70451af9c74d989 | |
parent | efebd9ea2938466b0f6912365cf9bbb7b6253541 (diff) | |
parent | e3353871e87f7ff24a9a35bb0eb7d70a7b357546 (diff) |
Merge pull request #26901 from vespa-engine/mortent/logforwarder-role-iddoc
Include roles from logfwarder config in identity document
8 files changed, 38 insertions, 13 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java index beb96ab8cc8..5ce5c2f64bf 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/LogForwarder.java @@ -52,6 +52,8 @@ public class LogForwarder extends AbstractService implements LogforwarderConfig. this.config = config; setProp("clustertype", "hosts"); setProp("clustername", "admin"); + // Make role information available in supermodel + Optional.ofNullable(config.role).map(r -> setProp("identity.role", r)); } public static Config cfg() { diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java index b07c2f14271..08a3285c9b4 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java @@ -407,7 +407,7 @@ public class Flags { "new_iddoc_layout", false, List.of("tokle", "bjorncs", "olaa"), "2023-04-24", "2023-05-31", "Whether to use new identity document layout", "Takes effect on node reboot", - HOSTNAME); + HOSTNAME, APPLICATION_ID, VESPA_VERSION); public static final UnboundBooleanFlag RANDOMIZED_ENDPOINT_NAMES = defineFeatureFlag( "randomized-endpoint-names", false, List.of("andreer"), "2023-04-26", "2023-06-30", diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java index 3ab1fdf211b..d5b48bc2609 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java @@ -363,8 +363,13 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer { Get the document version to ask for */ private int documentVersion(NodeAgentContext context) { + var version = context.node().currentVespaVersion() + .orElse(context.node().wantedVespaVersion().orElse(Version.emptyVersion)); + var appId = context.node().owner().orElse(ApplicationId.defaultId()); return useNewIdentityDocumentLayout .with(FetchVector.Dimension.HOSTNAME, context.hostname().value()) + .with(FetchVector.Dimension.VESPA_VERSION, version.toFullString()) + .with(FetchVector.Dimension.APPLICATION_ID, appId.serializedForm()) .value() ? SignedIdentityDocument.DEFAULT_DOCUMENT_VERSION : SignedIdentityDocument.LEGACY_DEFAULT_DOCUMENT_VERSION; diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapper.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapper.java index a695e10a29c..786a4213adf 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapper.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapper.java @@ -22,6 +22,7 @@ import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.time.Instant; import java.util.Base64; +import java.util.List; import java.util.Optional; import static com.yahoo.vespa.athenz.identityprovider.api.VespaUniqueInstanceId.fromDottedString; @@ -67,6 +68,7 @@ public class EntityBindingsMapper { Optional.ofNullable(docEntity.clusterType()).map(ClusterType::from).orElse(null), docEntity.ztsUrl(), Optional.ofNullable(docEntity.serviceIdentity()).map(AthenzIdentities::from).orElse(null), + List.of(), docEntity.unknownAttributes()); return new LegacySignedIdentityDocument( docEntity.signature(), @@ -146,6 +148,7 @@ public class EntityBindingsMapper { Optional.ofNullable(docEntity.clusterType()).map(ClusterType::from).orElse(null), docEntity.ztsUrl(), Optional.ofNullable(docEntity.serviceIdentity()).map(AthenzIdentities::from).orElse(null), + docEntity.roles(), docEntity.unknownAttributes()); } @@ -160,7 +163,8 @@ public class EntityBindingsMapper { identityDocument.identityType().id(), Optional.ofNullable(identityDocument.clusterType()).map(ClusterType::toConfigValue).orElse(null), identityDocument.ztsUrl(), - identityDocument.serviceIdentity().getFullName()); + identityDocument.serviceIdentity().getFullName(), + identityDocument.roles()); try { byte[] bytes = mapper.writeValueAsBytes(documentEntity); return Base64.getEncoder().encodeToString(bytes); diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/IdentityDocument.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/IdentityDocument.java index 577584db185..7caa4555f25 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/IdentityDocument.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/IdentityDocument.java @@ -6,7 +6,9 @@ import com.yahoo.vespa.athenz.api.AthenzService; import java.time.Instant; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; /** @@ -16,7 +18,7 @@ import java.util.Set; public record IdentityDocument(VespaUniqueInstanceId providerUniqueId, AthenzService providerService, String configServerHostname, String instanceHostname, Instant createdAt, Set<String> ipAddresses, IdentityType identityType, ClusterType clusterType, String ztsUrl, - AthenzIdentity serviceIdentity, Map<String, Object> unknownAttributes) { + AthenzIdentity serviceIdentity, List<String> roles, Map<String, Object> unknownAttributes) { public IdentityDocument { ipAddresses = Set.copyOf(ipAddresses); @@ -27,13 +29,14 @@ public record IdentityDocument(VespaUniqueInstanceId providerUniqueId, AthenzSer }); // Map.copyOf() does not allow null values unknownAttributes = Map.copyOf(nonNull); + roles = Optional.ofNullable(roles).orElse(List.of()); } public IdentityDocument(VespaUniqueInstanceId providerUniqueId, AthenzService providerService, String configServerHostname, String instanceHostname, Instant createdAt, Set<String> ipAddresses, IdentityType identityType, ClusterType clusterType, String ztsUrl, - AthenzIdentity serviceIdentity) { - this(providerUniqueId, providerService, configServerHostname, instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity, Map.of()); + AthenzIdentity serviceIdentity, List<String> roles) { + this(providerUniqueId, providerService, configServerHostname, instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity, roles, Map.of()); } @@ -49,6 +52,7 @@ public record IdentityDocument(VespaUniqueInstanceId providerUniqueId, AthenzSer this.clusterType, this.ztsUrl, athenzService, + roles, this.unknownAttributes); } } diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/IdentityDocumentEntity.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/IdentityDocumentEntity.java index 946eacc67eb..263708f1ace 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/IdentityDocumentEntity.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/IdentityDocumentEntity.java @@ -9,6 +9,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.time.Instant; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; @@ -19,7 +20,7 @@ import java.util.Set; @JsonInclude(JsonInclude.Include.NON_NULL) public record IdentityDocumentEntity(String providerUniqueId, String providerService, String configServerHostname, String instanceHostname, Instant createdAt, Set<String> ipAddresses, - String identityType, String clusterType, String ztsUrl, String serviceIdentity, Map<String, Object> unknownAttributes) { + String identityType, String clusterType, String ztsUrl, String serviceIdentity, List<String> roles, Map<String, Object> unknownAttributes) { @JsonCreator public IdentityDocumentEntity(@JsonProperty("provider-unique-id") String providerUniqueId, @@ -31,9 +32,10 @@ public record IdentityDocumentEntity(String providerUniqueId, String providerSer @JsonProperty("identity-type") String identityType, @JsonProperty("cluster-type") String clusterType, @JsonProperty("zts-url") String ztsUrl, - @JsonProperty("service-identity") String serviceIdentity) { + @JsonProperty("service-identity") String serviceIdentity, + @JsonProperty("roles") List<String> roles) { this(providerUniqueId, providerService, configServerHostname, - instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity, new HashMap<>()); + instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity, roles, new HashMap<>()); } @JsonProperty("provider-unique-id") @Override public String providerUniqueId() { return providerUniqueId; } @@ -46,6 +48,7 @@ public record IdentityDocumentEntity(String providerUniqueId, String providerSer @JsonProperty("cluster-type") @Override public String clusterType() { return clusterType; } @JsonProperty("zts-url") @Override public String ztsUrl() { return ztsUrl; } @JsonProperty("service-identity") @Override public String serviceIdentity() { return serviceIdentity; } + @JsonProperty("roles") @Override public List<String> roles() { return roles; } @JsonAnyGetter @Override public Map<String, Object> unknownAttributes() { return unknownAttributes; } @JsonAnySetter public void set(String name, Object value) { unknownAttributes.put(name, value); } } diff --git a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapperTest.java b/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapperTest.java index 513fb4cdbd3..02732033b75 100644 --- a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapperTest.java +++ b/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapperTest.java @@ -7,9 +7,11 @@ import org.junit.jupiter.api.Test; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Base64; +import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; /** @@ -47,6 +49,7 @@ class EntityBindingsMapperTest { assertTrue(json.contains(expectedMemberInJson), () -> "Expected JSON to contain '%s', but got \n'%s'".formatted(expectedMemberInJson, json)); assertEquals(EntityBindingsMapper.mapper.readTree(originalJson), EntityBindingsMapper.mapper.readTree(json)); + assertEquals(List.of(), entity.identityDocument().roles()); } @Test @@ -84,4 +87,6 @@ class EntityBindingsMapperTest { assertEquals(EntityBindingsMapper.mapper.readTree(originalJson), EntityBindingsMapper.mapper.readTree(json)); } + + }
\ No newline at end of file diff --git a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/client/IdentityDocumentSignerTest.java b/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/client/IdentityDocumentSignerTest.java index acb0905700f..334e0208c77 100644 --- a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/client/IdentityDocumentSignerTest.java +++ b/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/client/IdentityDocumentSignerTest.java @@ -19,6 +19,7 @@ import java.security.KeyPair; import java.time.Instant; import java.util.Arrays; import java.util.HashSet; +import java.util.List; import static com.yahoo.vespa.athenz.identityprovider.api.IdentityType.TENANT; import static com.yahoo.vespa.athenz.identityprovider.api.SignedIdentityDocument.LEGACY_DEFAULT_DOCUMENT_VERSION; @@ -44,13 +45,14 @@ public class IdentityDocumentSignerTest { private static final ClusterType clusterType = ClusterType.CONTAINER; private static final String ztsUrl = "https://foo"; private static final AthenzIdentity serviceIdentity = new AthenzService("vespa", "node"); + private static final List<String> roles = List.of(); @Test void legacy_generates_and_validates_signature() { IdentityDocumentSigner signer = new IdentityDocumentSigner(); IdentityDocument identityDocument = new IdentityDocument( id, providerService, configserverHostname, - instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity); + instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity, roles); String signature = signer.generateLegacySignature(identityDocument, keyPair.getPrivate()); @@ -65,7 +67,7 @@ public class IdentityDocumentSignerTest { IdentityDocumentSigner signer = new IdentityDocumentSigner(); IdentityDocument identityDocument = new IdentityDocument( id, providerService, configserverHostname, - instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity); + instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity, roles); String data = EntityBindingsMapper.toIdentityDocmentData(identityDocument); String signature = signer.generateSignature(data, keyPair.getPrivate()); @@ -81,10 +83,10 @@ public class IdentityDocumentSignerTest { IdentityDocumentSigner signer = new IdentityDocumentSigner(); IdentityDocument identityDocument = new IdentityDocument( id, providerService, configserverHostname, - instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity); + instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity, roles); IdentityDocument withoutIgnoredFields = new IdentityDocument( id, providerService, configserverHostname, - instanceHostname, createdAt, ipAddresses, identityType, null, null, serviceIdentity); + instanceHostname, createdAt, ipAddresses, identityType, null, null, serviceIdentity, roles); String signature = signer.generateLegacySignature(identityDocument, keyPair.getPrivate()); @@ -103,7 +105,7 @@ public class IdentityDocumentSignerTest { IdentityDocumentSigner signer = new IdentityDocumentSigner(); IdentityDocument identityDocument = new IdentityDocument( id, providerService, configserverHostname, - instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity); + instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity, roles); String signature = signer.generateLegacySignature(identityDocument, keyPair.getPrivate()); |