/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.brooklyn.core.config.external.vault;
import com.google.common.collect.ImmutableMap;
import org.apache.brooklyn.core.config.external.ExternalConfigSupplier;
import org.apache.brooklyn.util.text.Strings;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
/**
* Test the operation of the Vault external configuration supplier.
*
* <p>To run this test, you must have a working Vault server, and set a number of properties to allow the test to
* query your Vault server.</p>
*
* <p>You should start, initialise and unseal your vault according to the Vault documentation. Then you should insert
* a secret into Vault:</p>
*
* <p><tt>vault write secret/test password=foobar</tt></p>
*
* <p>Then set system properties so that the test can reach Vault and knows about the secret:</p>
*
* <p><tt>-Dtest.brooklyn.vault.endpoint=http://127.0.0.1:8200<br />
* -Dtest.brooklyn.vault.path=secret/test<br />
* -Dtest.brooklyn.vault.propertyName=password<br />
* -Dtest.brooklyn.vault.propertyExpectedValue=foobar</tt></p>
*
* <p>You will also need to configure authentication methods for the individual tests. Refer to the "see also" section
* to find each method that needs further configuration.</p>
*
* @see #testAppIdAuthenticationWithAutomaticUserId()
*/
public class VaultExternalConfigSupplierLiveTest {
private String endpoint;
private String path;
private String propertyName;
private String propertyExpectedValue;
@BeforeClass
public void setUp() throws Exception {
endpoint = getTestProperty("endpoint");
path = getTestProperty("path");
propertyName = getTestProperty("propertyName");
propertyExpectedValue = getTestProperty("propertyExpectedValue");
}
private String getTestProperty(String name) {
String propName = "test.brooklyn.vault." + name;
String propVal = System.getProperty(propName);
if (Strings.isBlank(propVal))
throw new IllegalArgumentException(propName + " is not set");
return propVal;
}
/**
* Test using a hard-coded authentication token.
*
* <p>This provider does not do authentication, but instead uses a known token for authentication. When Vault is
* initialised, it will give you an <em>Initial Root Token</em>, which can be used for this test. However,
* obviously, passing around a well-known root token is A Bad Idea for use in production, and would largely undo all
* the useful security that vault provides.</p>
*
* <p>Set these system properties:</p>
*
* <p><tt>-Dtest.brooklyn.vault.token=1091fc84-70c1-b266-b99f-781684dd0d2b</tt></p>
*/
@Test(groups = "Live")
public void testHardCodedToken() {
String token = getTestProperty("token");
ExternalConfigSupplier ecs = new VaultTokenExternalConfigSupplier(null, "test",
ImmutableMap.of("endpoint", endpoint, "token", token, "path", path));
assertEquals(ecs.get(propertyName), propertyExpectedValue);
}
/**
* Test using the "userpass" authentication backend.
*
* <p>Configure Vault to enable userpass and add a new user ID with password:</p>
*
* <p><tt>vault auth-enable userpass<br>
* vault write auth/userpass/users/brooklynTest password=s3kr1t policies=root # the "root" policy allows unrestricted access, you will want to use a different policy for real use
* </tt></p>
*
* <p>Set these system properties:</p>
*
* <p><tt>-Dtest.brooklyn.vault.username=brooklynTest<br />
* -Dtest.brooklyn.vault.password=s3kr1t</tt></p>
*/
@Test(groups = "Live")
public void testUserPassAuthentication() {
String username = getTestProperty("username");
String password = getTestProperty("password");
ExternalConfigSupplier ecs = new VaultUserPassExternalConfigSupplier(null, "test",
ImmutableMap.of("endpoint", endpoint, "username", username, "password", password, "path", path));
assertEquals(ecs.get(propertyName), propertyExpectedValue);
}
/**
* Test using the "App ID" authentication backend, with a MAC-address based user ID.
*
* <p>First, determine the MAC address of your system. This is system dependent, but a good guess will be to
* inspect the routing table to determine the default route, and take the MAC address of the interface that the
* default route would use. Express the MAC address as a series of 12 low-case hexadecimal digits, without any
* symbols.</p>
*
* <p>Configure Vault to enable App-ID, add a new app ID, and authorise the MAC address to the app ID:</p>
*
* <p><tt>/vault auth-enable app-id<br>
* vault write auth/app-id/map/app-id/brooklyn value=root display_name=Brooklyn # the app ID here is "brooklyn"; the "root" policy allows unrestricted access, you will want to use a different policy for real use
* vault write auth/app-id/map/user-id/0c4de9bca2db value=brooklyn
* </tt></p>
*
* <p>Set these system properties:</p>
*
* <p><tt>-Dtest.brooklyn.vault.appId=brooklyn</tt></p>
*/
@Test(groups = "Live")
public void testAppIdAuthenticationWithAutomaticUserId() {
String appId = getTestProperty("appId");
ExternalConfigSupplier ecs = new VaultAppIdExternalConfigSupplier(null, "test",
ImmutableMap.of("endpoint", endpoint, "appId", appId, "path", path));
assertEquals(ecs.get(propertyName), propertyExpectedValue);
}
/**
* Test using the "App ID" authentication backend, with an explicitly-given user ID.
*
* <p>Configure Vault to enable App-ID, add a new app ID, and authorise your chosen user ID to the app ID:</p>
*
* <p><tt>/vault auth-enable app-id<br>
* vault write auth/app-id/map/app-id/brooklyn value=root display_name=Brooklyn # the app ID here is "brooklyn"; the "root" policy allows unrestricted access, you will want to use a different policy for real use
* vault write auth/app-id/map/user-id/testUser value=brooklyn
* </tt></p>
*
* <p>Set these system properties:</p>
*
* <p><tt>-Dtest.brooklyn.vault.appId=brooklyn<br />
* -Dtest.brooklyn.vault.userId=testUser</tt></p>
*/
@Test(groups = "Live")
public void testAppIdAuthenticationWithExplicitUserId() {
String appId = getTestProperty("appId");
String userId = getTestProperty("userId");
ExternalConfigSupplier ecs = new VaultAppIdExternalConfigSupplier(null, "test",
ImmutableMap.of("endpoint", endpoint, "appId", appId, "path", path, "userId", userId));
assertEquals(ecs.get(propertyName), propertyExpectedValue);
}
}