diff options
42 files changed, 317 insertions, 433 deletions
diff --git a/athenz-identity-provider-service/pom.xml b/athenz-identity-provider-service/pom.xml index bfd02d54d43..57339159e3d 100644 --- a/athenz-identity-provider-service/pom.xml +++ b/athenz-identity-provider-service/pom.xml @@ -14,67 +14,6 @@ <relativePath>../parent/pom.xml</relativePath> </parent> <dependencies> - <!-- COMPILE --> - <dependency> - <groupId>com.yahoo.athenz</groupId> - <artifactId>athenz-zms-java-client</artifactId> - <scope>compile</scope> - <exclusions> - <!-- Provided by JDisc / container-dev --> - <exclusion> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> - </exclusion> - <!--Exclude all Jersey bundles provided by JDisc--> - <exclusion> - <groupId>org.glassfish.jersey.core</groupId> - <artifactId>jersey-client</artifactId> - </exclusion> - <exclusion> - <groupId>org.glassfish.jersey.media</groupId> - <artifactId>jersey-media-json-jackson</artifactId> - </exclusion> - <!--Exclude all Jackson bundles provided by JDisc --> - <exclusion> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-core</artifactId> - </exclusion> - <exclusion> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - </exclusion> - <exclusion> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-annotations</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>com.yahoo.athenz</groupId> - <artifactId>athenz-zts-java-client</artifactId> - <scope>compile</scope> - <exclusions> - <!-- Provided by JDisc / container-dev --> - <exclusion> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> - </exclusion> - <!--Exclude all Jackson bundles provided by JDisc --> - <exclusion> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-core</artifactId> - </exclusion> - <exclusion> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - </exclusion> - <exclusion> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-annotations</artifactId> - </exclusion> - </exclusions> - </dependency> - <!-- PROVIDED --> <dependency> <groupId>com.yahoo.vespa</groupId> @@ -110,6 +49,30 @@ <version>${project.version}</version> <scope>provided</scope> </dependency> + <dependency> + <groupId>com.yahoo.vespa</groupId> + <artifactId>vespa-athenz</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + </dependency> + <dependency> + <groupId>org.bouncycastle</groupId> + <artifactId>bcpkix-jdk15on</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.bouncycastle</groupId> + <artifactId>bcprov-jdk15on</artifactId> + <scope>compile</scope> + </dependency> <!-- TEST --> <dependency> @@ -130,18 +93,6 @@ <scope>test</scope> </dependency> <dependency> - <groupId>org.apache.httpcomponents</groupId> - <artifactId>httpclient</artifactId> - <version>4.4.1</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.apache.httpcomponents</groupId> - <artifactId>httpcore</artifactId> - <version>4.4.1</version> - <scope>test</scope> - </dependency> - <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <scope>test</scope> diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/AthenzCredentials.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/AthenzCredentials.java index 790a7c54333..36c1aee49e0 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/AthenzCredentials.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/AthenzCredentials.java @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.jdisc.athenz.impl; +package com.yahoo.vespa.hosted.athenz.identityprovider; import java.security.KeyPair; import java.security.cert.X509Certificate; diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/AthenzCredentialsService.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/AthenzCredentialsService.java index 5786eb9e398..4072568d9d2 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/AthenzCredentialsService.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/AthenzCredentialsService.java @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.jdisc.athenz.impl; +package com.yahoo.vespa.hosted.athenz.identityprovider; import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.container.core.identity.IdentityConfig; diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/AthenzIdentityProviderImpl.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/AthenzIdentityProviderImpl.java index 3b2b065fa8c..18f90ce545f 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/AthenzIdentityProviderImpl.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/AthenzIdentityProviderImpl.java @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.jdisc.athenz.impl; +package com.yahoo.vespa.hosted.athenz.identityprovider; import com.google.inject.Inject; import com.yahoo.component.AbstractComponent; @@ -9,21 +9,11 @@ import com.yahoo.container.jdisc.athenz.AthenzIdentityProviderException; import com.yahoo.jdisc.Metric; import com.yahoo.log.LogLevel; import com.yahoo.vespa.defaults.Defaults; +import com.yahoo.vespa.athenz.api.AthenzIdentityCertificate; +import com.yahoo.vespa.athenz.tls.AthenzSslContextBuilder; -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import java.io.FileInputStream; -import java.io.IOException; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; +import java.io.File; import java.time.Clock; import java.time.Duration; import java.time.Instant; @@ -63,9 +53,8 @@ public final class AthenzIdentityProviderImpl extends AbstractComponent implemen static final String METRICS_UPDATER_TAG = "metrics-updater"; - private final AtomicReference<AthenzCredentials> credentials = new AtomicReference<>(); + private volatile AthenzCredentials credentials; private final AtomicReference<Throwable> lastThrowable = new AtomicReference<>(); - private final CountDownLatch credentialsRetrievedSignal = new CountDownLatch(1); private final AthenzCredentialsService athenzCredentialsService; private final Scheduler scheduler; private final Clock clock; @@ -97,26 +86,17 @@ public final class AthenzIdentityProviderImpl extends AbstractComponent implemen this.clock = clock; this.domain = config.domain(); this.service = config.service(); - scheduler.submit(new RegisterInstanceTask()); - scheduler.schedule(new TimeoutInitialWaitTask(), INITIAL_WAIT_NTOKEN); - metricUpdater = new CertificateExpiryMetricUpdater(metric); + registerInstance(); } - @Override - public String getNToken() { + private void registerInstance() { try { - credentialsRetrievedSignal.await(); - AthenzCredentials credentialsSnapshot = credentials.get(); - if (credentialsSnapshot == null) { - throw new AthenzIdentityProviderException("Could not retrieve Athenz credentials", lastThrowable.get()); - } - if (isExpired(credentialsSnapshot)) { - throw new AthenzIdentityProviderException("Athenz credentials are expired", lastThrowable.get()); - } - return credentialsSnapshot.getNToken(); - } catch (InterruptedException e) { - throw new AthenzIdentityProviderException("Failed to register instance credentials", lastThrowable.get()); + credentials = athenzCredentialsService.registerInstance(); + scheduler.schedule(new UpdateCredentialsTask(), UPDATE_PERIOD); + scheduler.submit(metricUpdater); + } catch (Throwable t) { + throw new AthenzIdentityProviderException("Could not retrieve Athenz credentials", t); } } @@ -131,49 +111,13 @@ public final class AthenzIdentityProviderImpl extends AbstractComponent implemen } @Override - public SSLContext getSslContext() { - try { - SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); - sslContext.init(createKeyManagersWithServiceCertificate(), - createTrustManagersWithAthenzCa(), - null); - return sslContext; - } catch (NoSuchAlgorithmException | KeyManagementException e) { - throw new RuntimeException(e); - } - } - - private KeyManager[] createKeyManagersWithServiceCertificate() { - try { - credentialsRetrievedSignal.await(); - KeyStore keyStore = KeyStore.getInstance("JKS"); - keyStore.load(null); - keyStore.setKeyEntry("instance-key", - credentials.get().getKeyPair().getPrivate(), - new char[0], - new Certificate[]{credentials.get().getCertificate()}); - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - keyManagerFactory.init(keyStore, new char[0]); - return keyManagerFactory.getKeyManagers(); - } catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException | IOException e) { - throw new RuntimeException(e); - } catch (InterruptedException e) { - throw new AthenzIdentityProviderException("Failed to register instance credentials", lastThrowable.get()); - } - } - - private static TrustManager[] createTrustManagersWithAthenzCa() { - try { - KeyStore trustStore = KeyStore.getInstance("JKS"); - try (FileInputStream in = new FileInputStream(Defaults.getDefaults().underVespaHome("share/ssl/certs/yahoo_certificate_bundle.jks"))) { - trustStore.load(in, null); - } - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - trustManagerFactory.init(trustStore); - return trustManagerFactory.getTrustManagers(); - } catch (CertificateException | IOException | KeyStoreException | NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } + public SSLContext getIdentitySslContext() { + return new AthenzSslContextBuilder() + .withIdentityCertificate(new AthenzIdentityCertificate( + credentials.getCertificate(), + credentials.getKeyPair().getPrivate())) + .withTrustStore(new File(Defaults.getDefaults().underVespaHome("share/ssl/certs/yahoo_certificate_bundle.jks")), "JKS") + .build(); } @Override @@ -189,56 +133,19 @@ public final class AthenzIdentityProviderImpl extends AbstractComponent implemen return credentials.getCreatedAt().plus(EXPIRES_AFTER).minus(EXPIRATION_MARGIN); } - private class RegisterInstanceTask implements RunnableWithTag { - - private final Duration backoffDelay; - - RegisterInstanceTask() { - this(INITIAL_BACKOFF_DELAY); - } - - RegisterInstanceTask(Duration backoffDelay) { - this.backoffDelay = backoffDelay; - } - - @Override - public void run() { - try { - credentials.set(athenzCredentialsService.registerInstance()); - credentialsRetrievedSignal.countDown(); - scheduler.schedule(new UpdateCredentialsTask(), UPDATE_PERIOD); - scheduler.submit(metricUpdater); - } catch (Throwable t) { - log.log(LogLevel.ERROR, "Failed to register instance: " + t.getMessage(), t); - lastThrowable.set(t); - Duration nextBackoffDelay = backoffDelay.multipliedBy(BACKOFF_DELAY_MULTIPLIER); - if (nextBackoffDelay.compareTo(MAX_REGISTER_BACKOFF_DELAY) > 0) { - nextBackoffDelay = MAX_REGISTER_BACKOFF_DELAY; - } - scheduler.schedule(new RegisterInstanceTask(nextBackoffDelay), backoffDelay); - } - } - - @Override - public String tag() { - return REGISTER_INSTANCE_TAG; - } - } - private class UpdateCredentialsTask implements RunnableWithTag { @Override public void run() { - AthenzCredentials currentCredentials = credentials.get(); try { - AthenzCredentials newCredentials = isExpired(currentCredentials) + AthenzCredentials newCredentials = isExpired(credentials) ? athenzCredentialsService.registerInstance() - : athenzCredentialsService.updateCredentials(currentCredentials); - credentials.set(newCredentials); + : athenzCredentialsService.updateCredentials(credentials); + credentials = newCredentials; scheduler.schedule(new UpdateCredentialsTask(), UPDATE_PERIOD); } catch (Throwable t) { log.log(LogLevel.WARNING, "Failed to update credentials: " + t.getMessage(), t); lastThrowable.set(t); - Duration timeToExpiration = Duration.between(clock.instant(), getExpirationTime(currentCredentials)); + Duration timeToExpiration = Duration.between(clock.instant(), getExpirationTime(credentials)); // NOTE: Update period might be after timeToExpiration, still we do not want to DDoS Athenz. Duration updatePeriod = timeToExpiration.compareTo(UPDATE_PERIOD) > 0 ? UPDATE_PERIOD : REDUCED_UPDATE_PERIOD; @@ -261,7 +168,7 @@ public final class AthenzIdentityProviderImpl extends AbstractComponent implemen @Override public void run() { - Instant expirationTime = getExpirationTime(credentials.get()); + Instant expirationTime = getExpirationTime(credentials); Duration remainingLifetime = Duration.between(clock.instant(), expirationTime); metric.set(CERTIFICATE_EXPIRY_METRIC_NAME, remainingLifetime.getSeconds(), null); scheduler.schedule(this, CERTIFICATE_EXPIRY_METRIC_UPDATE_PERIOD); @@ -273,18 +180,6 @@ public final class AthenzIdentityProviderImpl extends AbstractComponent implemen } } - private class TimeoutInitialWaitTask implements RunnableWithTag { - @Override - public void run() { - credentialsRetrievedSignal.countDown(); - } - - @Override - public String tag() { - return TIMEOUT_INITIAL_WAIT_TAG; - } - } - private static class ThreadPoolScheduler implements Scheduler { private static final Logger log = Logger.getLogger(ThreadPoolScheduler.class.getName()); diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/AthenzService.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/AthenzService.java index 898f90e3438..c9e3809ea96 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/AthenzService.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/AthenzService.java @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.jdisc.athenz.impl; +package com.yahoo.vespa.hosted.athenz.identityprovider; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/CryptoUtils.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/CryptoUtils.java index 388b40a1fe0..6a766e7c49d 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/CryptoUtils.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/CryptoUtils.java @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.jdisc.athenz.impl; +package com.yahoo.vespa.hosted.athenz.identityprovider; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.Extension; diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/IdentityDocumentService.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/IdentityDocumentService.java index 7878400964a..8a9137a491d 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/IdentityDocumentService.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/IdentityDocumentService.java @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.jdisc.athenz.impl; +package com.yahoo.vespa.hosted.athenz.identityprovider; import com.yahoo.vespa.defaults.Defaults; import org.apache.http.client.methods.CloseableHttpResponse; diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/InstanceIdentity.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/InstanceIdentity.java index 20bbb2aa67e..d6e986959cb 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/InstanceIdentity.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/InstanceIdentity.java @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.jdisc.athenz.impl; +package com.yahoo.vespa.hosted.athenz.identityprovider; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/InstanceRefreshInformation.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/InstanceRefreshInformation.java index dd893cb3143..d0c22d1d0d2 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/InstanceRefreshInformation.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/InstanceRefreshInformation.java @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.jdisc.athenz.impl; +package com.yahoo.vespa.hosted.athenz.identityprovider; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/InstanceRegisterInformation.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/InstanceRegisterInformation.java index e2355cb7a2d..dd9f164fef1 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/InstanceRegisterInformation.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/InstanceRegisterInformation.java @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.jdisc.athenz.impl; +package com.yahoo.vespa.hosted.athenz.identityprovider; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/SignedIdentityDocument.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/SignedIdentityDocument.java index 5d5b5430859..7bbd49c953f 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/SignedIdentityDocument.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/SignedIdentityDocument.java @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.jdisc.athenz.impl; +package com.yahoo.vespa.hosted.athenz.identityprovider; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/package-info.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/package-info.java index 2d7cbbb6315..1b4842327dd 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/impl/package-info.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/identityprovider/package-info.java @@ -3,6 +3,6 @@ * @author mortent */ @ExportPackage -package com.yahoo.container.jdisc.athenz.impl; +package com.yahoo.vespa.hosted.athenz.identityprovider; import com.yahoo.osgi.annotation.ExportPackage;
\ No newline at end of file diff --git a/container-disc/src/test/java/com/yahoo/container/jdisc/athenz/impl/AthenzIdentityProviderImplTest.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/identityprovider/AthenzIdentityProviderImplTest.java index 1ee23334a16..3a506a39c43 100644 --- a/container-disc/src/test/java/com/yahoo/container/jdisc/athenz/impl/AthenzIdentityProviderImplTest.java +++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/identityprovider/AthenzIdentityProviderImplTest.java @@ -1,14 +1,16 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.jdisc.athenz.impl; +package com.yahoo.vespa.hosted.athenz.identityprovider; import com.yahoo.container.core.identity.IdentityConfig; import com.yahoo.container.jdisc.athenz.AthenzIdentityProvider; -import com.yahoo.container.jdisc.athenz.impl.AthenzIdentityProviderImpl.RunnableWithTag; -import com.yahoo.container.jdisc.athenz.impl.AthenzIdentityProviderImpl.Scheduler; +import com.yahoo.container.jdisc.athenz.AthenzIdentityProviderException; +import com.yahoo.vespa.hosted.athenz.identityprovider.AthenzIdentityProviderImpl.RunnableWithTag; +import com.yahoo.vespa.hosted.athenz.identityprovider.AthenzIdentityProviderImpl.Scheduler; import com.yahoo.jdisc.Metric; import com.yahoo.test.ManualClock; import org.junit.Test; +import java.security.cert.X509Certificate; import java.time.Duration; import java.time.Instant; import java.util.ArrayList; @@ -23,15 +25,15 @@ import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; -import static com.yahoo.container.jdisc.athenz.impl.AthenzIdentityProviderImpl.INITIAL_BACKOFF_DELAY; -import static com.yahoo.container.jdisc.athenz.impl.AthenzIdentityProviderImpl.INITIAL_WAIT_NTOKEN; -import static com.yahoo.container.jdisc.athenz.impl.AthenzIdentityProviderImpl.MAX_REGISTER_BACKOFF_DELAY; -import static com.yahoo.container.jdisc.athenz.impl.AthenzIdentityProviderImpl.METRICS_UPDATER_TAG; -import static com.yahoo.container.jdisc.athenz.impl.AthenzIdentityProviderImpl.REDUCED_UPDATE_PERIOD; -import static com.yahoo.container.jdisc.athenz.impl.AthenzIdentityProviderImpl.REGISTER_INSTANCE_TAG; -import static com.yahoo.container.jdisc.athenz.impl.AthenzIdentityProviderImpl.TIMEOUT_INITIAL_WAIT_TAG; -import static com.yahoo.container.jdisc.athenz.impl.AthenzIdentityProviderImpl.UPDATE_CREDENTIALS_TAG; -import static com.yahoo.container.jdisc.athenz.impl.AthenzIdentityProviderImpl.UPDATE_PERIOD; +import static com.yahoo.vespa.hosted.athenz.identityprovider.AthenzIdentityProviderImpl.INITIAL_BACKOFF_DELAY; +import static com.yahoo.vespa.hosted.athenz.identityprovider.AthenzIdentityProviderImpl.INITIAL_WAIT_NTOKEN; +import static com.yahoo.vespa.hosted.athenz.identityprovider.AthenzIdentityProviderImpl.MAX_REGISTER_BACKOFF_DELAY; +import static com.yahoo.vespa.hosted.athenz.identityprovider.AthenzIdentityProviderImpl.METRICS_UPDATER_TAG; +import static com.yahoo.vespa.hosted.athenz.identityprovider.AthenzIdentityProviderImpl.REDUCED_UPDATE_PERIOD; +import static com.yahoo.vespa.hosted.athenz.identityprovider.AthenzIdentityProviderImpl.REGISTER_INSTANCE_TAG; +import static com.yahoo.vespa.hosted.athenz.identityprovider.AthenzIdentityProviderImpl.TIMEOUT_INITIAL_WAIT_TAG; +import static com.yahoo.vespa.hosted.athenz.identityprovider.AthenzIdentityProviderImpl.UPDATE_CREDENTIALS_TAG; +import static com.yahoo.vespa.hosted.athenz.identityprovider.AthenzIdentityProviderImpl.UPDATE_PERIOD; import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; @@ -46,77 +48,33 @@ public class AthenzIdentityProviderImplTest { private static final Metric DUMMY_METRIC = new Metric() { @Override - public void set(String s, Number number, Context context) {} + public void set(String s, Number number, Context context) { + } + @Override - public void add(String s, Number number, Context context) {} + public void add(String s, Number number, Context context) { + } + @Override - public Context createContext(Map<String, ?> stringMap) { return null; } + public Context createContext(Map<String, ?> stringMap) { + return null; + } }; private static final IdentityConfig IDENTITY_CONFIG = new IdentityConfig(new IdentityConfig.Builder() .service("tenantService").domain("tenantDomain").loadBalancerAddress("cfg")); - private final Set<String> IGNORED_TASKS = Stream.of(UPDATE_CREDENTIALS_TAG, METRICS_UPDATER_TAG) - .collect(Collectors.toSet()); - - @Test - public void athenz_credentials_are_retrieved_after_component_contruction_completed() { - IdentityDocumentService identityDocumentService = mock(IdentityDocumentService.class); - AthenzService athenzService = mock(AthenzService.class); - ManualClock clock = new ManualClock(Instant.EPOCH); - MockScheduler scheduler = new MockScheduler(clock); - - when(identityDocumentService.getSignedIdentityDocument()).thenReturn(getIdentityDocument()); - when(athenzService.sendInstanceRegisterRequest(any(), any())).thenReturn( - new InstanceIdentity(null, "TOKEN")); - AthenzCredentialsService credentialService = - new AthenzCredentialsService(IDENTITY_CONFIG, identityDocumentService, athenzService, clock); - - AthenzIdentityProvider identityProvider = - new AthenzIdentityProviderImpl(IDENTITY_CONFIG, DUMMY_METRIC, credentialService, scheduler, clock); - - List<MockScheduler.CompletedTask> expectedTasks = - Arrays.asList( - new MockScheduler.CompletedTask(REGISTER_INSTANCE_TAG, Duration.ZERO), - new MockScheduler.CompletedTask(TIMEOUT_INITIAL_WAIT_TAG, INITIAL_WAIT_NTOKEN)); - // Don't run update credential tasks, otherwise infinite loop - List<MockScheduler.CompletedTask> completedTasks = - scheduler.runAllTasks(task -> !IGNORED_TASKS.contains(task.tag())); - assertEquals(expectedTasks, completedTasks); - assertEquals("TOKEN", identityProvider.getNToken()); - } - - @Test - public void register_instance_uses_exponential_backoff() { + @Test (expected = AthenzIdentityProviderException.class) + public void component_creation_fails_when_credentials_not_found() { AthenzCredentialsService credentialService = mock(AthenzCredentialsService.class); when(credentialService.registerInstance()) - .thenThrow(new RuntimeException("#1")) - .thenThrow(new RuntimeException("#2")) - .thenThrow(new RuntimeException("#3")) - .thenThrow(new RuntimeException("#4")) - .thenThrow(new RuntimeException("#5")) - .thenReturn(new AthenzCredentials("TOKEN", null, null, null, Instant.now())); + .thenThrow(new RuntimeException("athenz unavailable")); ManualClock clock = new ManualClock(Instant.EPOCH); MockScheduler scheduler = new MockScheduler(clock); AthenzIdentityProvider identityProvider = new AthenzIdentityProviderImpl(IDENTITY_CONFIG, DUMMY_METRIC, credentialService, scheduler, clock); - - List<MockScheduler.CompletedTask> expectedTasks = - Arrays.asList( - new MockScheduler.CompletedTask(REGISTER_INSTANCE_TAG, Duration.ZERO), - new MockScheduler.CompletedTask(REGISTER_INSTANCE_TAG, INITIAL_BACKOFF_DELAY), - new MockScheduler.CompletedTask(TIMEOUT_INITIAL_WAIT_TAG, INITIAL_WAIT_NTOKEN), - new MockScheduler.CompletedTask(REGISTER_INSTANCE_TAG, INITIAL_BACKOFF_DELAY.multipliedBy(2)), - new MockScheduler.CompletedTask(REGISTER_INSTANCE_TAG, INITIAL_BACKOFF_DELAY.multipliedBy(4)), - new MockScheduler.CompletedTask(REGISTER_INSTANCE_TAG, INITIAL_BACKOFF_DELAY.multipliedBy(8)), - new MockScheduler.CompletedTask(REGISTER_INSTANCE_TAG, MAX_REGISTER_BACKOFF_DELAY)); - // Don't run update credential tasks, otherwise infinite loop - List<MockScheduler.CompletedTask> completedTasks = - scheduler.runAllTasks(task -> !IGNORED_TASKS.contains(task.tag())); - assertEquals(expectedTasks, completedTasks); - assertEquals("TOKEN", identityProvider.getNToken()); } @Test @@ -125,6 +83,7 @@ public class AthenzIdentityProviderImplTest { AthenzService athenzService = mock(AthenzService.class); ManualClock clock = new ManualClock(Instant.EPOCH); MockScheduler scheduler = new MockScheduler(clock); + X509Certificate x509Certificate = mock(X509Certificate.class); when(identityDocumentService.getSignedIdentityDocument()).thenReturn(getIdentityDocument()); when(athenzService.sendInstanceRegisterRequest(any(), any())).thenReturn( @@ -143,8 +102,6 @@ public class AthenzIdentityProviderImplTest { List<MockScheduler.CompletedTask> expectedTasks = Arrays.asList( - new MockScheduler.CompletedTask(REGISTER_INSTANCE_TAG, Duration.ZERO), - new MockScheduler.CompletedTask(TIMEOUT_INITIAL_WAIT_TAG, INITIAL_WAIT_NTOKEN), new MockScheduler.CompletedTask(UPDATE_CREDENTIALS_TAG, UPDATE_PERIOD), new MockScheduler.CompletedTask(UPDATE_CREDENTIALS_TAG, UPDATE_PERIOD), new MockScheduler.CompletedTask(UPDATE_CREDENTIALS_TAG, REDUCED_UPDATE_PERIOD), @@ -153,9 +110,8 @@ public class AthenzIdentityProviderImplTest { AtomicInteger counter = new AtomicInteger(0); List<MockScheduler.CompletedTask> completedTasks = scheduler.runAllTasks(task -> !task.tag().equals(METRICS_UPDATER_TAG) && - counter.getAndIncrement() < expectedTasks.size()); + counter.getAndIncrement() < expectedTasks.size()); assertEquals(expectedTasks, completedTasks); - assertEquals("TOKEN", identityProvider.getNToken()); } private static String getIdentityDocument() { @@ -232,7 +188,7 @@ public class AthenzIdentityProviderImplTest { if (o == null || getClass() != o.getClass()) return false; CompletedTask that = (CompletedTask) o; return Objects.equals(tag, that.tag) && - Objects.equals(delay, that.delay); + Objects.equals(delay, that.delay); } @Override @@ -243,9 +199,9 @@ public class AthenzIdentityProviderImplTest { @Override public String toString() { return "CompletedTask{" + - "tag='" + tag + '\'' + - ", delay=" + delay + - '}'; + "tag='" + tag + '\'' + + ", delay=" + delay + + '}'; } } } diff --git a/container-disc/src/test/java/com/yahoo/container/jdisc/athenz/impl/CryptoUtilsTest.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/identityprovider/CryptoUtilsTest.java index dc9690355e8..0412b9071dd 100644 --- a/container-disc/src/test/java/com/yahoo/container/jdisc/athenz/impl/CryptoUtilsTest.java +++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/identityprovider/CryptoUtilsTest.java @@ -1,5 +1,5 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.container.jdisc.athenz.impl; +package com.yahoo.vespa.hosted.athenz.identityprovider; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.junit.Test; diff --git a/build_settings.cmake b/build_settings.cmake index 2cccea9b64f..7616ff63ad9 100644 --- a/build_settings.cmake +++ b/build_settings.cmake @@ -81,6 +81,11 @@ else() set (VESPA_BOOST_LIB_SUFFIX "-mt-d") endif() +if(VESPA_USER) +else() + set(VESPA_USER "vespa") +endif() + if(EXTRA_INCLUDE_DIRECTORY) include_directories(SYSTEM ${EXTRA_INCLUDE_DIRECTORY}) endif() diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/IdentityProvider.java b/config-model/src/main/java/com/yahoo/vespa/model/container/IdentityProvider.java index 0368f7eaf3e..640a85d9b50 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/IdentityProvider.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/IdentityProvider.java @@ -5,14 +5,13 @@ import com.yahoo.config.provision.AthenzDomain; import com.yahoo.config.provision.AthenzService; import com.yahoo.config.provision.HostName; import com.yahoo.container.core.identity.IdentityConfig; -import com.yahoo.container.jdisc.athenz.impl.AthenzIdentityProviderImpl; import com.yahoo.vespa.model.container.component.SimpleComponent; /** * @author mortent */ public class IdentityProvider extends SimpleComponent implements IdentityConfig.Producer { - public static final String CLASS = AthenzIdentityProviderImpl.class.getName(); + public static final String CLASS = "com.yahoo.vespa.hosted.athenz.identityprovider.AthenzIdentityProviderImpl"; private final AthenzDomain domain; private final AthenzService service; diff --git a/config-model/src/main/perl/vespa-deploy b/config-model/src/main/perl/vespa-deploy index 9f8277998f2..aea97bebb96 100755 --- a/config-model/src/main/perl/vespa-deploy +++ b/config-model/src/main/perl/vespa-deploy @@ -144,53 +144,48 @@ $session_id_file = "$cloudconfig_dir/$tenant/deploy-session-id"; my $command = shift; -given($command) { - when ("upload") { - my $application_package = shift; - if (!$opt_F) { - if (!$application_package) { - print "Command failed. No application package specified\n"; - usage("upload"); - exit 1; - } - if (!(-e $application_package)) { - print "Command failed. No such directory found: '$application_package'\n"; - exit 1; - } - check_application_directory($application_package); +if ($command eq "upload") { + my $application_package = shift; + if (!$opt_F) { + if (!$application_package) { + print "Command failed. No application package specified\n"; + usage("upload"); + exit 1; } - - do_http_request("upload", $application_package); - } - when ("prepare") { - my $arg = shift; - if ($arg && looks_like_number($arg) && !(-d $arg)) { - do_http_request("prepare", "", $arg); - } elsif ($arg) { - check_application_directory($arg); - do_http_request("upload", $arg); - do_http_request("prepare"); - } else { - do_http_request("prepare"); - } - } - when ("activate") { - my $session_id = shift; - do_http_request("activate", "", $session_id); - } - when ("fetch") { - my $arg = shift; - if ($arg) { - fetch_active_application($arg); - } else { - usage("fetch", $arg); - } + if (!(-e $application_package)) { + print "Command failed. No such directory found: '$application_package'\n"; + exit 1; + } + check_application_directory($application_package); } - when ("help") { + + do_http_request("upload", $application_package); +} elsif ($command eq "prepare") { my $arg = shift; - usage($command, $arg); - } - default { usage($command); } + if ($arg && looks_like_number($arg) && !(-d $arg)) { + do_http_request("prepare", "", $arg); + } elsif ($arg) { + check_application_directory($arg); + do_http_request("upload", $arg); + do_http_request("prepare"); + } else { + do_http_request("prepare"); + } +} elsif ($command eq "activate") { + my $session_id = shift; + do_http_request("activate", "", $session_id); +} elsif ($command eq "fetch") { + my $arg = shift; + if ($arg) { + fetch_active_application($arg); + } else { + usage("fetch", $arg); + } +} elsif ($command eq "help") { + my $arg = shift; + usage($command, $arg); +} else { + usage($command); } @@ -214,17 +209,19 @@ sub usage { $command = $arg; } - given($command) { - when ("upload") { usage_upload(); } - when ("prepare") { usage_prepare(); } - when ("activate") { usage_activate(); } - when ("fetch") { usage_fetch(); } - default { - print "Usage: vespa-deploy [-h] [-v] [-f] [-t] [-p] [<command>] [args]\n"; - print "Supported commands: 'upload', 'prepare', 'activate', 'fetch' and 'help'\n"; - print "Supported options: '-h' (help), '-v' (verbose), '-f' (force/ignore validation errors), '-t' (timeout in seconds), '-p' (config server http port)\n"; - print "Try 'vespa-deploy help <command>' to get more help\n"; - } + if ($command eq "upload") { + usage_upload(); + } elsif ($command eq "prepare") { + usage_prepare(); + } elsif ($command eq "activate") { + usage_activate(); + } elsif ($command eq "fetch") { + usage_fetch(); + } else { + print "Usage: vespa-deploy [-h] [-v] [-f] [-t] [-p] [<command>] [args]\n"; + print "Supported commands: 'upload', 'prepare', 'activate', 'fetch' and 'help'\n"; + print "Supported options: '-h' (help), '-v' (verbose), '-f' (force/ignore validation errors), '-t' (timeout in seconds), '-p' (config server http port)\n"; + print "Try 'vespa-deploy help <command>' to get more help\n"; } } @@ -340,18 +337,14 @@ sub do_http_request { my $output; my $exitcode = 1; - given($command) { - when ("upload") { - ($exitcode, $output) = http_upload(\@configsources, $configsource_url, $application_package); - } - when ("prepare") { - $output = http_prepare($configsource_url, $supplied_session_id); - $exitcode = $? >> 8; - } - when ("activate") { - $output = http_activate($configsource_url, $supplied_session_id); - $exitcode = $? >> 8; - } + if ($command eq "upload") { + ($exitcode, $output) = http_upload(\@configsources, $configsource_url, $application_package); + } elsif ($command eq "prepare") { + $output = http_prepare($configsource_url, $supplied_session_id); + $exitcode = $? >> 8; + } elsif ($command eq "activate") { + $output = http_activate($configsource_url, $supplied_session_id); + $exitcode = $? >> 8; } my $response; diff --git a/config-proxy/src/main/sh/vespa-config-ctl.sh b/config-proxy/src/main/sh/vespa-config-ctl.sh index db96fe0eadb..407b3179a88 100755 --- a/config-proxy/src/main/sh/vespa-config-ctl.sh +++ b/config-proxy/src/main/sh/vespa-config-ctl.sh @@ -110,7 +110,7 @@ case $1 in echo "Waiting for config proxy to start" fail=true for ((sleepcount=0;$sleepcount<600;sleepcount=$sleepcount+1)) ; do - usleep 100000 + sleep 0.1 if [ -f $P_CONFIG_PROXY ] && kill -0 `cat $P_CONFIG_PROXY` && vespa-ping-configproxy -s $hname 2>/dev/null then echo "config proxy started (runserver pid `cat $P_CONFIG_PROXY`)" diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileServer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileServer.java index dbd8fdda052..c9859cc79d3 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileServer.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileServer.java @@ -107,7 +107,7 @@ public class FileServer { private void serveFile(FileReference reference, Receiver target) { File file = root.getFile(reference); - log.log(LogLevel.DEBUG, "Start serving reference '" + reference.value() + "' with file '" + file.getAbsolutePath() + "'"); + log.log(LogLevel.DEBUG, () -> "Start serving reference '" + reference.value() + "' with file '" + file.getAbsolutePath() + "'"); boolean success = false; String errorDescription = "OK"; FileReferenceData fileData = FileReferenceDataBlob.empty(reference, file.getName()); @@ -141,7 +141,7 @@ public class FileServer { private void serveFile(String fileReference, Request request, Receiver receiver) { FileApiErrorCodes result; try { - log.log(LogLevel.DEBUG, "Received request for reference '" + fileReference + "'"); + log.log(LogLevel.DEBUG, () -> "Received request for reference '" + fileReference + "'"); result = hasFile(fileReference) ? FileApiErrorCodes.OK : FileApiErrorCodes.NOT_FOUND; diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/Ckms.java b/container-disc/src/main/java/com/yahoo/container/jdisc/Ckms.java new file mode 100644 index 00000000000..26c71686a82 --- /dev/null +++ b/container-disc/src/main/java/com/yahoo/container/jdisc/Ckms.java @@ -0,0 +1,14 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +package com.yahoo.container.jdisc; + +/** + * @author mortent + */ +public interface Ckms { + /** Returns the secret for this key */ + String getSecret(String key); + + /** Returns the secret for this key and version */ + String getSecret(String key, int version); +} diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/AthenzIdentityProvider.java b/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/AthenzIdentityProvider.java index c4c57f4bc47..b7190927d11 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/AthenzIdentityProvider.java +++ b/container-disc/src/main/java/com/yahoo/container/jdisc/athenz/AthenzIdentityProvider.java @@ -7,8 +7,7 @@ import javax.net.ssl.SSLContext; * @author mortent */ public interface AthenzIdentityProvider { - String getNToken() throws AthenzIdentityProviderException; String getDomain(); String getService(); - SSLContext getSslContext(); + SSLContext getIdentitySslContext(); } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilter.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilter.java index 13707772244..fddc2bb6fa1 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilter.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilter.java @@ -3,11 +3,11 @@ package com.yahoo.vespa.hosted.controller.restapi.filter; import com.google.inject.Inject; import com.yahoo.config.provision.ApplicationName; +import com.yahoo.jdisc.Response; import com.yahoo.jdisc.handler.ResponseHandler; import com.yahoo.jdisc.http.HttpRequest.Method; import com.yahoo.jdisc.http.filter.DiscFilterRequest; import com.yahoo.jdisc.http.filter.SecurityRequestFilter; -import com.yahoo.log.LogLevel; import com.yahoo.vespa.athenz.api.AthenzIdentity; import com.yahoo.vespa.athenz.api.AthenzPrincipal; import com.yahoo.vespa.hosted.controller.Controller; @@ -27,7 +27,6 @@ import javax.ws.rs.WebApplicationException; import java.util.Arrays; import java.util.List; import java.util.Optional; -import java.util.logging.Logger; import static com.yahoo.jdisc.http.HttpRequest.Method.GET; import static com.yahoo.jdisc.http.HttpRequest.Method.HEAD; @@ -61,7 +60,7 @@ public class ControllerAuthorizationFilter implements SecurityRequestFilter { Controller controller, EntityService entityService, ZoneRegistry zoneRegistry) { - this(clientFactory, controller, entityService, zoneRegistry, new LoggingAuthorizationResponseHandler()); + this(clientFactory, controller, entityService, zoneRegistry, new DefaultAuthorizationResponseHandler()); } ControllerAuthorizationFilter(AthenzClientFactory clientFactory, @@ -197,27 +196,10 @@ public class ControllerAuthorizationFilter implements SecurityRequestFilter { .map(AthenzPrincipal.class::cast); } - private static class LoggingAuthorizationResponseHandler implements AuthorizationResponseHandler { - - @SuppressWarnings("LoggerInitializedWithForeignClass") - private static final Logger log = Logger.getLogger(ControllerAuthorizationFilter.class.getName()); - - @Override - public void handle(ResponseHandler responseHandler, - DiscFilterRequest request, - WebApplicationException exception) { - log.log(LogLevel.WARNING, - String.format("Access denied (%d): '%s'\nPath: %s\nIdentity: %s", - exception.getResponse().getStatus(), - exception.getMessage(), - request.getRequestURI(), - getPrincipal(request).map(p -> p.getIdentity().getFullName()).orElse("[none]"))); - } - } - - // TODO Use this as default once we are confident that the access control does not block legal operations - @SuppressWarnings("unused") - static class HttpRespondingAuthorizationResponseHandler implements AuthorizationResponseHandler { + /** + * Maps {@link WebApplicationException} to http response ({@link Response}. + */ + static class DefaultAuthorizationResponseHandler implements AuthorizationResponseHandler { @Override public void handle(ResponseHandler responseHandler, DiscFilterRequest request, diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java index fe1718de135..ff4ceae1c8e 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java @@ -17,7 +17,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.athenz.ApplicationActio import com.yahoo.vespa.hosted.controller.api.integration.athenz.HostedAthenzIdentities; import com.yahoo.vespa.hosted.controller.athenz.mock.AthenzClientFactoryMock; import com.yahoo.vespa.hosted.controller.athenz.mock.AthenzDbMock; -import com.yahoo.vespa.hosted.controller.restapi.filter.ControllerAuthorizationFilter.HttpRespondingAuthorizationResponseHandler; +import com.yahoo.vespa.hosted.controller.restapi.filter.ControllerAuthorizationFilter.DefaultAuthorizationResponseHandler; import org.junit.Test; import java.io.IOException; @@ -149,7 +149,7 @@ public class ControllerAuthorizationFilterTest { controllerTester.controller(), controllerTester.entityService(), controllerTester.zoneRegistry(), - new HttpRespondingAuthorizationResponseHandler()); + new DefaultAuthorizationResponseHandler()); } private static Optional<AuthorizationResponse> invokeFilter(ControllerAuthorizationFilter filter, diff --git a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/CompressedFileReference.java b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/CompressedFileReference.java index 27ada7532f5..c4cd2a073c1 100644 --- a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/CompressedFileReference.java +++ b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/CompressedFileReference.java @@ -63,7 +63,7 @@ public class CompressedFileReference { } static void decompress(File inputFile, File outputDir) throws IOException { - log.log(LogLevel.DEBUG, "Decompressing '" + inputFile + "' into '" + outputDir + "'"); + log.log(LogLevel.DEBUG, () -> "Decompressing '" + inputFile + "' into '" + outputDir + "'"); ArchiveInputStream ais = new TarArchiveInputStream(new GZIPInputStream(new FileInputStream(inputFile))); decompress(ais, outputDir); ais.close(); @@ -77,7 +77,7 @@ public class CompressedFileReference { File outFile = new File(outputFile, entry.getName()); if (entry.isDirectory()) { if (!(outFile.exists() && outFile.isDirectory())) { - log.log(LogLevel.DEBUG, "Creating dir: " + outFile.getAbsolutePath()); + log.log(LogLevel.DEBUG, () -> "Creating dir: " + outFile.getAbsolutePath()); if (!outFile.mkdirs()) { log.log(LogLevel.WARNING, "Could not create dir " + entry.getName()); } @@ -111,7 +111,7 @@ public class CompressedFileReference { } private static void writeFileToTar(ArchiveOutputStream taos, File baseDir, File file) throws IOException { - log.log(LogLevel.DEBUG, "Adding file to tar: " + baseDir.toPath().relativize(file.toPath()).toString()); + log.log(LogLevel.DEBUG, () -> "Adding file to tar: " + baseDir.toPath().relativize(file.toPath()).toString()); taos.putArchiveEntry(taos.createArchiveEntry(file, baseDir.toPath().relativize(file.toPath()).toString())); ByteStreams.copy(new FileInputStream(file), taos); taos.closeArchiveEntry(); diff --git a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileDistributionRpcServer.java b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileDistributionRpcServer.java index 3e81321f92e..f24d76fe8be 100644 --- a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileDistributionRpcServer.java +++ b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileDistributionRpcServer.java @@ -115,12 +115,12 @@ public class FileDistributionRpcServer { private void downloadFile(Request req) { FileReference fileReference = new FileReference(req.parameters().get(0).asString()); - log.log(LogLevel.DEBUG, "getFile() called for file reference '" + fileReference.value() + "'"); + log.log(LogLevel.DEBUG, () -> "getFile() called for file reference '" + fileReference.value() + "'"); Optional<File> pathToFile = downloader.getFile(fileReference); try { if (pathToFile.isPresent()) { req.returnValues().add(new StringValue(pathToFile.get().getAbsolutePath())); - log.log(LogLevel.DEBUG, "File reference '" + fileReference.value() + "' available at " + pathToFile.get()); + log.log(LogLevel.DEBUG, () -> "File reference '" + fileReference.value() + "' available at " + pathToFile.get()); } else { log.log(LogLevel.INFO, "File reference '" + fileReference.value() + "' not found, returning error"); req.setError(fileReferenceDoesNotExists, "File reference '" + fileReference.value() + "' not found"); diff --git a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileDownloader.java b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileDownloader.java index 5655d69593c..bed38bdcac6 100644 --- a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileDownloader.java +++ b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileDownloader.java @@ -57,7 +57,7 @@ public class FileDownloader { private Future<Optional<File>> getFutureFile(FileReference fileReference) { Objects.requireNonNull(fileReference, "file reference cannot be null"); File directory = new File(downloadDirectory, fileReference.value()); - log.log(LogLevel.DEBUG, "Checking if there is a file in '" + directory.getAbsolutePath() + "' "); + log.log(LogLevel.DEBUG, () -> "Checking if there is a file in '" + directory.getAbsolutePath() + "' "); Optional<File> file = getFileFromFileSystem(fileReference, directory); if (file.isPresent()) { @@ -65,7 +65,7 @@ public class FileDownloader { future.set(file); return future; } else { - log.log(LogLevel.INFO, "File reference '" + fileReference.value() + "' not found in " + + log.log(LogLevel.DEBUG, () -> "File reference '" + fileReference.value() + "' not found in " + directory.getAbsolutePath() + ", starting download"); return queueForAsyncDownload(fileReference, timeout); } @@ -75,7 +75,7 @@ public class FileDownloader { public void queueForAsyncDownload(List<FileReference> fileReferences) { fileReferences.forEach(fileReference -> { if (fileReferenceDownloader.isDownloading(fileReference)) { - log.log(LogLevel.DEBUG, "Already downloading '" + fileReference.value() + "'"); + log.log(LogLevel.DEBUG, () -> "Already downloading '" + fileReference.value() + "'"); } else { queueForAsyncDownload(fileReference); } @@ -117,12 +117,12 @@ public class FileDownloader { private synchronized Future<Optional<File>> queueForAsyncDownload(FileReference fileReference, Duration timeout) { Future<Optional<File>> inProgress = fileReferenceDownloader.addDownloadListener(fileReference, () -> getFile(fileReference)); if (inProgress != null) { - log.log(LogLevel.DEBUG, "Already downloading '" + fileReference.value() + "'"); + log.log(LogLevel.DEBUG, () -> "Already downloading '" + fileReference.value() + "'"); return inProgress; } Future<Optional<File>> future = queueForAsyncDownload(fileReference); - log.log(LogLevel.INFO, "Queued '" + fileReference.value() + "' for download with timeout " + timeout); + log.log(LogLevel.DEBUG, () -> "Queued '" + fileReference.value() + "' for download with timeout " + timeout); return future; } diff --git a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReceiver.java b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReceiver.java index a580759b03b..83cf4e1ad80 100644 --- a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReceiver.java +++ b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReceiver.java @@ -113,7 +113,7 @@ public class FileReceiver { // Unpack if necessary if (fileType == FileReferenceData.Type.compressed) { File decompressedDir = Files.createTempDirectory(tmpDir.toPath(), "archive").toFile(); - log.log(LogLevel.DEBUG, "Archived file, unpacking " + inprogressFile + " to " + decompressedDir); + log.log(LogLevel.DEBUG, () -> "Archived file, unpacking " + inprogressFile + " to " + decompressedDir); CompressedFileReference.decompress(inprogressFile, decompressedDir); moveFileToDestination(decompressedDir, fileReferenceDir); } else { @@ -123,7 +123,7 @@ public class FileReceiver { log.log(LogLevel.ERROR, "Failed creating directory (" + fileReferenceDir.toPath() + "): " + e.getMessage(), e); throw new RuntimeException("Failed creating directory (" + fileReferenceDir.toPath() + "): ", e); } - log.log(LogLevel.DEBUG, "Uncompressed file, moving to " + file.getAbsolutePath()); + log.log(LogLevel.DEBUG, () -> "Uncompressed file, moving to " + file.getAbsolutePath()); moveFileToDestination(inprogressFile, file); } } catch (IOException e) { @@ -202,11 +202,11 @@ public class FileReceiver { // Unpack if necessary if (fileReferenceData.type() == FileReferenceData.Type.compressed) { File decompressedDir = Files.createTempDirectory(tempDownloadedDir.toPath(), "decompressed").toFile(); - log.log(LogLevel.DEBUG, "Compressed file, unpacking " + tempFile + " to " + decompressedDir); + log.log(LogLevel.DEBUG, () -> "Compressed file, unpacking " + tempFile + " to " + decompressedDir); CompressedFileReference.decompress(tempFile, decompressedDir); moveFileToDestination(decompressedDir, fileReferenceDir); } else { - log.log(LogLevel.DEBUG, "Uncompressed file, moving to " + file.getAbsolutePath()); + log.log(LogLevel.DEBUG, () -> "Uncompressed file, moving to " + file.getAbsolutePath()); Files.createDirectories(fileReferenceDir.toPath()); moveFileToDestination(tempFile, file); } @@ -220,11 +220,11 @@ public class FileReceiver { private static void moveFileToDestination(File tempFile, File destination) { try { Files.move(tempFile.toPath(), destination.toPath()); - log.log(LogLevel.DEBUG, "File moved from " + tempFile.getAbsolutePath()+ " to " + destination.getAbsolutePath()); + log.log(LogLevel.DEBUG, () -> "File moved from " + tempFile.getAbsolutePath()+ " to " + destination.getAbsolutePath()); } catch (FileAlreadyExistsException e) { // Don't fail if it already exists (we might get the file from several config servers when retrying, servers are down etc. // so it might be written already). Delete temp file in that case, to avoid filling the disk. - log.log(LogLevel.DEBUG, "File '" + destination.getAbsolutePath() + "' already exists, continuing: " + e.getMessage()); + log.log(LogLevel.DEBUG, () -> "File '" + destination.getAbsolutePath() + "' already exists, continuing: " + e.getMessage()); try { Files.delete(tempFile.toPath()); } catch (IOException ioe) { /* ignore failure */} @@ -237,7 +237,7 @@ public class FileReceiver { @SuppressWarnings({"UnusedDeclaration"}) public final void receiveFileMeta(Request req) { - log.log(LogLevel.DEBUG, "Received method call '" + req.methodName() + "' with parameters : " + req.parameters()); + log.log(LogLevel.DEBUG, () -> "Received method call '" + req.methodName() + "' with parameters : " + req.parameters()); FileReference reference = new FileReference(req.parameters().get(0).asString()); String fileName = req.parameters().get(1).asString(); String type = req.parameters().get(2).asString(); @@ -263,7 +263,7 @@ public class FileReceiver { @SuppressWarnings({"UnusedDeclaration"}) public final void receiveFilePart(Request req) { - log.log(LogLevel.DEBUG, "Received method call '" + req.methodName() + "' with parameters : " + req.parameters()); + log.log(LogLevel.DEBUG, () -> "Received method call '" + req.methodName() + "' with parameters : " + req.parameters()); FileReference reference = new FileReference(req.parameters().get(0).asString()); int sessionId = req.parameters().get(1).asInt32(); @@ -278,14 +278,14 @@ public class FileReceiver { retval = 1; } double completeness = (double) session.currentFileSize / (double) session.fileSize; - log.log(LogLevel.DEBUG, String.format("%.1f percent of '%s' downloaded", completeness * 100, reference.value())); + log.log(LogLevel.DEBUG, () -> String.format("%.1f percent of '%s' downloaded", completeness * 100, reference.value())); downloader.setDownloadStatus(reference, completeness); req.returnValues().add(new Int32Value(retval)); } @SuppressWarnings({"UnusedDeclaration"}) public final void receiveFileEof(Request req) { - log.log(LogLevel.DEBUG, "Received method call '" + req.methodName() + "' with parameters : " + req.parameters()); + log.log(LogLevel.DEBUG, () -> "Received method call '" + req.methodName() + "' with parameters : " + req.parameters()); FileReference reference = new FileReference(req.parameters().get(0).asString()); int sessionId = req.parameters().get(1).asInt32(); long xxhash = req.parameters().get(2).asInt64(); diff --git a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReferenceDownloader.java b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReferenceDownloader.java index 8e230a1a2cc..92c483fc3b1 100644 --- a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReferenceDownloader.java +++ b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReferenceDownloader.java @@ -11,6 +11,7 @@ import com.yahoo.jrt.StringValue; import com.yahoo.log.LogLevel; import com.yahoo.vespa.config.Connection; import com.yahoo.vespa.config.ConnectionPool; +import org.apache.commons.compress.archivers.ArchiveEntry; import java.io.File; import java.time.Duration; @@ -74,7 +75,7 @@ public class FileReferenceDownloader { void addToDownloadQueue(FileReferenceDownload fileReferenceDownload) { FileReference fileReference = fileReferenceDownload.fileReference(); - log.log(LogLevel.DEBUG, "Will download file reference '" + fileReference.value() + "' with timeout " + downloadTimeout); + log.log(LogLevel.DEBUG, () -> "Will download file reference '" + fileReference.value() + "' with timeout " + downloadTimeout); synchronized (downloads) { downloads.put(fileReference, fileReferenceDownload); downloadStatus.put(fileReference, 0.0); @@ -94,7 +95,7 @@ public class FileReferenceDownloader { downloads.remove(fileReference); download.future().set(Optional.of(file)); } else { - log.log(LogLevel.INFO, "Received '" + fileReference + "', which was not requested. Can be ignored if happening during upgrades/restarts"); + log.log(LogLevel.DEBUG, () -> "Received '" + fileReference + "', which was not requested. Can be ignored if happening during upgrades/restarts"); } } } @@ -106,9 +107,9 @@ public class FileReferenceDownloader { execute(request, connection); if (validateResponse(request)) { - log.log(LogLevel.DEBUG, "Request callback, OK. Req: " + request + "\nSpec: " + connection); + log.log(LogLevel.DEBUG, () -> "Request callback, OK. Req: " + request + "\nSpec: " + connection); if (request.returnValues().get(0).asInt32() == 0) { - log.log(LogLevel.DEBUG, "Found file reference '" + fileReference.value() + "' available at " + connection.getAddress()); + log.log(LogLevel.DEBUG, () -> "Found file reference '" + fileReference.value() + "' available at " + connection.getAddress()); return true; } else { log.log(LogLevel.INFO, "File reference '" + fileReference.value() + "' not found for " + connection.getAddress()); @@ -116,7 +117,7 @@ public class FileReferenceDownloader { return false; } } else { - log.log(LogLevel.WARNING, "Request failed. Req: " + request + "\nSpec: " + connection.getAddress() + + log.log(LogLevel.INFO, "Request failed. Req: " + request + "\nSpec: " + connection.getAddress() + ", error code: " + request.errorCode()); if (request.isError() && request.errorCode() == ErrorCode.CONNECTION || request.errorCode() == ErrorCode.TIMEOUT) { log.log(LogLevel.INFO, "Mark connection " + connection.getAddress() + " with error"); diff --git a/node-admin/scripts/maintenance.sh b/node-admin/scripts/maintenance.sh index 4438d5d684b..4438d5d684b 100644..100755 --- a/node-admin/scripts/maintenance.sh +++ b/node-admin/scripts/maintenance.sh diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/package-info.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/package-info.java new file mode 100644 index 00000000000..deb5352d1eb --- /dev/null +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/package-info.java @@ -0,0 +1,5 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +@ExportPackage +package com.yahoo.vespa.hosted.node.admin.configserver.noderepository; + +import com.yahoo.osgi.annotation.ExportPackage; diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/orchestrator/package-info.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/orchestrator/package-info.java new file mode 100644 index 00000000000..6f67fe2ea08 --- /dev/null +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/orchestrator/package-info.java @@ -0,0 +1,5 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +@ExportPackage +package com.yahoo.vespa.hosted.node.admin.configserver.orchestrator; + +import com.yahoo.osgi.annotation.ExportPackage; diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/package-info.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/package-info.java new file mode 100644 index 00000000000..347f6eaf516 --- /dev/null +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/package-info.java @@ -0,0 +1,5 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +@ExportPackage +package com.yahoo.vespa.hosted.node.admin.configserver; + +import com.yahoo.osgi.annotation.ExportPackage; diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/package-info.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/package-info.java new file mode 100644 index 00000000000..948dfc070bc --- /dev/null +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/package-info.java @@ -0,0 +1,5 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +@ExportPackage +package com.yahoo.vespa.hosted.node.admin; + +import com.yahoo.osgi.annotation.ExportPackage; diff --git a/parent/pom.xml b/parent/pom.xml index ccbe34841fc..cbcc218b27d 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -707,7 +707,7 @@ <aries.util.version>1.0.0</aries.util.version> <asm-debug-all.version>5.0.3</asm-debug-all.version> <!-- Athenz dependencies. Make sure these dependencies matches those in Vespa's internal repositories --> - <athenz.version>1.7.41</athenz.version> + <athenz.version>1.7.43</athenz.version> <bouncycastle.version>1.58</bouncycastle.version> <commons-lang.version>2.6</commons-lang.version> <!-- WARNING: If you change curator version, you also need to update diff --git a/protocols/getnodestate/distributor.json b/protocols/getnodestate/distributor.json index ceed1a1b5c3..970fd09f253 100644 --- a/protocols/getnodestate/distributor.json +++ b/protocols/getnodestate/distributor.json @@ -13,13 +13,17 @@ "bucket-spaces" : [ { "name": "default", - "total": 11, - "pending": 3 + "buckets": { + "total": 11, + "pending": 3 + } }, { "name": "global", - "total": 13, - "pending": 5 + "buckets": { + "total": 13, + "pending": 5 + } } ] }, @@ -34,9 +38,7 @@ }, "bucket-spaces" : [ { - "name": "default", - "total": 17, - "pending": 7 + "name": "default" } ] } diff --git a/storage/src/tests/distributor/distributor_host_info_reporter_test.cpp b/storage/src/tests/distributor/distributor_host_info_reporter_test.cpp index 14df6ee5016..64df05acb8f 100644 --- a/storage/src/tests/distributor/distributor_host_info_reporter_test.cpp +++ b/storage/src/tests/distributor/distributor_host_info_reporter_test.cpp @@ -149,8 +149,9 @@ DistributorHostInfoReporterTest::verifyBucketSpaceStats(const vespalib::Slime& r size_t bucketsPending) { const auto &stats = getBucketSpaceStats(root, nodeIndex, bucketSpaceName); - CPPUNIT_ASSERT_EQUAL(bucketsTotal, static_cast<size_t>(stats["total"].asLong())); - CPPUNIT_ASSERT_EQUAL(bucketsPending, static_cast<size_t>(stats["pending"].asLong())); + const auto &buckets = stats["buckets"]; + CPPUNIT_ASSERT_EQUAL(bucketsTotal, static_cast<size_t>(buckets["total"].asLong())); + CPPUNIT_ASSERT_EQUAL(bucketsPending, static_cast<size_t>(buckets["pending"].asLong())); } void @@ -159,8 +160,7 @@ DistributorHostInfoReporterTest::verifyBucketSpaceStats(const vespalib::Slime& r const vespalib::string& bucketSpaceName) { const auto &stats = getBucketSpaceStats(root, nodeIndex, bucketSpaceName); - CPPUNIT_ASSERT(!stats["total"].valid()); - CPPUNIT_ASSERT(!stats["pending"].valid()); + CPPUNIT_ASSERT(!stats["buckets"].valid()); } struct Fixture { @@ -233,7 +233,7 @@ DistributorHostInfoReporterTest::generateExampleJson() PerNodeBucketSpacesStats stats; stats[0]["default"] = BucketSpaceStats(11, 3); stats[0]["global"] = BucketSpaceStats(13, 5); - stats[5]["default"] = BucketSpaceStats(17, 7); + stats[5]["default"] = BucketSpaceStats(); f.bucketSpacesStatsProvider.stats = stats; vespalib::asciistream json; diff --git a/storage/src/vespa/storage/distributor/distributor_host_info_reporter.cpp b/storage/src/vespa/storage/distributor/distributor_host_info_reporter.cpp index 5929f02c04b..8d2e45655d2 100644 --- a/storage/src/vespa/storage/distributor/distributor_host_info_reporter.cpp +++ b/storage/src/vespa/storage/distributor/distributor_host_info_reporter.cpp @@ -49,8 +49,10 @@ writeBucketSpacesStats(vespalib::JsonStream& stream, for (const auto& elem : stats) { stream << Object() << "name" << elem.first; if (elem.second.valid()) { - stream << "total" << elem.second.bucketsTotal() - << "pending" << elem.second.bucketsPending(); + stream << "buckets" << Object() + << "total" << elem.second.bucketsTotal() + << "pending" << elem.second.bucketsPending() + << End(); } stream << End(); } diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identity/SiaIdentityProvider.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identity/SiaIdentityProvider.java new file mode 100644 index 00000000000..c050ddce2c6 --- /dev/null +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identity/SiaIdentityProvider.java @@ -0,0 +1,51 @@ +// 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.identity; + +import com.yahoo.athenz.auth.util.Crypto; +import com.yahoo.container.jdisc.athenz.AthenzIdentityProvider; +import com.yahoo.vespa.athenz.api.AthenzDomain; +import com.yahoo.vespa.athenz.api.AthenzIdentityCertificate; +import com.yahoo.vespa.athenz.api.AthenzService; +import com.yahoo.vespa.athenz.tls.AthenzSslContextBuilder; + +import javax.net.ssl.SSLContext; +import java.io.File; +import java.nio.file.Paths; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; + +/** + * @author mortent + */ +public class SiaIdentityProvider implements AthenzIdentityProvider { + + private final AthenzDomain domain; + private final AthenzService service; + private final String path; + + public SiaIdentityProvider(SiaProviderConfig siaProviderConfig) { + this.domain = new AthenzDomain(siaProviderConfig.athenzDomain()); + this.service = new AthenzService(domain, siaProviderConfig.athenzService()); + this.path = siaProviderConfig.keyPathPrefix(); + } + + @Override + public String getDomain() { + return domain.getName(); + } + + @Override + public String getService() { + return service.getName(); + } + + @Override + public SSLContext getIdentitySslContext() { + X509Certificate certificate = Crypto.loadX509Certificate(Paths.get(path, "certs", String.format("%s.%s.cert.pem", getDomain(),getService())).toFile()); + PrivateKey privateKey = Crypto.loadPrivateKey(Paths.get(path, "keys", String.format("%s.%s.key.pem", getDomain(),getService())).toFile()); + + return new AthenzSslContextBuilder() + .withIdentityCertificate(new AthenzIdentityCertificate(certificate, privateKey)) + .build(); + } +} diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identity/package-info.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identity/package-info.java new file mode 100644 index 00000000000..da31e72a1fa --- /dev/null +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identity/package-info.java @@ -0,0 +1,8 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +/** + * @author mortent + */ +@ExportPackage +package com.yahoo.vespa.athenz.identity; + +import com.yahoo.osgi.annotation.ExportPackage;
\ No newline at end of file diff --git a/vespa-athenz/src/main/resources/configdefinitions/sia-provider.def b/vespa-athenz/src/main/resources/configdefinitions/sia-provider.def new file mode 100644 index 00000000000..f668ef544f7 --- /dev/null +++ b/vespa-athenz/src/main/resources/configdefinitions/sia-provider.def @@ -0,0 +1,6 @@ +# Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +namespace=vespa.athenz.identity + +athenzDomain string +athenzService string +keyPathPrefix string diff --git a/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/communication/IOThread.java b/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/communication/IOThread.java index 16a541f939c..bff9d2186e6 100644 --- a/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/communication/IOThread.java +++ b/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/communication/IOThread.java @@ -319,12 +319,12 @@ class IOThread implements Runnable, AutoCloseable { successfullHandshakes.getAndIncrement(); } catch (ServerResponseException ser) { executeProblemsCounter.incrementAndGet(); - log.log(Level.INFO, "Handshake did not work out " + endpoint, Exceptions.toMessageString(ser)); + log.info("Handshake did not work out " + endpoint + ": " + Exceptions.toMessageString(ser)); drainFirstDocumentsInQueueIfOld(); return ThreadState.CONNECTED; } catch (Throwable throwable) { // This cover IOException as well executeProblemsCounter.incrementAndGet(); - log.log(Level.INFO, "Problem with Handshake " + endpoint, Exceptions.toMessageString(throwable)); + log.info("Problem with Handshake " + endpoint + ": " + Exceptions.toMessageString(throwable)); drainFirstDocumentsInQueueIfOld(); client.close(); return ThreadState.DISCONNECTED; @@ -340,7 +340,7 @@ class IOThread implements Runnable, AutoCloseable { return ThreadState.CONNECTED; } catch (Throwable e) { // Covers IOException as well - log.info("Problems while handing data over to gateway " + endpoint + ": " + Exceptions.toMessageString(e)); + log.info("Problems while handing data over to gateway " + endpoint + ": " + Exceptions.toMessageString(e)); client.close(); return ThreadState.DISCONNECTED; } diff --git a/vespabase/conf/default-env.txt.in b/vespabase/conf/default-env.txt.in index 5b144e4c301..3551cec9945 100644 --- a/vespabase/conf/default-env.txt.in +++ b/vespabase/conf/default-env.txt.in @@ -1,3 +1,3 @@ # Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. fallback VESPA_HOME @CMAKE_INSTALL_PREFIX@ -override VESPA_USER vespa +override VESPA_USER @VESPA_USER@ |