diff --git a/vcloud-director-nat-microservice/src/test/java/brooklyn/networking/vclouddirector/natmicroservice/NatServiceMicroserviceLiveTest.java b/vcloud-director-nat-microservice/src/test/java/brooklyn/networking/vclouddirector/natmicroservice/NatServiceMicroserviceLiveTest.java index f26500ab..22cd55d6 100644 --- a/vcloud-director-nat-microservice/src/test/java/brooklyn/networking/vclouddirector/natmicroservice/NatServiceMicroserviceLiveTest.java +++ b/vcloud-director-nat-microservice/src/test/java/brooklyn/networking/vclouddirector/natmicroservice/NatServiceMicroserviceLiveTest.java @@ -15,6 +15,11 @@ import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; +import com.google.common.escape.Escaper; +import com.google.common.net.UrlEscapers; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.GenericType; + import brooklyn.config.BrooklynProperties; import brooklyn.entity.basic.Entities; import brooklyn.location.jclouds.JcloudsLocation; @@ -25,23 +30,24 @@ import brooklyn.test.entity.LocalManagementContextForTests; import brooklyn.util.exceptions.Exceptions; -import com.google.common.escape.Escaper; -import com.google.common.net.UrlEscapers; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.GenericType; - public class NatServiceMicroserviceLiveTest extends AbstractRestApiTest { private static final Logger LOG = LoggerFactory.getLogger(NatServiceMicroserviceLiveTest.class); private ManagementContext mgmt; private JcloudsLocation loc; + + private String trustStore; + private String trustStorePassword; @BeforeClass(alwaysRun=true) @Override public void setUp() throws Exception { mgmt = new LocalManagementContextForTests(BrooklynProperties.Factory.newDefault()); loc = (JcloudsLocation) mgmt.getLocationRegistry().resolve("canopy-vCHS"); + trustStore = (String) loc.getAllConfigBag().getStringKey("trustStore"); + trustStorePassword = (String) loc.getAllConfigBag().getStringKey("trustStorePassword"); + super.setUp(); } @@ -54,7 +60,7 @@ public void tearDown() throws Exception { protected NatServiceDispatcher newNatServiceDispatcher() { return NatServiceDispatcher.builder() - .endpoint(endpoint(loc), new TrustConfig(null, null)) + .endpoint(endpoint(loc), new TrustConfig(trustStore, trustStorePassword)) .build(); } diff --git a/vcloud-director-portforwarding/src/main/java/brooklyn/networking/vclouddirector/NatDirectClient.java b/vcloud-director-portforwarding/src/main/java/brooklyn/networking/vclouddirector/NatDirectClient.java index ccb1fbb7..f14a7e2b 100644 --- a/vcloud-director-portforwarding/src/main/java/brooklyn/networking/vclouddirector/NatDirectClient.java +++ b/vcloud-director-portforwarding/src/main/java/brooklyn/networking/vclouddirector/NatDirectClient.java @@ -47,6 +47,8 @@ public NatDirectClient(JcloudsLocation loc) { .endpoint(endpoint) .identity(loc.getIdentity()) .credential(loc.getCredential()) + .trustStore((String) loc.getAllConfigBag().getStringKey("trustStore")) + .trustStorePassword((String) loc.getAllConfigBag().getStringKey("trustStorePassword")) .mutex(MutexRegistry.INSTANCE.getMutexFor(endpoint)) .build(); } diff --git a/vcloud-director/src/main/java/brooklyn/networking/vclouddirector/CustomSSLSocketFactory.java b/vcloud-director/src/main/java/brooklyn/networking/vclouddirector/CustomSSLSocketFactory.java index 346a9377..d72bd54f 100644 --- a/vcloud-director/src/main/java/brooklyn/networking/vclouddirector/CustomSSLSocketFactory.java +++ b/vcloud-director/src/main/java/brooklyn/networking/vclouddirector/CustomSSLSocketFactory.java @@ -26,43 +26,42 @@ import org.apache.http.conn.ssl.SSLSocketFactory; +import com.google.common.base.Throwables; + public class CustomSSLSocketFactory { private CustomSSLSocketFactory() { } - public static SSLSocketFactory getInstance() - throws NoSuchAlgorithmException, KeyStoreException, - CertificateException, KeyManagementException, IOException { - - TrustManagerFactory trustManagerFactory = TrustManagerFactory - .getInstance(TrustManagerFactory.getDefaultAlgorithm()); - KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); - try{ - String trustStore = System.getProperty("javax.net.ssl.trustStore"); - String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword"); - if(trustStore == null || trustStorePassword == null){ - throw new IOException("javax.net.ssl.trustStore/javax.net.ssl.trustStorePassword property - not set"); - } + public static SSLSocketFactory getInstance(String trustStore, String trustStorePassword) { + try { + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); FileInputStream keystoreStream = new FileInputStream(trustStore); - try{ - keystore = KeyStore.getInstance(KeyStore.getDefaultType()); + KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); + try { keystore.load(keystoreStream, trustStorePassword.toCharArray()); - } finally{ + } finally { keystoreStream.close(); } - } catch(FileNotFoundException e){ - e.printStackTrace(); + trustManagerFactory.init(keystore); + TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, trustManagers, null); + SSLContext.setDefault(sslContext); + return new SSLSocketFactory(sslContext, SSLSocketFactory.STRICT_HOSTNAME_VERIFIER); + } catch (CertificateException e) { + throw Throwables.propagate(e); + } catch (NoSuchAlgorithmException e) { + throw Throwables.propagate(e); + } catch (KeyStoreException e) { + throw Throwables.propagate(e); + } catch (KeyManagementException e) { + throw Throwables.propagate(e); + } catch (FileNotFoundException e) { + throw Throwables.propagate(e); } catch (IOException e) { - e.printStackTrace(); + throw Throwables.propagate(e); } - trustManagerFactory.init(keystore); - TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(null, trustManagers, null); - SSLContext.setDefault(sslContext); - - return new SSLSocketFactory(sslContext, - SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); } + } diff --git a/vcloud-director/src/main/java/brooklyn/networking/vclouddirector/NatService.java b/vcloud-director/src/main/java/brooklyn/networking/vclouddirector/NatService.java index f692b8be..ac2e8243 100644 --- a/vcloud-director/src/main/java/brooklyn/networking/vclouddirector/NatService.java +++ b/vcloud-director/src/main/java/brooklyn/networking/vclouddirector/NatService.java @@ -15,13 +15,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import brooklyn.util.exceptions.Exceptions; -import brooklyn.util.guava.Maybe; -import brooklyn.util.net.Protocol; -import brooklyn.util.text.Strings; -import brooklyn.util.time.Duration; -import brooklyn.util.time.Time; - import com.google.common.annotations.Beta; import com.google.common.base.Objects; import com.google.common.base.Predicates; @@ -51,6 +44,12 @@ import com.vmware.vcloud.sdk.constants.Version; import com.vmware.vcloud.sdk.constants.query.QueryReferenceType; +import brooklyn.util.exceptions.Exceptions; +import brooklyn.util.guava.Maybe; +import brooklyn.util.net.Protocol; +import brooklyn.util.time.Duration; +import brooklyn.util.time.Time; + /** * For adding/removing NAT rules to vcloud-director. * @@ -477,7 +476,6 @@ protected VcloudClient newVcloudClient() { return newVcloudClient(baseUrl, identity, credential, trustStore, trustStorePassword, logLevel); } - // FIXME Don't set sysprop as could affect all other activities of the JVM! protected VcloudClient newVcloudClient(String endpoint, String identity, String credential, String trustStore, String trustStorePassword, Level logLevel) { try { if (logLevel != null) { @@ -494,6 +492,15 @@ protected VcloudClient newVcloudClient(String endpoint, String identity, String vcloudClient = new VcloudClient(endpoint, version); LOG.debug("VCloudClient - trying login to {} using {}", endpoint, version); vcloudClient.login(identity, credential); + + // Performing Certificate Validation + if (trustStore != null && trustStorePassword != null) { + vcloudClient.registerScheme("https", 443, CustomSSLSocketFactory.getInstance(trustStore, trustStorePassword)); + } else { + LOG.warn("Ignoring the Certificate Validation using FakeSSLSocketFactory"); + vcloudClient.registerScheme("https", 443, FakeSSLSocketFactory.getInstance()); + } + versionFound = true; LOG.info("VCloudClient - Logged into {} using version {}", endpoint, version); break; @@ -504,17 +511,6 @@ protected VcloudClient newVcloudClient(String endpoint, String identity, String if (!versionFound) { throw new IllegalStateException("Cannot login to " + endpoint + " using any of " + VCLOUD_VERSIONS); } - - // Performing Certificate Validation - if (Strings.isNonBlank(trustStore)) { - System.setProperty("javax.net.ssl.trustStore", trustStore); - System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword); - vcloudClient.registerScheme("https", 443, CustomSSLSocketFactory.getInstance()); - - } else { - LOG.warn("Ignoring the Certificate Validation using FakeSSLSocketFactory"); - vcloudClient.registerScheme("https", 443, FakeSSLSocketFactory.getInstance()); - } return vcloudClient; } catch (Exception e) { throw Exceptions.propagate(e); diff --git a/vcloud-director/src/test/java/brooklyn/networking/vclouddirector/SecureNatServiceLiveTest.java b/vcloud-director/src/test/java/brooklyn/networking/vclouddirector/SecureNatServiceLiveTest.java new file mode 100644 index 00000000..b00a2958 --- /dev/null +++ b/vcloud-director/src/test/java/brooklyn/networking/vclouddirector/SecureNatServiceLiveTest.java @@ -0,0 +1,111 @@ +package brooklyn.networking.vclouddirector; + +import static org.testng.Assert.assertNotNull; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.concurrent.Executors; + +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import com.vmware.vcloud.api.rest.schema.NatRuleType; + +import brooklyn.entity.BrooklynAppLiveTestSupport; +import brooklyn.location.jclouds.JcloudsLocation; +import brooklyn.util.exceptions.Exceptions; + +/** + * Tests assume that brooklyn.properties have been configured with location specs for vCHS and TAI. + * For example: + * + *
+ * brooklyn.location.named.canopy-vCHS=jclouds:vcloud-director:https://p5v1-vcd.vchs.vmware.com/api + * brooklyn.location.named.canopy-vCHS.identity=jo.blogs@cloudsoftcorp.com@M123456789-1234 + * brooklyn.location.named.canopy-vCHS.credential=pa55w0rd + * brooklyn.location.named.canopy-vCHS.advancednetworking.vcloud.network.id=041e176a-befc-4b28-89e2-3c5343ff4d12 + * brooklyn.location.named.canopy-vCHS.advancednetworking.vcloud.network.publicip=23.92.230.21 + * brooklyn.location.named.canopy-vCHS.trustStore=/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/security/cacerts + * brooklyn.location.named.canopy-vCHS.trustStorePassword=changeit + * + * brooklyn.location.named.canopy-TAI=jclouds:vcloud-director:https://svdc.it-solutions.atos.net/api + * brooklyn.location.named.canopy-TAI.identity=jo.blogs@myvorg_01 + * brooklyn.location.named.canopy-TAI.credential=pa55w0rd + * brooklyn.location.named.canopy-TAI.trustStore=/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/jre/lib/security/cacerts + * brooklyn.location.named.canopy-TAI.trustStorePassword=changeit + *+ */ +public class SecureNatServiceLiveTest extends BrooklynAppLiveTestSupport { + + // + private static final String LOCATION_SPEC = "canopy-vCHS"; + + private static final String LOCATION_TAI_SPEC = "canopy-TAI"; + + protected JcloudsLocation loc; + + protected ListeningExecutorService executor; + + @BeforeMethod(alwaysRun=true) + @Override + public void setUp() throws Exception { + super.setUp(); + loc = (JcloudsLocation) mgmt.getLocationRegistry().resolve(LOCATION_SPEC); + + executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()); + } + + @AfterMethod(alwaysRun=true) + @Override + public void tearDown() throws Exception { + try { + super.tearDown(); + } finally { + executor.shutdownNow(); + } + } + + // TAI (as at 2014-12-16) is running vcloud-director version 5.1 + @Test(groups="Live") + public void testGetNatRulesAtTai() throws Exception { + loc = (JcloudsLocation) mgmt.getLocationRegistry().resolve(LOCATION_TAI_SPEC); + NatService service = newServiceBuilder(loc).build(); + List