You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2016/02/19 11:07:41 UTC

[4/7] brooklyn-library git commit: Addition of Ansible extra vars from Brooklyn config.

Addition of Ansible extra vars from Brooklyn config.


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-library/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-library/commit/121db325
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-library/tree/121db325
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-library/diff/121db325

Branch: refs/heads/master
Commit: 121db3252a606aebdd9fc7a038f9920f082fdd8a
Parents: 8de0e9f
Author: Geoff Macartney <ge...@cloudsoftcorp.com>
Authored: Wed Feb 10 14:44:54 2016 +0000
Committer: Yavor Yanchev <ya...@yanchev.com>
Committed: Wed Feb 17 11:43:03 2016 +0200

----------------------------------------------------------------------
 .../entity/cm/ansible/AnsibleConfig.java        | 20 ++++----
 .../entity/cm/ansible/AnsibleEntityImpl.java    | 24 ++++++----
 .../ansible/AnsibleLifecycleEffectorTasks.java  | 49 ++++++++++++++------
 .../entity/cm/ansible/AnsiblePlaybookTasks.java | 47 +++++++++++++++----
 4 files changed, 100 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/121db325/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsibleConfig.java
----------------------------------------------------------------------
diff --git a/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsibleConfig.java b/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsibleConfig.java
index b201294..d63c2c6 100644
--- a/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsibleConfig.java
+++ b/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsibleConfig.java
@@ -28,35 +28,39 @@ import com.google.common.annotations.Beta;
 @Beta
 public interface AnsibleConfig {
 
-    public static enum AnsibleModes {
+    enum AnsibleModes {
         PLAYBOOK
     };
 
     @SetFromFlag("playbook")
-    public static final ConfigKey<String> ANSIBLE_PLAYBOOK = ConfigKeys.newStringConfigKey("brooklyn.ansible.playbook",
+    ConfigKey<String> ANSIBLE_PLAYBOOK = ConfigKeys.newStringConfigKey("brooklyn.ansible.playbook",
         "Playbook to be execute by Ansible");
 
     @SetFromFlag("playbook.yaml")
-    public static final ConfigKey<String> ANSIBLE_PLAYBOOK_YAML = ConfigKeys.newStringConfigKey("brooklyn.ansible.playbookYaml",
+    ConfigKey<String> ANSIBLE_PLAYBOOK_YAML = ConfigKeys.newStringConfigKey("brooklyn.ansible.playbookYaml",
         "Playbook to be execute by Ansible");
 
     @SetFromFlag("playbook.url")
-    public static final ConfigKey<String> ANSIBLE_PLAYBOOK_URL = ConfigKeys.newStringConfigKey("brooklyn.ansible.playbookUrl");
+    ConfigKey<String> ANSIBLE_PLAYBOOK_URL = ConfigKeys.newStringConfigKey("brooklyn.ansible.playbookUrl");
 
     @SetFromFlag("ansible.service.start")
-    public static final ConfigKey<String> ANSIBLE_SERVICE_START = ConfigKeys.newStringConfigKey("ansible.service.start",
+    ConfigKey<String> ANSIBLE_SERVICE_START = ConfigKeys.newStringConfigKey("ansible.service.start",
             "Default start command used with conjunction with the Ansible's service module",
             "sudo ansible localhost -c local -m service -a \"name=%s state=started\"");
 
     @SetFromFlag("ansible.service.stop")
-    public static final ConfigKey<String> ANSIBLE_SERVICE_STOP = ConfigKeys.newStringConfigKey("ansible.service.stop",
+    ConfigKey<String> ANSIBLE_SERVICE_STOP = ConfigKeys.newStringConfigKey("ansible.service.stop",
             "Default stop command used with conjunction with the Ansible's service module",
             "sudo ansible localhost -c local -m service -a \"name=%s state=stopped\"");
 
     @SetFromFlag("ansible.service.checkPort")
-    public static final ConfigKey<Integer> ANSIBLE_SERVICE_CHECK_PORT = ConfigKeys.newIntegerConfigKey("ansible.service.check.port");
+    ConfigKey<Integer> ANSIBLE_SERVICE_CHECK_PORT = ConfigKeys.newIntegerConfigKey("ansible.service.check.port");
 
     @SetFromFlag("service.name")
-    public static final ConfigKey<String> SERVICE_NAME = ConfigKeys.newStringConfigKey("brooklyn.ansible.serviceName",
+    ConfigKey<String> SERVICE_NAME = ConfigKeys.newStringConfigKey("brooklyn.ansible.serviceName",
         "Name of OS service this will run as, for use in checking running and stopping");
+
+    @SetFromFlag("ansible.vars")
+    ConfigKey<Object> ANSIBLE_VARS = ConfigKeys.newConfigKey(Object.class, "brooklyn.ansible.vars",
+        "Ansible 'extra-vars' variable configuration values");
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/121db325/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsibleEntityImpl.java
----------------------------------------------------------------------
diff --git a/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsibleEntityImpl.java b/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsibleEntityImpl.java
index b34603e..c2635ca 100644
--- a/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsibleEntityImpl.java
+++ b/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsibleEntityImpl.java
@@ -27,13 +27,18 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 public class AnsibleEntityImpl extends EffectorStartableImpl implements AnsibleEntity {
 
+    private AnsibleLifecycleEffectorTasks lifecycleTasks;
+
     public void init() {
         checkNotNull(getConfig(SERVICE_NAME), "service name is missing. it has to be provided by the user");
         String playbookName = getConfig(ANSIBLE_PLAYBOOK);
         if (!Strings.isBlank(playbookName)) setDefaultDisplayName(playbookName + " (ansible)");
 
         super.init();
-        new AnsibleLifecycleEffectorTasks().attachLifecycleEffectors(this);
+
+        lifecycleTasks = new AnsibleLifecycleEffectorTasks();
+
+        lifecycleTasks.attachLifecycleEffectors(this);
     }
 
     @Override
@@ -43,13 +48,14 @@ public class AnsibleEntityImpl extends EffectorStartableImpl implements AnsibleE
 
     @Override
     public String ansibleCommand(String module, String args) {
-        final ProcessTaskWrapper<Integer> command = DynamicTasks.queue(AnsiblePlaybookTasks.moduleCommand(module, args));
-                command.asTask().blockUntilEnded();
-                if (0 == command.getExitCode()) {
-                        return command.getStdout();
-                    } else {
-                        throw new RuntimeException("Command (" + args + ") in module " + module
-                            +  " failed with stderr:\n" + command.getStderr() + "\n");
-                    }
+        final ProcessTaskWrapper<Integer> command = DynamicTasks.queue(
+            AnsiblePlaybookTasks.moduleCommand(module, config().get(ANSIBLE_VARS), lifecycleTasks.getRunDir(), args));
+        command.asTask().blockUntilEnded();
+        if (0 == command.getExitCode()) {
+            return command.getStdout();
+        } else {
+            throw new RuntimeException("Command (" + args + ") in module " + module
+                + " failed with stderr:\n" + command.getStderr() + "\n");
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/121db325/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsibleLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsibleLifecycleEffectorTasks.java b/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsibleLifecycleEffectorTasks.java
index 0262af3..e1a8622 100644
--- a/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsibleLifecycleEffectorTasks.java
+++ b/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsibleLifecycleEffectorTasks.java
@@ -18,6 +18,7 @@
  */
 package org.apache.brooklyn.entity.cm.ansible;
 
+import com.google.common.base.Supplier;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.location.MachineLocation;
 import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
@@ -31,16 +32,14 @@ import org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffect
 import org.apache.brooklyn.feed.ssh.SshFeed;
 import org.apache.brooklyn.feed.ssh.SshPollConfig;
 import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.net.Urls;
 import org.apache.brooklyn.util.text.Strings;
 import org.apache.brooklyn.util.time.Duration;
 import org.apache.brooklyn.util.time.Time;
-
-import com.google.common.base.Supplier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class AnsibleLifecycleEffectorTasks extends MachineLifecycleEffectorTasks implements AnsibleConfig {
 
@@ -48,7 +47,11 @@ public class AnsibleLifecycleEffectorTasks extends MachineLifecycleEffectorTasks
 
     protected String serviceName;
     protected SshFeed serviceSshFeed;
-    
+
+    protected Object extraVars;
+    protected String baseDir;
+    protected String runDir;
+
     public AnsibleLifecycleEffectorTasks() {
     }
 
@@ -57,6 +60,23 @@ public class AnsibleLifecycleEffectorTasks extends MachineLifecycleEffectorTasks
         return serviceName = entity().config().get(AnsibleConfig.SERVICE_NAME);
     }
 
+    public Object getExtraVars() {
+        if (extraVars != null) return extraVars;
+        return extraVars = entity().config().get(ANSIBLE_VARS);
+    }
+
+    public String getBaseDir() {
+        if (null != baseDir) return baseDir;
+        return baseDir = MachineLifecycleEffectorTasks.resolveOnBoxDir(entity(),
+                Machines.findUniqueMachineLocation(entity().getLocations(), SshMachineLocation.class).get());
+    }
+
+    public String getRunDir() {
+        if (null != runDir) return runDir;
+        return runDir = Urls.mergePaths(getBaseDir(), "apps/"+entity().getApplicationId()+"/ansible/playbooks/"
+            +entity().getEntityType().getSimpleName()+"_"+entity().getId());
+    }
+
     @Override
     public void attachLifecycleEffectors(Entity entity) {
         if (getServiceName()==null && getClass().equals(AnsibleLifecycleEffectorTasks.class)) {
@@ -79,30 +99,33 @@ public class AnsibleLifecycleEffectorTasks extends MachineLifecycleEffectorTasks
     }
 
     protected void startWithAnsibleAsync() {
-        String baseDir = MachineLifecycleEffectorTasks.resolveOnBoxDir(entity(), Machines.findUniqueMachineLocation(entity().getLocations(), SshMachineLocation.class).get());
-        String installDir = Urls.mergePaths(baseDir, "installs/ansible");
+        String installDir = Urls.mergePaths(getBaseDir(), "installs/ansible");
 
         String playbookUrl = entity().config().get(ANSIBLE_PLAYBOOK_URL);
         String playbookYaml = entity().config().get(ANSIBLE_PLAYBOOK_YAML);
 
         if (Strings.isNonBlank(playbookUrl) && Strings.isNonBlank(playbookYaml)) {
-            throw new IllegalArgumentException("You can specify " +  AnsibleConfig.ANSIBLE_PLAYBOOK_URL.getName() +  " or " + AnsibleConfig.ANSIBLE_PLAYBOOK_YAML.getName() + " but not both of them!");
+            throw new IllegalArgumentException("You can specify " +  AnsibleConfig.ANSIBLE_PLAYBOOK_URL.getName()
+                +  " or " + AnsibleConfig.ANSIBLE_PLAYBOOK_YAML.getName() + " but not both of them!");
         }
 
         DynamicTasks.queue(AnsiblePlaybookTasks.installAnsible(installDir, false));
 
-        String runDir = Urls.mergePaths(baseDir, "apps/"+entity().getApplicationId()+"/ansible/playbooks/"+entity().getEntityType().getSimpleName()+"_"+entity().getId());
-        
+        if (getExtraVars() != null) {
+            DynamicTasks.queue(AnsiblePlaybookTasks.configureExtraVars(getRunDir(), extraVars, false));
+        }
+
         if (Strings.isNonBlank(playbookUrl)) {
-            DynamicTasks.queue(AnsiblePlaybookTasks.installPlaybook(runDir, getPlaybookName(), playbookUrl));
+            DynamicTasks.queue(AnsiblePlaybookTasks.installPlaybook(getRunDir(), getPlaybookName(), playbookUrl));
         }
 
         if (Strings.isNonBlank(playbookYaml)) {
-            DynamicTasks.queue(AnsiblePlaybookTasks.buildPlaybookFile(runDir, getPlaybookName()));
+            DynamicTasks.queue(AnsiblePlaybookTasks.buildPlaybookFile(getRunDir(), getPlaybookName()));
         }
-        DynamicTasks.queue(AnsiblePlaybookTasks.runAnsible(runDir, getPlaybookName()));
+        DynamicTasks.queue(AnsiblePlaybookTasks.runAnsible(getRunDir(), getExtraVars(), getPlaybookName()));
     }
 
+
     protected void postStartCustom() {
         boolean result = false;
         result |= tryCheckStartService();

http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/121db325/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsiblePlaybookTasks.java
----------------------------------------------------------------------
diff --git a/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsiblePlaybookTasks.java b/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsiblePlaybookTasks.java
index 29924d4..36076a1 100644
--- a/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsiblePlaybookTasks.java
+++ b/software/cm/src/main/java/org/apache/brooklyn/entity/cm/ansible/AnsiblePlaybookTasks.java
@@ -27,15 +27,17 @@ import org.apache.brooklyn.util.core.task.Tasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
 import org.apache.brooklyn.util.net.Urls;
 import org.apache.brooklyn.util.ssh.BashCommands;
+import org.apache.brooklyn.util.text.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import java.util.Map;
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.Yaml;
 
 import static org.apache.brooklyn.util.ssh.BashCommands.sudo;
 
 public class AnsiblePlaybookTasks {
     private static final Logger LOG = LoggerFactory.getLogger(AnsiblePlaybookTasks.class);
+    private static final String EXTRA_VARS_FILENAME = "extra_vars.yaml";
 
     public static TaskFactory<?> installAnsible(String ansibleDirectory, boolean force) {
         String installCmd = cdAndRun(ansibleDirectory, AnsibleBashCommands.INSTALL_ANSIBLE);
@@ -45,7 +47,9 @@ public class AnsiblePlaybookTasks {
 
     public static TaskFactory<?> installPlaybook(final String ansibleDirectory, final String playbookName, final String playbookUrl) {
         return Tasks.sequential("build ansible playbook file for "+playbookName,
-                SshEffectorTasks.put(ansibleDirectory + "/" + playbookName + ".yaml").contents(ResourceUtils.create().getResourceFromUrl(playbookUrl)).createDirectory());
+                SshEffectorTasks.put(ansibleDirectory + "/" + playbookName + ".yaml")
+                    .contents(ResourceUtils.create().getResourceFromUrl(playbookUrl))
+                    .createDirectory());
     }
     
     protected static String cdAndRun(String targetDirectory, String command) {
@@ -59,24 +63,47 @@ public class AnsiblePlaybookTasks {
         String yaml = entity.config().get(AnsibleConfig.ANSIBLE_PLAYBOOK_YAML);
 
         return Tasks.sequential("build ansible playbook file for "+ playbook,
-                    SshEffectorTasks.put(Urls.mergePaths(ansibleDirectory) + "/" + playbook + ".yaml").contents(yaml).createDirectory());
+            SshEffectorTasks.put(Urls.mergePaths(ansibleDirectory) + "/" + playbook + ".yaml")
+                .contents(yaml).createDirectory());
     }
 
-    public static TaskFactory<?> runAnsible(final String ansibleDirectory, String playbookName) {
-        String cmd = String.format("sudo ansible-playbook -i \"localhost,\" -c local -s %s.yaml", playbookName);
+    public static TaskFactory<?> runAnsible(final String dir, Object extraVars, String playbookName) {
+        String cmd = String.format("sudo ansible-playbook -i \"localhost,\" -c local "
+            + optionalExtraVarsParameter(extraVars)
+            + " -s %s.yaml", playbookName);
 
         if (LOG.isDebugEnabled()) {
             LOG.debug("Ansible command: {}", cmd);
         }
 
-        return SshEffectorTasks.ssh(cdAndRun(ansibleDirectory, cmd)).
+        return SshEffectorTasks.ssh(cdAndRun(dir, cmd)).
                 summary("run ansible playbook for " + playbookName).requiringExitCodeZero();
     }
 
-    public static ProcessTaskFactory<Integer> moduleCommand(String module, String args) {
-        final String command = "ansible localhost -m '" + module + "' -a '" + args + "'";
-        return SshEffectorTasks.ssh(sudo(command))
+    public static ProcessTaskFactory<Integer> moduleCommand(String module, Object extraVars, String root, String args) {
+        final String command = "ansible localhost "
+            + optionalExtraVarsParameter(extraVars)
+            + " -m '" + module + "' -a '" + args + "'";
+        return SshEffectorTasks.ssh(sudo(BashCommands.chain("cd " + root, command)))
             .summary("ad-hoc: " + command).requiringExitCodeZero();
     }
+
+    public static TaskFactory<?> configureExtraVars(String dir, Object extraVars, boolean force) {
+        DumperOptions options = new DumperOptions();
+        options.setDefaultScalarStyle(DumperOptions.ScalarStyle.DOUBLE_QUOTED);
+        Yaml asYaml = new Yaml(options);
+        final String varsYaml = asYaml.dump(extraVars);
+        return SshEffectorTasks.put(Urls.mergePaths(dir, EXTRA_VARS_FILENAME))
+            .contents(varsYaml)
+            .summary("install extra vars")
+            .createDirectory();
+    }
+
+    private static String optionalExtraVarsParameter(Object extraVars) {
+        if (null == extraVars || Strings.isBlank(extraVars.toString())) {
+            return "";
+        }
+        return " --extra-vars \"@" + EXTRA_VARS_FILENAME + "\" ";
+    }
 }