diff options
Diffstat (limited to 'athenz-identity-provider-service/src')
3 files changed, 87 insertions, 23 deletions
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGenerator.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGenerator.java index 950d2df9532..0abbb5a64f5 100644 --- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGenerator.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGenerator.java @@ -5,6 +5,7 @@ import com.google.inject.Inject; import com.yahoo.config.provision.Zone; import com.yahoo.net.HostName; import com.yahoo.vespa.athenz.api.AthenzService; +import com.yahoo.vespa.athenz.identityprovider.api.IdentityDocument; import com.yahoo.vespa.athenz.identityprovider.api.IdentityType; import com.yahoo.vespa.athenz.identityprovider.api.SignedIdentityDocument; import com.yahoo.vespa.athenz.identityprovider.api.VespaUniqueInstanceId; @@ -16,6 +17,7 @@ import com.yahoo.vespa.hosted.provision.Node; import com.yahoo.vespa.hosted.provision.NodeRepository; import com.yahoo.vespa.hosted.provision.node.Allocation; +import java.net.URI; import java.security.PrivateKey; import java.time.Instant; import java.util.HashSet; @@ -47,46 +49,57 @@ public class IdentityDocumentGenerator { } public SignedIdentityDocument generateSignedIdentityDocument(String hostname, IdentityType identityType) { + Node node = nodeRepository.getNode(hostname).orElseThrow(() -> new RuntimeException("Unable to find node " + hostname)); try { - Node node = nodeRepository.getNode(hostname).orElseThrow(() -> new RuntimeException("Unable to find node " + hostname)); - Allocation allocation = node.allocation().orElseThrow(() -> new RuntimeException("No allocation for node " + node.hostname())); - VespaUniqueInstanceId providerUniqueId = new VespaUniqueInstanceId( - allocation.membership().index(), - allocation.membership().cluster().id().value(), - allocation.owner().instance().value(), - allocation.owner().application().value(), - allocation.owner().tenant().value(), - zone.region().value(), - zone.environment().value(), - identityType); - - Set<String> ips = new HashSet<>(node.ipAddresses()); + IdentityDocument identityDocument = generateIdDocument(node, identityType); PrivateKey privateKey = keyProvider.getPrivateKey(zoneConfig.secretVersion()); AthenzService providerService = new AthenzService(zoneConfig.domain(), zoneConfig.serviceName()); - String configServerHostname = HostName.getLocalhost(); - Instant createdAt = Instant.now(); String signature = signer.generateSignature( - providerUniqueId, providerService, configServerHostname, - node.hostname(), createdAt, ips, identityType, privateKey); + identityDocument.providerUniqueId(), providerService, identityDocument.configServerHostname(), + identityDocument.instanceHostname(), identityDocument.createdAt(), identityDocument.ipAddresses(), identityType, privateKey); return new SignedIdentityDocument( + identityDocument, signature, SignedIdentityDocument.DEFAULT_KEY_VERSION, - providerUniqueId, + identityDocument.providerUniqueId(), + toZoneDnsSuffix(zone, zoneConfig.certDnsSuffix()), providerService, + URI.create(zoneConfig.ztsUrl()), SignedIdentityDocument.DEFAULT_DOCUMENT_VERSION, - configServerHostname, - node.hostname(), - createdAt, - ips, + identityDocument.configServerHostname(), + identityDocument.instanceHostname(), + identityDocument.createdAt(), + identityDocument.ipAddresses(), identityType); } catch (Exception e) { throw new RuntimeException("Exception generating identity document: " + e.getMessage(), e); } } + private IdentityDocument generateIdDocument(Node node, IdentityType identityType) { + Allocation allocation = node.allocation().orElseThrow(() -> new RuntimeException("No allocation for node " + node.hostname())); + VespaUniqueInstanceId providerUniqueId = new VespaUniqueInstanceId( + allocation.membership().index(), + allocation.membership().cluster().id().value(), + allocation.owner().instance().value(), + allocation.owner().application().value(), + allocation.owner().tenant().value(), + zone.region().value(), + zone.environment().value(), + identityType); + + Set<String> ips = new HashSet<>(node.ipAddresses()); + return new IdentityDocument( + providerUniqueId, + HostName.getLocalhost(), + node.hostname(), + Instant.now(), + ips); + } + private static String toZoneDnsSuffix(Zone zone, String dnsSuffix) { return zone.environment().value() + "-" + zone.region().value() + "." + dnsSuffix; } diff --git a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGeneratorTest.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGeneratorTest.java index 48e85f6047e..a1839ec62a2 100644 --- a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGeneratorTest.java +++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGeneratorTest.java @@ -87,6 +87,8 @@ public class IdentityDocumentGeneratorTest { String environment = "dev"; String region = "us-north-1"; + String expectedZoneDnsSuffix = environment + "-" + region + "." + dnsSuffix; + assertEquals(expectedZoneDnsSuffix, signedIdentityDocument.dnsSuffix()); VespaUniqueInstanceId expectedProviderUniqueId = new VespaUniqueInstanceId(0, "default", "default", "application", "tenant", region, environment, IdentityType.TENANT); diff --git a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java index 56777325231..04c4d4da51a 100644 --- a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java +++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java @@ -1,6 +1,8 @@ // 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.athenz.instanceproviderservice.instanceconfirmation; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableSet; import com.yahoo.config.model.api.ApplicationInfo; import com.yahoo.config.model.api.HostInfo; import com.yahoo.config.model.api.Model; @@ -8,8 +10,18 @@ import com.yahoo.config.model.api.ServiceInfo; import com.yahoo.config.model.api.SuperModel; import com.yahoo.config.model.api.SuperModelProvider; import com.yahoo.config.provision.ApplicationId; +import com.yahoo.vespa.athenz.identityprovider.api.EntityBindingsMapper; +import com.yahoo.vespa.athenz.identityprovider.api.bindings.IdentityDocumentEntity; +import com.yahoo.vespa.athenz.identityprovider.api.bindings.SignedIdentityDocumentEntity; +import com.yahoo.vespa.athenz.identityprovider.api.bindings.VespaUniqueInstanceIdEntity; +import com.yahoo.vespa.hosted.athenz.instanceproviderservice.impl.Utils; import org.junit.Test; +import java.net.URI; +import java.security.PrivateKey; +import java.security.Signature; +import java.time.Instant; +import java.util.Base64; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -28,7 +40,6 @@ import static org.mockito.Mockito.when; /** * @author valerijf - * @author bjorncs */ public class InstanceValidatorTest { @@ -82,6 +93,44 @@ public class InstanceValidatorTest { assertTrue(instanceValidator.isSameIdentityAsInServicesXml(applicationId, domain, service)); } + private static InstanceConfirmation createInstanceConfirmation(PrivateKey privateKey, ApplicationId applicationId, + String domain, String service) { + IdentityDocumentEntity identityDocument = new IdentityDocumentEntity( + new VespaUniqueInstanceIdEntity(applicationId.tenant().value(), applicationId.application().value(), + "environment", "region", applicationId.instance().value(), "cluster-id", 0), + "hostname", + "instance-hostname", + Instant.now(), + ImmutableSet.of("127.0.0.1", "::1")); + + try { + ObjectMapper mapper = Utils.getMapper(); + String encodedIdentityDocument = + Base64.getEncoder().encodeToString(mapper.writeValueAsString(identityDocument).getBytes()); + Signature sigGenerator = Signature.getInstance("SHA512withRSA"); + sigGenerator.initSign(privateKey); + sigGenerator.update(encodedIdentityDocument.getBytes()); + + return new InstanceConfirmation( + "provider", domain, service, + new SignedIdentityDocumentEntity(encodedIdentityDocument, + Base64.getEncoder().encodeToString(sigGenerator.sign()), + 0, + EntityBindingsMapper.toVespaUniqueInstanceId(identityDocument.providerUniqueId).asDottedString(), + "dnssuffix", + "service", + URI.create("http://localhost/zts"), + 1, + identityDocument.configServerHostname, + identityDocument.instanceHostname, + identityDocument.createdAt, + identityDocument.ipAddresses, + null)); // TODO Remove support for legacy representation without type + } catch (Exception e) { + throw new RuntimeException(e); + } + } + private SuperModelProvider mockSuperModelProvider(ApplicationInfo... appInfos) { SuperModel superModel = new SuperModel(Stream.of(appInfos) .collect(Collectors.groupingBy( |