From d49441d18093a9967cc9d7050dfdbbb4f6d881ba Mon Sep 17 00:00:00 2001 From: Aled Sage Date: Fri, 23 Sep 2016 19:04:58 +0100 Subject: [PATCH 1/4] Fix MAP_DEV_RANDOM_TO_DEV_URANDOM for running as root Fixes JcloudsLoginLiveTest.testSpecifyingPasswordWhenNoDefaultKeyFilesExistWithRootUser --- .../org/apache/brooklyn/location/jclouds/JcloudsLocation.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java index 11412d6117..dc4b93cd00 100644 --- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java @@ -909,7 +909,9 @@ protected MachineLocation obtainOnce(ConfigBag setup) throws NoMachinesAvailable executeCommandThrowingOnError( (SshMachineLocation)machineLocation, "using urandom instead of random", - Arrays.asList("sudo mv /dev/random /dev/random-real", "sudo ln -s /dev/urandom /dev/random")); + Arrays.asList( + BashCommands.sudo("mv /dev/random /dev/random-real"), + BashCommands.sudo("ln -s /dev/urandom /dev/random"))); } } From d0d8cf09755c6adbdd6c5990aa77ab2a7f4d74b6 Mon Sep 17 00:00:00 2001 From: Aled Sage Date: Fri, 23 Sep 2016 19:07:48 +0100 Subject: [PATCH 2/4] Mark failing tests as broken in JcloudsLoginLiveTest --- .../brooklyn/location/jclouds/JcloudsLoginLiveTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLoginLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLoginLiveTest.java index 8c2b68ba9d..0b737b9da8 100644 --- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLoginLiveTest.java +++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLoginLiveTest.java @@ -172,12 +172,14 @@ protected void testSpecifyingNothingAndNoDefaultKeyFilesExist() throws Exception } } - @Test(groups = {"Live"}) + // TODO Fails when ssh'ing during obtain(), because it prefers the password over the ssh key + @Test(groups = {"Live", "Broken"}) public void testSpecifyingPasswordAndSshKeysPrefersKeysAndDisablesPassword() throws Exception { runSpecifyingPasswordAndSshKeysPrefersKeys(false); } - @Test(groups = {"Live"}) + // TODO Fails because the password is passed through (so asserting machine config does not have password fails) + @Test(groups = {"Live", "Broken"}) public void testSpecifyingPasswordAndSshKeysPrefersKeysAndAllowsPassword() throws Exception { runSpecifyingPasswordAndSshKeysPrefersKeys(true); } From 9c9dd47810627da6b05450e89cbce40787faac17 Mon Sep 17 00:00:00 2001 From: Aled Sage Date: Fri, 23 Sep 2016 21:25:18 +0100 Subject: [PATCH 3/4] Add JcloudsWinrmingLiveTest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A test for JcloudsLocation provisioning (and WinRM’ing to) a Windows VM. Deletes the old AwsEc2LocationWindowsLiveTest, which was massively out of date and wrong. --- .../location/jclouds/JcloudsLocation.java | 4 +- .../jclouds/AbstractJcloudsLiveTest.java | 27 ++++-- .../jclouds/JcloudsAddressesLiveTest.java | 2 +- .../jclouds/JcloudsLoginLiveTest.java | 2 +- .../jclouds/JcloudsWinrmingLiveTest.java | 47 +++++++++ ...neProvisioningLocationJcloudsLiveTest.java | 4 +- .../AwsEc2LocationWindowsLiveTest.java | 95 ------------------- 7 files changed, 74 insertions(+), 107 deletions(-) create mode 100644 locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsWinrmingLiveTest.java delete mode 100644 locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AwsEc2LocationWindowsLiveTest.java diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java index dc4b93cd00..bc57874113 100644 --- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java @@ -1218,7 +1218,7 @@ public void suspendMachine(MachineLocation rawLocation) { * @see #registerMachine(ConfigBag) */ @Override - public MachineLocation resumeMachine(Map flags) { + public JcloudsMachineLocation resumeMachine(Map flags) { ConfigBag setup = ConfigBag.newInstanceExtending(config().getBag(), flags); LOG.info("{} using resuming node matching properties: {}", this, Sanitizer.sanitize(setup)); ComputeService computeService = getComputeService(setup); @@ -1229,7 +1229,7 @@ public MachineLocation resumeMachine(Map flags) { // hostname and addresses populated. node = findNodeOrThrow(setup); LOG.debug("{} resumed {}", this, node); - MachineLocation registered = registerMachineLocation(setup, node); + JcloudsMachineLocation registered = registerMachineLocation(setup, node); LOG.info("{} resumed and registered {}", this, registered); return registered; } diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java index 4313c43fee..4e2e7ccb58 100644 --- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java +++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Map; +import org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse; import org.apache.brooklyn.util.exceptions.CompoundRuntimeException; import org.apache.brooklyn.api.location.MachineLocation; import org.slf4j.Logger; @@ -36,6 +37,7 @@ import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext; import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests; import org.apache.brooklyn.location.ssh.SshMachineLocation; +import org.apache.brooklyn.location.winrm.WinRmMachineLocation; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -67,7 +69,7 @@ public class AbstractJcloudsLiveTest { protected BrooklynProperties brooklynProperties; protected LocalManagementContext managementContext; - protected List machines; + protected List machines; protected JcloudsLocation jcloudsLocation; @BeforeMethod(alwaysRun=true) @@ -135,6 +137,11 @@ protected void assertSshable(SshMachineLocation machine) { assertEquals(result, 0); } + protected void assertWinrmable(WinRmMachineLocation machine) { + WinRmToolResponse result = machine.executeCommand(ImmutableList.of("echo mySimpleWinrmCmd")); + assertEquals(result.getStatusCode(), 0, "stdout="+result.getStdOut()+"; stderr="+result.getStdErr()); + } + // Use this utility method to ensure machines are released on tearDown protected JcloudsSshMachineLocation obtainMachine(Map conf) throws Exception { assertNotNull(jcloudsLocation); @@ -147,16 +154,24 @@ protected JcloudsSshMachineLocation obtainMachine() throws Exception { return obtainMachine(ImmutableMap.of()); } - protected void releaseMachine(JcloudsSshMachineLocation machine) { + protected JcloudsWinRmMachineLocation obtainWinrmMachine(Map conf) throws Exception { + assertNotNull(jcloudsLocation); + JcloudsWinRmMachineLocation result = (JcloudsWinRmMachineLocation)jcloudsLocation.obtain(conf); + machines.add(checkNotNull(result, "result")); + return result; + } + + // Use this utility method to ensure machines are released on tearDown + protected void releaseMachine(JcloudsMachineLocation machine) { assertNotNull(jcloudsLocation); machines.remove(machine); jcloudsLocation.release(machine); } - protected List releaseMachineSafely(Iterable machines) { + protected List releaseMachineSafely(Iterable machines) { List exceptions = Lists.newArrayList(); - for (JcloudsSshMachineLocation machine : machines) { + for (JcloudsMachineLocation machine : machines) { try { releaseMachine(machine); } catch (Exception e) { @@ -175,8 +190,8 @@ protected void suspendMachine(MachineLocation machine) { protected MachineLocation resumeMachine(Map flags) { assertNotNull(jcloudsLocation); - MachineLocation location = jcloudsLocation.resumeMachine(flags); - machines.add((JcloudsSshMachineLocation) location); + JcloudsMachineLocation location = jcloudsLocation.resumeMachine(flags); + machines.add(location); return location; } diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java index 4ffb57eb2e..12e064d29a 100644 --- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java +++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java @@ -195,7 +195,7 @@ private void assertReachableFromMachine(SshMachineLocation machine, String addr, } @Override - protected void releaseMachine(JcloudsSshMachineLocation machine) { + protected void releaseMachine(JcloudsMachineLocation machine) { jcloudsLocation.release(machine); } diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLoginLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLoginLiveTest.java index 0b737b9da8..3744ee9e74 100644 --- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLoginLiveTest.java +++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLoginLiveTest.java @@ -368,7 +368,7 @@ protected void testAwsEc2SpecifyingSpecialUser() throws Exception { } @Override - protected void releaseMachine(JcloudsSshMachineLocation machine) { + protected void releaseMachine(JcloudsMachineLocation machine) { jcloudsLocation.release(machine); } diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsWinrmingLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsWinrmingLiveTest.java new file mode 100644 index 0000000000..1c3e63e2fa --- /dev/null +++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsWinrmingLiveTest.java @@ -0,0 +1,47 @@ +/* + * 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.location.jclouds; + +import org.apache.brooklyn.util.collections.MutableMap; +import org.jclouds.compute.domain.OsFamily; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; + +/** + * Tests the initial WinRM command execution, for a VM provisioned through jclouds. + */ +public class JcloudsWinrmingLiveTest extends AbstractJcloudsLiveTest { + + public static final String AWS_EC2_LOCATION_SPEC = "jclouds:" + AWS_EC2_PROVIDER + ":" + AWS_EC2_EUWEST_REGION_NAME; + public static final String AWS_EC2_IMAGE_NAME_REGEX = "Windows_Server-2012-R2_RTM-English-64Bit-Base-.*"; + + @Test(groups = {"Live"}) + public void testCreatesWindowsVm() throws Exception { + jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().getLocationManaged(AWS_EC2_LOCATION_SPEC); + + JcloudsWinRmMachineLocation machine = obtainWinrmMachine(MutableMap.builder() + .putIfAbsent("inboundPorts", ImmutableList.of(5986, 5985, 3389)) + .put(JcloudsLocation.IMAGE_NAME_REGEX.getName(), AWS_EC2_IMAGE_NAME_REGEX) + .put(JcloudsLocation.USE_JCLOUDS_SSH_INIT.getName(), false) + .put(JcloudsLocation.OS_FAMILY_OVERRIDE.getName(), OsFamily.WINDOWS) + .build()); + assertWinrmable(machine); + } +} diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SingleMachineProvisioningLocationJcloudsLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SingleMachineProvisioningLocationJcloudsLiveTest.java index 35a0a89d5c..23cb58086d 100644 --- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SingleMachineProvisioningLocationJcloudsLiveTest.java +++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SingleMachineProvisioningLocationJcloudsLiveTest.java @@ -105,10 +105,10 @@ protected JcloudsSshMachineLocation obtainMachine(Map conf) throws Excepti } @Override - protected void releaseMachine(JcloudsSshMachineLocation machine) { + protected void releaseMachine(JcloudsMachineLocation machine) { if (location.getChildren().contains(machine)) { machines.remove(machine); - location.release(machine); + location.release((JcloudsSshMachineLocation) machine); } } diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AwsEc2LocationWindowsLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AwsEc2LocationWindowsLiveTest.java deleted file mode 100644 index b5fdf82c81..0000000000 --- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AwsEc2LocationWindowsLiveTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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.location.jclouds.provider; - -import static org.testng.Assert.assertNotNull; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import org.apache.brooklyn.api.location.NoMachinesAvailableException; -import org.apache.brooklyn.api.mgmt.ManagementContext; -import org.apache.brooklyn.core.entity.Entities; -import org.apache.brooklyn.location.jclouds.JcloudsLocation; -import org.apache.brooklyn.location.jclouds.JcloudsSshMachineLocation; -import org.apache.brooklyn.location.ssh.SshMachineLocation; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import com.google.common.collect.ImmutableMap; - -public class AwsEc2LocationWindowsLiveTest { - private static final Logger LOG = LoggerFactory.getLogger(AwsEc2LocationWindowsLiveTest.class); - - private static final String PROVIDER = "aws-ec2"; - private static final String EUWEST_REGION_NAME = "eu-west-1"; - private static final String EUWEST_IMAGE_ID = EUWEST_REGION_NAME+"/"+"ami-7f0c260b";//"ami-41d3d635" - private static final String LOCATION_ID = "jclouds:"+PROVIDER+":"+EUWEST_REGION_NAME; - - protected JcloudsLocation loc; - protected Collection machines = new ArrayList(); - protected ManagementContext ctx; - - @BeforeMethod(groups = "Live") - public void setUp() { - ctx = Entities.newManagementContext(ImmutableMap.of("provider", PROVIDER)); - - loc = (JcloudsLocation) ctx.getLocationRegistry().getLocationManaged(LOCATION_ID); - } - - @AfterMethod(groups = "Live") - public void tearDown() throws Exception { - List exceptions = new ArrayList(); - for (SshMachineLocation machine : machines) { - try { - loc.release(machine); - } catch (Exception e) { - LOG.warn("Error releasing machine $it; continuing...", e); - exceptions.add(e); - } - } - if (!exceptions.isEmpty()) { - throw exceptions.get(0); - } - machines.clear(); - } - - // TODO Note careful choice of image due to jclouds 1.4 issue 886 - // TODO Blocks for long time, waiting for IP:22 to be reachable, before falling back to using public IP - // 10*2 minutes per attempt in jclouds 1.4 because done sequentially, and done twice by us so test takes 40 minutes! - @Test(enabled=true, groups = "Live") - public void testProvisionWindowsVm() throws NoMachinesAvailableException { - JcloudsSshMachineLocation machine = (JcloudsSshMachineLocation) obtainMachine(ImmutableMap.of("imageId", EUWEST_IMAGE_ID)); - - LOG.info("Provisioned Windows VM {}; checking if has password", machine); - assertNotNull(machine.waitForPassword()); - } - - // Use this utility method to ensure machines are released on tearDown - protected SshMachineLocation obtainMachine(Map flags) throws NoMachinesAvailableException { - JcloudsSshMachineLocation result = (JcloudsSshMachineLocation) loc.obtain(flags); - machines.add(result); - return result; - } -} From aba3f0980d7adfa1d7e9bf601c2ecbf1329a5a9e Mon Sep 17 00:00:00 2001 From: Aled Sage Date: Fri, 23 Sep 2016 21:40:06 +0100 Subject: [PATCH 4/4] JcloudsLocation: pass relevant config to child machine loc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously it only passed a small selection of the config to the child location. But if you passed additional ssh config values in the `provisioning.properties` then they wouldn’t get passed through. --- ...tractCloudMachineProvisioningLocation.java | 35 ++++++++++++---- .../location/jclouds/JcloudsLocation.java | 42 ++++++++++++++----- ...oudsSshMachineLocationStubbedLiveTest.java | 27 ++++++++++++ 3 files changed, 86 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/org/apache/brooklyn/core/location/cloud/AbstractCloudMachineProvisioningLocation.java b/core/src/main/java/org/apache/brooklyn/core/location/cloud/AbstractCloudMachineProvisioningLocation.java index 90d9f8b4d8..99988344e0 100644 --- a/core/src/main/java/org/apache/brooklyn/core/location/cloud/AbstractCloudMachineProvisioningLocation.java +++ b/core/src/main/java/org/apache/brooklyn/core/location/cloud/AbstractCloudMachineProvisioningLocation.java @@ -24,17 +24,26 @@ import org.apache.brooklyn.api.location.LocationSpec; import org.apache.brooklyn.api.location.MachineLocation; import org.apache.brooklyn.api.location.MachineProvisioningLocation; +import org.apache.brooklyn.config.ConfigKey.HasConfigKey; import org.apache.brooklyn.core.location.AbstractLocation; +import org.apache.brooklyn.location.ssh.SshMachineLocation; import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.core.config.ConfigBag; import org.apache.brooklyn.util.core.internal.ssh.SshTool; +import org.apache.brooklyn.util.text.StringPredicates; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Maps; public abstract class AbstractCloudMachineProvisioningLocation extends AbstractLocation -implements MachineProvisioningLocation, CloudLocationConfig -{ - public AbstractCloudMachineProvisioningLocation() { - super(); - } + implements MachineProvisioningLocation, CloudLocationConfig { + + private static final Logger LOG = LoggerFactory.getLogger(AbstractCloudMachineProvisioningLocation.class); + + public AbstractCloudMachineProvisioningLocation() { + super(); + } /** typically wants at least ACCESS_IDENTITY and ACCESS_CREDENTIAL */ public AbstractCloudMachineProvisioningLocation(Map conf) { @@ -70,6 +79,19 @@ public Map getProvisioningFlags(Collection tags) { protected ConfigBag extractSshConfig(ConfigBag setup, ConfigBag alt) { ConfigBag sshConfig = new ConfigBag(); + for (HasConfigKey key : SshMachineLocation.ALL_SSH_CONFIG_KEYS) { + String keyName = key.getConfigKey().getName(); + if (setup.containsKey(keyName)) { + sshConfig.putStringKey(keyName, setup.getStringKey(keyName)); + } else if (alt.containsKey(keyName)) { + sshConfig.putStringKey(keyName, setup.getStringKey(keyName)); + } + } + + Map sshToolClassProperties = Maps.filterKeys(setup.getAllConfig(), StringPredicates.startsWith(SshMachineLocation.SSH_TOOL_CLASS_PROPERTIES_PREFIX)); + sshConfig.putAll(sshToolClassProperties); + + // Special cases (preserving old code!) if (setup.containsKey(PASSWORD)) { sshConfig.copyKeyAs(setup, PASSWORD, SshTool.PROP_PASSWORD); } else if (alt.containsKey(PASSWORD)) { @@ -89,9 +111,6 @@ protected ConfigBag extractSshConfig(ConfigBag setup, ConfigBag alt) { sshConfig.copyKeyAs(setup, PRIVATE_KEY_PASSPHRASE, SshTool.PROP_PRIVATE_KEY_PASSPHRASE); } - // TODO extract other SshTool properties ? - return sshConfig; } - } diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java index bc57874113..4681ba7343 100644 --- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java @@ -28,7 +28,6 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; -import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.KeyPair; @@ -129,6 +128,7 @@ import org.apache.brooklyn.util.text.ByteSizeStrings; import org.apache.brooklyn.util.text.Identifiers; import org.apache.brooklyn.util.text.KeyValueParser; +import org.apache.brooklyn.util.text.StringPredicates; import org.apache.brooklyn.util.text.Strings; import org.apache.brooklyn.util.time.Duration; import org.apache.brooklyn.util.time.Time; @@ -2481,13 +2481,10 @@ protected JcloudsSshMachineLocation createJcloudsSshMachineLocation(ComputeServi if (isManaged()) { return getManagementContext().getLocationManager().createLocation(LocationSpec.create(JcloudsSshMachineLocation.class) + .configure(sshConfig) .configure("displayName", vmHostname) .configure("address", address) .configure(JcloudsSshMachineLocation.SSH_PORT, sshHostAndPort.isPresent() ? sshHostAndPort.get().getPort() : node.getLoginPort()) - // don't think "config" does anything - .configure(sshConfig) - // FIXME remove "config" -- inserted directly, above - .configure("config", sshConfig) .configure("user", userCredentials.getUser()) .configure(SshMachineLocation.PASSWORD.getName(), sshConfig.get(SshMachineLocation.PASSWORD.getName()) != null ? sshConfig.get(SshMachineLocation.PASSWORD.getName()) : @@ -2509,13 +2506,10 @@ protected JcloudsSshMachineLocation createJcloudsSshMachineLocation(ComputeServi } else { LOG.warn("Using deprecated JcloudsSshMachineLocation constructor because "+this+" is not managed"); return new JcloudsSshMachineLocation(MutableMap.builder() + .putAll(sshConfig) .put("displayName", vmHostname) .put("address", address) .put("port", sshHostAndPort.isPresent() ? sshHostAndPort.get().getPort() : node.getLoginPort()) - // don't think "config" does anything - .putAll(sshConfig) - // FIXME remove "config" -- inserted directly, above - .put("config", sshConfig) .put("user", userCredentials.getUser()) .putIfNotNull(SshMachineLocation.PASSWORD.getName(), sshConfig.get(SshMachineLocation.PASSWORD.getName()) != null ? SshMachineLocation.PASSWORD.getName() : @@ -2547,6 +2541,7 @@ protected JcloudsWinRmMachineLocation registerWinRmMachineLocation(ComputeServic } protected JcloudsWinRmMachineLocation createWinRmMachineLocation(ComputeService computeService, NodeMetadata node, String vmHostname, Optional sshHostAndPort, ConfigBag setup) { + Map winrmConfig = extractWinrmConfig(setup, node); String nodeAvailabilityZone = extractAvailabilityZone(setup, node); String nodeRegion = extractRegion(setup, node); if (nodeRegion == null) { @@ -2558,13 +2553,13 @@ protected JcloudsWinRmMachineLocation createWinRmMachineLocation(ComputeService if (isManaged()) { return getManagementContext().getLocationManager().createLocation(LocationSpec.create(JcloudsWinRmMachineLocation.class) + .configure(winrmConfig) .configure("jcloudsParent", this) .configure("displayName", vmHostname) .configure("address", address) .configure(WinRmMachineLocation.WINRM_CONFIG_PORT, sshHostAndPort.isPresent() ? sshHostAndPort.get().getPort() : node.getLoginPort()) .configure("user", getUser(setup)) .configure(WinRmMachineLocation.USER, setup.get(USER)) - .configure(ConfigBag.newInstance().copyKeyAs(setup, PASSWORD, WinRmMachineLocation.PASSWORD).getAllConfigRaw()) .configure("node", node) .configureIfNotNull(CLOUD_AVAILABILITY_ZONE_ID, nodeAvailabilityZone) .configureIfNotNull(CLOUD_REGION_ID, nodeRegion) @@ -2590,6 +2585,33 @@ protected Map extractSshConfig(ConfigBag setup, NodeMetadata node return extractSshConfig(setup, nodeConfig).getAllConfig(); } + protected Map extractWinrmConfig(ConfigBag setup, NodeMetadata node) { + ConfigBag nodeConfig = new ConfigBag(); + if (node!=null && node.getCredentials() != null) { + nodeConfig.putIfNotNull(PASSWORD, node.getCredentials().getOptionalPassword().orNull()); + nodeConfig.putIfNotNull(PRIVATE_KEY_DATA, node.getCredentials().getOptionalPrivateKey().orNull()); + } + return extractWinrmConfig(setup, nodeConfig).getAllConfig(); + } + + protected ConfigBag extractWinrmConfig(ConfigBag setup, ConfigBag alt) { + ConfigBag winrmConfig = new ConfigBag(); + + for (HasConfigKey key : WinRmMachineLocation.ALL_WINRM_CONFIG_KEYS) { + String keyName = key.getConfigKey().getName(); + if (setup.containsKey(keyName)) { + winrmConfig.putStringKey(keyName, setup.getStringKey(keyName)); + } else if (alt.containsKey(keyName)) { + winrmConfig.putStringKey(keyName, setup.getStringKey(keyName)); + } + } + + Map winrmToolClassProperties = Maps.filterKeys(setup.getAllConfig(), StringPredicates.startsWith(WinRmMachineLocation.WINRM_TOOL_CLASS_PROPERTIES_PREFIX)); + winrmConfig.putAll(winrmToolClassProperties); + + return winrmConfig; + } + protected String extractAvailabilityZone(ConfigBag setup, NodeMetadata node) { return extractNodeLocationId(setup, node, LocationScope.ZONE); } diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocationStubbedLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocationStubbedLiveTest.java index ca89d12c69..be29cdc64d 100644 --- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocationStubbedLiveTest.java +++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocationStubbedLiveTest.java @@ -25,9 +25,14 @@ import org.apache.brooklyn.location.jclouds.StubbedComputeServiceRegistry.AbstractNodeCreator; import org.apache.brooklyn.location.jclouds.StubbedComputeServiceRegistry.NodeCreator; +import org.apache.brooklyn.location.ssh.SshMachineLocation; +import org.apache.brooklyn.location.winrm.WinRmMachineLocation; +import org.apache.brooklyn.util.core.internal.ssh.SshTool; +import org.apache.brooklyn.util.core.internal.winrm.WinRmTool; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata.Status; import org.jclouds.compute.domain.NodeMetadataBuilder; +import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.Template; import org.jclouds.domain.LoginCredentials; import org.slf4j.Logger; @@ -97,4 +102,26 @@ public void testWithPrivateAddress() throws Exception { assertEquals(machine.getSubnetIp(), privateAddresses.get(0)); assertEquals(machine.getSubnetHostname(), privateAddresses.get(0)); } + + @Test(groups={"Live", "Live-sanity"}) + public void testSshConfigPassedToMachine() throws Exception { + JcloudsSshMachineLocation machine = obtainMachine(ImmutableMap.of( + SshMachineLocation.LOCAL_TEMP_DIR.getName(), "/my/local/temp/dir", + SshMachineLocation.LOG_PREFIX.getName(), "myLogPrefix", + SshTool.PROP_SSH_TRIES, 123)); + assertEquals(machine.config().get(SshMachineLocation.LOCAL_TEMP_DIR), "/my/local/temp/dir"); + assertEquals(machine.config().get(SshMachineLocation.LOG_PREFIX), "myLogPrefix"); + assertEquals(machine.config().get(SshTool.PROP_SSH_TRIES), Integer.valueOf(123)); + } + + @Test(groups={"Live", "Live-sanity"}) + public void testWinrmConfigPassedToMachine() throws Exception { + JcloudsWinRmMachineLocation machine = obtainWinrmMachine(ImmutableMap.of( + JcloudsLocation.OS_FAMILY_OVERRIDE.getName(), OsFamily.WINDOWS, + JcloudsLocation.WAIT_FOR_WINRM_AVAILABLE.getName(), "false", + WinRmMachineLocation.COPY_FILE_CHUNK_SIZE_BYTES.getName(), 123, + WinRmTool.PROP_EXEC_TRIES.getName(), 456)); + assertEquals(machine.config().get(WinRmMachineLocation.COPY_FILE_CHUNK_SIZE_BYTES), Integer.valueOf(123)); + assertEquals(machine.config().get(WinRmTool.PROP_EXEC_TRIES), Integer.valueOf(456)); + } }