You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2015/05/29 19:21:56 UTC

[03/27] incubator-brooklyn git commit: Basic support for Windows BYON with WinRM pre-configured

Basic support for Windows BYON with WinRM pre-configured


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/1fa59690
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/1fa59690
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/1fa59690

Branch: refs/heads/master
Commit: 1fa596902d3cd70f3e58dc558a07d90dca837bfe
Parents: 638d3e9
Author: Martin Harris <gi...@nakomis.com>
Authored: Mon Apr 6 13:13:18 2015 +0100
Committer: Richard Downer <ri...@apache.org>
Committed: Thu May 28 17:27:34 2015 +0100

----------------------------------------------------------------------
 core/pom.xml                                    |   6 +-
 .../location/basic/ByonLocationResolver.java    |  17 +++-
 .../location/basic/WinRmMachineLocation.java    | 101 +++++++++++++++++++
 .../basic/ByonLocationResolverTest.java         |  66 ++++++++----
 pom.xml                                         |   1 +
 .../AbstractSoftwareProcessWinRmDriver.java     |  43 ++++++++
 6 files changed, 212 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1fa59690/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index 27ba663..fddcd0a 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -65,7 +65,11 @@
             <classifier>tests</classifier>
             <scope>test</scope>
         </dependency>
-
+        <dependency>
+            <groupId>io.cloudsoft.windows</groupId>
+            <artifactId>winrm4j</artifactId>
+            <version>${winrm4j.version}</version>
+        </dependency>
         <dependency>
             <groupId>net.schmizz</groupId>
             <artifactId>sshj</artifactId>

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1fa59690/core/src/main/java/brooklyn/location/basic/ByonLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/ByonLocationResolver.java b/core/src/main/java/brooklyn/location/basic/ByonLocationResolver.java
index 86cf747..2ce37d2 100644
--- a/core/src/main/java/brooklyn/location/basic/ByonLocationResolver.java
+++ b/core/src/main/java/brooklyn/location/basic/ByonLocationResolver.java
@@ -25,8 +25,11 @@ import java.util.Map;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.location.Location;
 import brooklyn.location.LocationSpec;
+import brooklyn.location.MachineLocation;
 import brooklyn.management.internal.LocalLocationManager;
 import brooklyn.util.JavaGroovyEquivalents;
 import brooklyn.util.config.ConfigBag;
@@ -34,6 +37,7 @@ import brooklyn.util.text.WildcardGlobs;
 import brooklyn.util.text.WildcardGlobs.PhraseTreatment;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 
 /**
@@ -55,6 +59,12 @@ public class ByonLocationResolver extends AbstractLocationResolver {
     
     public static final String BYON = "byon";
 
+    public static final ConfigKey<String> OS_FAMILY = ConfigKeys.newStringConfigKey("osfamily", "OS Family of the machine, either windows or linux", "linux");
+
+    public static final Map<String, Class<? extends MachineLocation>> OS_TO_MACHINE_LOCATION_TYPE = ImmutableMap.<String, Class<? extends MachineLocation>>of(
+            "windows", WinRmMachineLocation.class,
+            "linux", SshMachineLocation.class);
+
     @Override
     public String getPrefix() {
         return BYON;
@@ -77,6 +87,7 @@ public class ByonLocationResolver extends AbstractLocationResolver {
         Object hosts = config.getStringKey("hosts");
         config.remove("hosts");
         String user = (String)config.getStringKey("user");
+        Class<? extends MachineLocation> locationClass = OS_TO_MACHINE_LOCATION_TYPE.get(config.get(OS_FAMILY));
         
         List<String> hostAddresses;
         
@@ -96,7 +107,7 @@ public class ByonLocationResolver extends AbstractLocationResolver {
             throw new IllegalArgumentException("Invalid location '"+spec+"'; at least one host must be defined");
         }
         
-        List<SshMachineLocation> machines = Lists.newArrayList();
+        List<MachineLocation> machines = Lists.newArrayList();
         for (String host : hostAddresses) {
             String userHere = user;
             String hostHere = host;
@@ -109,13 +120,13 @@ public class ByonLocationResolver extends AbstractLocationResolver {
             } catch (Exception e) {
                 throw new IllegalArgumentException("Invalid host '"+hostHere+"' specified in '"+spec+"': "+e);
             }
-            LocationSpec<SshMachineLocation> locationSpec = LocationSpec.create(SshMachineLocation.class)
+            LocationSpec<? extends MachineLocation> locationSpec = LocationSpec.create(locationClass)
                     .configure("address", hostHere.trim())
                     .configureIfNotNull(LocalLocationManager.CREATE_UNMANAGED, config.get(LocalLocationManager.CREATE_UNMANAGED));
             if (JavaGroovyEquivalents.groovyTruth(userHere)) {
                 locationSpec.configure("user", userHere.trim());
             }
-            SshMachineLocation machine = managementContext.getLocationManager().createLocation(locationSpec);
+            MachineLocation machine = managementContext.getLocationManager().createLocation(locationSpec);
             machines.add(machine);
         }
         

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1fa59690/core/src/main/java/brooklyn/location/basic/WinRmMachineLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/WinRmMachineLocation.java b/core/src/main/java/brooklyn/location/basic/WinRmMachineLocation.java
new file mode 100644
index 0000000..febf901
--- /dev/null
+++ b/core/src/main/java/brooklyn/location/basic/WinRmMachineLocation.java
@@ -0,0 +1,101 @@
+/*
+ * 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 brooklyn.location.basic;
+
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.location.MachineDetails;
+import brooklyn.location.MachineLocation;
+import brooklyn.location.OsDetails;
+import brooklyn.util.flags.SetFromFlag;
+import io.cloudsoft.winrm4j.winrm.WinRmTool;
+import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
+
+public class WinRmMachineLocation extends AbstractLocation implements MachineLocation {
+
+    public static final ConfigKey<String> WINDOWS_USERNAME = ConfigKeys.newStringConfigKey("windows.username",
+            "Username to use when connecting to the remote machine");
+
+    public static final ConfigKey<String> WINDOWS_PASSWORD = ConfigKeys.newStringConfigKey("windows.password",
+            "Password to use when connecting to the remote machine");
+
+    @SetFromFlag
+    protected String user;
+
+    @SetFromFlag(nullable = false)
+    protected InetAddress address;
+
+    @Override
+    public InetAddress getAddress() {
+        return address;
+    }
+
+    @Override
+    public OsDetails getOsDetails() {
+        return null;
+    }
+
+    @Override
+    public MachineDetails getMachineDetails() {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public String getHostname() {
+        return address.getHostAddress();
+    }
+
+    @Override
+    public Set<String> getPublicAddresses() {
+        return null;
+    }
+
+    @Override
+    public Set<String> getPrivateAddresses() {
+        return null;
+    }
+
+    public int executeScript(List<String> script) {
+        WinRmTool winRmTool = WinRmTool.connect(getHostname(), getUsername(), getPassword());
+        WinRmToolResponse response = winRmTool.executeScript(script);
+        return response.getStatusCode();
+    }
+
+    public int executePsScript(List<String> psScript) {
+        WinRmTool winRmTool = WinRmTool.connect(getHostname(), getUsername(), getPassword());
+        WinRmToolResponse response = winRmTool.executePs(psScript);
+        return response.getStatusCode();
+    }
+
+    public String getUsername() {
+        return config().get(WINDOWS_USERNAME);
+    }
+
+    private String getPassword() {
+        return config().get(WINDOWS_PASSWORD);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1fa59690/core/src/test/java/brooklyn/location/basic/ByonLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/ByonLocationResolverTest.java b/core/src/test/java/brooklyn/location/basic/ByonLocationResolverTest.java
index 2fb85e5..0d6e5ff 100644
--- a/core/src/test/java/brooklyn/location/basic/ByonLocationResolverTest.java
+++ b/core/src/test/java/brooklyn/location/basic/ByonLocationResolverTest.java
@@ -60,7 +60,8 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 
-public class ByonLocationResolverTest {
+public class
+        ByonLocationResolverTest {
 
     private static final Logger log = LoggerFactory.getLogger(ByonLocationResolverTest.class);
     
@@ -101,14 +102,14 @@ public class ByonLocationResolverTest {
     public void testNamedByonLocation() throws Exception {
         brooklynProperties.put("brooklyn.location.named.mynamed", "byon(hosts=\"1.1.1.1\")");
         
-        FixedListMachineProvisioningLocation<SshMachineLocation> loc = resolve("named:mynamed");
+        FixedListMachineProvisioningLocation<MachineLocation> loc = resolve("named:mynamed");
         assertEquals(loc.obtain().getAddress(), InetAddress.getByName("1.1.1.1"));
     }
 
     @Test
     public void testPropertiesInSpec() throws Exception {
-        FixedListMachineProvisioningLocation<SshMachineLocation> loc = resolve("byon(privateKeyFile=myprivatekeyfile,hosts=\"1.1.1.1\")");
-        SshMachineLocation machine = loc.obtain();
+        FixedListMachineProvisioningLocation<MachineLocation> loc = resolve("byon(privateKeyFile=myprivatekeyfile,hosts=\"1.1.1.1\")");
+        SshMachineLocation machine = (SshMachineLocation)loc.obtain();
         
         assertEquals(machine.config().getBag().getStringKey("privateKeyFile"), "myprivatekeyfile");
         assertEquals(machine.getAddress(), Networking.getInetAddressWithFixedName("1.1.1.1"));
@@ -188,7 +189,7 @@ public class ByonLocationResolverTest {
     public void testNiceError() throws Exception {
         Asserts.assertFailsWith(new Runnable() {
             @Override public void run() {
-                FixedListMachineProvisioningLocation<SshMachineLocation> x = 
+                FixedListMachineProvisioningLocation<MachineLocation> x =
                         resolve("byon(hosts=\"1.1.1.{1,2}}\")");
                 log.error("got "+x+" but should have failed (your DNS is giving an IP for hostname '1.1.1.1}' (with the extra '}')");
             }
@@ -224,8 +225,8 @@ public class ByonLocationResolverTest {
     @Test
     public void testResolvesUserArg2() throws Exception {
         String spec = "byon(hosts=\"1.1.1.1\",user=bob)";
-        FixedListMachineProvisioningLocation<SshMachineLocation> ll = resolve(spec);
-        SshMachineLocation l = ll.obtain();
+        FixedListMachineProvisioningLocation<MachineLocation> ll = resolve(spec);
+        SshMachineLocation l = (SshMachineLocation)ll.obtain();
         Assert.assertEquals("bob", l.getUser());
     }
 
@@ -281,8 +282,8 @@ public class ByonLocationResolverTest {
         String localTempDir = Os.mergePaths(Os.tmp(), "testResolvesUsernameAtHost");
         brooklynProperties.put("brooklyn.location.byon.localTempDir", localTempDir);
 
-        FixedListMachineProvisioningLocation<SshMachineLocation> byon = resolve("byon(hosts=\"1.1.1.1\")");
-        SshMachineLocation machine = byon.obtain();
+        FixedListMachineProvisioningLocation<MachineLocation> byon = resolve("byon(hosts=\"1.1.1.1\",osFamily=\"windows\")");
+        MachineLocation machine = byon.obtain();
         assertEquals(machine.getConfig(SshMachineLocation.LOCAL_TEMP_DIR), localTempDir);
     }
 
@@ -291,10 +292,10 @@ public class ByonLocationResolverTest {
         List<String> ips = ImmutableList.of("1.1.1.1", "1.1.1.6", "1.1.1.3", "1.1.1.4", "1.1.1.5");
         String spec = "byon(hosts=\""+Joiner.on(",").join(ips)+"\")";
         
-        MachineProvisioningLocation<SshMachineLocation> ll = resolve(spec);
+        MachineProvisioningLocation<MachineLocation> ll = resolve(spec);
 
         for (String expected : ips) {
-            SshMachineLocation obtained = ll.obtain(ImmutableMap.of());
+            MachineLocation obtained = ll.obtain(ImmutableMap.of());
             assertEquals(obtained.getAddress().getHostAddress(), expected);
         }
     }
@@ -307,12 +308,41 @@ public class ByonLocationResolverTest {
                 "name", "foo",
                 "user", "myuser"
         );
-        MachineProvisioningLocation<SshMachineLocation> provisioner = resolve(spec, flags);
-        SshMachineLocation location1 = provisioner.obtain(ImmutableMap.of());
+        MachineProvisioningLocation<MachineLocation> provisioner = resolve(spec, flags);
+        SshMachineLocation location1 = (SshMachineLocation)provisioner.obtain(ImmutableMap.of());
         Assert.assertEquals("myuser", location1.getUser());
         Assert.assertEquals("1.1.1.1", location1.getAddress().getHostAddress());
     }
 
+    @Test
+    public void testWindowsMachines() throws Exception {
+        brooklynProperties.put("brooklyn.location.byon.windows.username", "myuser");
+        brooklynProperties.put("brooklyn.location.byon.windows.password", "mypassword");
+        String spec = "byon";
+        Map<String, ?> flags = ImmutableMap.of(
+                "hosts", ImmutableList.of("1.1.1.1", "2.2.2.2"),
+                "osfamily", "windows"
+        );
+        MachineProvisioningLocation<MachineLocation> provisioner = resolve(spec, flags);
+        MachineLocation location = provisioner.obtain(ImmutableMap.of());
+
+        assertEquals(location.config().get(WinRmMachineLocation.WINDOWS_USERNAME), "myuser");
+        assertEquals(location.config().get(WinRmMachineLocation.WINDOWS_PASSWORD), "mypassword");
+        Assert.assertNotNull(provisioner);
+    }
+
+    @Test
+    public void testNoneWindowsMachines() throws Exception {
+        String spec = "byon";
+        Map<String, ?> flags = ImmutableMap.of(
+                "hosts", ImmutableList.of("1.1.1.1", "2.2.2.2"),
+                "osfamily", "linux"
+        );
+        MachineProvisioningLocation<MachineLocation> provisioner = resolve(spec, flags);
+        MachineLocation location = provisioner.obtain(ImmutableMap.of());
+        assertTrue(location instanceof SshMachineLocation, "Expected location to be SshMachineLocation, found " + location);
+    }
+
     private void assertByonClusterEquals(FixedListMachineProvisioningLocation<? extends MachineLocation> cluster, Set<String> expectedHosts) {
         assertByonClusterEquals(cluster, expectedHosts, defaultNamePredicate);
     }
@@ -362,15 +392,15 @@ public class ByonLocationResolverTest {
     }
     
     @SuppressWarnings("unchecked")
-    private FixedListMachineProvisioningLocation<SshMachineLocation> resolve(String val) {
-        return (FixedListMachineProvisioningLocation<SshMachineLocation>) managementContext.getLocationRegistry().resolve(val);
+    private FixedListMachineProvisioningLocation<MachineLocation> resolve(String val) {
+        return (FixedListMachineProvisioningLocation<MachineLocation>) managementContext.getLocationRegistry().resolve(val);
     }
     
     @SuppressWarnings("unchecked")
-    private FixedListMachineProvisioningLocation<SshMachineLocation> resolve(String val, Map<?, ?> locationFlags) {
-        return (FixedListMachineProvisioningLocation<SshMachineLocation>) managementContext.getLocationRegistry().resolve(val, locationFlags);
+    private FixedListMachineProvisioningLocation<MachineLocation> resolve(String val, Map<?, ?> locationFlags) {
+        return (FixedListMachineProvisioningLocation<MachineLocation>) managementContext.getLocationRegistry().resolve(val, locationFlags);
     }
-    
+
     private static class UserHostTuple {
         final String username;
         final String hostname;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1fa59690/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 0747f8d..af08b2e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -205,6 +205,7 @@
         <jsr311-api.version>1.1.1</jsr311-api.version>
         <maxmind.version>0.8.1</maxmind.version>
         <jna.version>4.0.0</jna.version>
+        <winrm4j.version>0.1.0-SNAPSHOT</winrm4j.version>
         <coverage.target>${working.dir}</coverage.target>
 
         <!-- Release -->

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1fa59690/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessWinRmDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessWinRmDriver.java b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessWinRmDriver.java
new file mode 100644
index 0000000..8d65bec
--- /dev/null
+++ b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessWinRmDriver.java
@@ -0,0 +1,43 @@
+/*
+ * 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 brooklyn.entity.basic;
+
+import java.util.List;
+
+import brooklyn.location.basic.WinRmMachineLocation;
+
+public abstract class AbstractSoftwareProcessWinRmDriver extends AbstractSoftwareProcessDriver {
+
+    public AbstractSoftwareProcessWinRmDriver(EntityLocal entity, WinRmMachineLocation location) {
+        super(entity, location);
+    }
+
+    public WinRmMachineLocation getMachine() {
+        return (WinRmMachineLocation) getLocation();
+    }
+
+    public int execute(List<String> script) {
+        return getMachine().executeScript(script);
+    }
+
+    public int executePowerShell(List<String> psScript) {
+        return getMachine().executePsScript(psScript);
+    }
+
+}