Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added chef basics example

This example combines the compute-basics example with the Chef features
in jclouds to bootstrap the created nodes.

When using the SOLO action, the node will download the cookbooks from
the Opscode github repository and will run them without interacting with
a Chef Server.

When using the CHEF action, the node will be registered in the provided
Chef Server (can be a Community Chef, a Hosted chef or a Private Chef)
and will run the cookbooks accordingly.
  • Loading branch information...
commit 84ed0db8a4b4dfd1ed5cccf4eadc91c2b357bee9 1 parent 60080c6
@nacx nacx authored
View
4 README.md
@@ -58,6 +58,10 @@ This repository contains various examples of using
<td><a href="jclouds-examples/tree/master/rackspace/">Rackspace (Java)</a></td>
<td>Example code that uses jclouds to perform common tasks on the Rackspace open cloud.</td>
</tr>
+ <tr>
+ <td><a href="jclouds-examples/tree/master/chef-basics/">Chef Basics (Java)</a></td>
+ <td>Example code to add nodes to a group and execute Chef cookbooks on them using Chef Solo or a standard or Hosted Chef Server.</td>
+ </tr>
</tbody>
</table>
View
58 chef-basics/README.md
@@ -0,0 +1,58 @@
+# chef-basics
+
+This is a simple example command line client that creates a node in a [ComputeService](http://code.google.com/p/jclouds/wiki/ComputeGuide) provider and installs an Apache web server on everything in its group using Chef.
+
+## Build
+
+Ensure you have maven 3.02 or higher installed, then execute 'mvn install' to build the example. Note you also need an ssh key setup in your home directory.
+
+If you don't already have ~/.ssh/id_rsa present, generate a key with the command 'ssh-keygen -t rsa' and leave the passphrase blank.
+
+Also make sure you have the private keys for the client and validator if you are using a Chef Server.
+
+## Run
+
+Invoke the jar, passing the name of the cloud provider you with to access (ex. aws-ec2, gogrid), identity (ex. accesskey, username), credential (ex. secretkey, password), then the name of the group you'd like to add the node to. The 5th parameter must be add, chef or destroy, noting that destroy will destroy all nodes in the group. If the 5th parameter is chef or solo, you must provide the list of recipes to install, separated by commas.
+
+Also, if the 5th parameter is 'chef', you must provide the connection details to the chef server. See the examples below:
+
+java -jar target/chef-basics-jar-with-dependencies.jar provider identity credential mygroup add
+
+java -Dchef.endpoint=http://chefendpoint -Dchef.client=clientname -Dchef.validator=validatorname -jar target/chef-basics-jar-with-dependencies.jar provider identity credential mygroup chef apache2
+
+java -jar target/chef-basics-jar-with-dependencies.jar provider identity credential mygroup solo apache2
+
+java -jar target/chef-basics-jar-with-dependencies.jar provider identity credential mygroup destroy
+
+Ex. for Amazon EC2
+
+java -jar target/chef-basics-jar-with-dependencies.jar aws-ec2 accesskey secretkey mygroup add
+
+Ex. for HP Cloud
+
+java -jar target/chef-basics-jar-with-dependencies.jar hpcloud-compute tenantId:accesskey secretkey mygroup add
+
+Ex. for TryStack.org
+
+java -jar target/chef-basics-jar-with-dependencies.jar trystack-nova tenantId:user password mygroup add
+
+Ex. for Abiquo
+
+java -Dabiquo.endpoint=http://abiquohost/api -jar target/chef-basics-jar-with-dependencies.jar abiquo user password mygroup add
+
+Ex. for your own OpenStack Nova
+
+java -Dopenstack-nova.image-id=RegionOne/15 -Dopenstack-nova.login-user=ubuntu -Djclouds.trust-all-certs=true -Djclouds.keystone.credential-type=passwordCredentials -Dopenstack-nova.endpoint=https://keystone:35357 -jar target/chef-basics-jar-with-dependencies.jar openstack-nova tenantId:user password mygroup add
+
+Ex. for Virtualbox
+java -jar target/chef-basics-jar-with-dependencies.jar virtualbox vboxwebsrv-username vboxwebsrv-password mygroup add
+
+Ex. for your own OpenStack Nova emulating EC2
+
+java -Dopenstack-nova-ec2.image-id=nova/ami-00000009 -Dopenstack-nova-ec2.login-user=ubuntu -Djclouds.trust-all-certs=true -Dopenstack-nova-ec2.endpoint=https://novahost/services/Cloud -jar target/chef-basics-jar-with-dependencies.jar openstack-nova-ec2 tenantId:accesskey secretkey mygroup add
+
+## License
+
+Copyright (C) 2009-2012 jclouds, Inc.
+
+Licensed under the Apache License, Version 2.0
View
192 chef-basics/pom.xml
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to jclouds, Inc. (jclouds) under one or more
+ contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. jclouds 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.jclouds.examples</groupId>
+ <artifactId>chef-basics</artifactId>
+ <version>1.6.0-SNAPSHOT</version>
+ <name>chef-basics</name>
+ <description>jclouds chef example that adds a node to a group, then installs an Apache web server on all nodes</description>
+
+ <properties>
+ <jclouds.version>1.6.0-SNAPSHOT</jclouds.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.jclouds</groupId>
+ <artifactId>jclouds-compute</artifactId>
+ <version>${jclouds.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jclouds.api</groupId>
+ <artifactId>chef</artifactId>
+ <version>${jclouds.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jclouds</groupId>
+ <artifactId>jclouds-allcompute</artifactId>
+ <version>${jclouds.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jclouds.labs</groupId>
+ <artifactId>joyentcloud</artifactId>
+ <version>${jclouds.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jclouds.labs</groupId>
+ <artifactId>virtualbox</artifactId>
+ <version>${jclouds.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jclouds.labs</groupId>
+ <artifactId>abiquo</artifactId>
+ <version>${jclouds.version}</version>
+ </dependency>
+ <!-- note that if you want a smaller distribution
+ remove the above dependency and place something
+ like below -->
+ <!--
+ <dependency>
+ <groupId>org.jclouds.provider</groupId>
+ <artifactId>gogrid</artifactId>
+ <version>${jclouds.version}</version>
+ </dependency>
+ -->
+ <dependency>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcprov-jdk16</artifactId>
+ <version>1.46</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jclouds.driver</groupId>
+ <artifactId>jclouds-bouncycastle</artifactId>
+ <version>${jclouds.version}</version>
+ <exclusions>
+ <!-- bouncy castle is a provider, so
+ it must be signed and used as-is.
+ we are doing this to prevent its
+ classes from getting into the
+ jar-with-dependencies -->
+ <exclusion>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcprov-jdk16</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.jclouds.driver</groupId>
+ <artifactId>jclouds-sshj</artifactId>
+ <version>${jclouds.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jclouds.driver</groupId>
+ <artifactId>jclouds-enterprise</artifactId>
+ <version>${jclouds.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>1.0.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <finalName>${project.artifactId}</finalName>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <mainClass>org.jclouds.examples.chef.basics.MainApp</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.2.1</version>
+ <configuration>
+ <descriptors>
+ <descriptor>src/main/assembly/jar-with-dependencies.xml</descriptor>
+ </descriptors>
+ <archive>
+ <manifest>
+ <mainClass>org.jclouds.examples.chef.basics.MainApp</mainClass>
+ </manifest>
+ <manifestEntries>
+ <Class-Path>bcprov-jdk16.jar</Class-Path>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.3</version>
+ <executions>
+ <execution>
+ <id>copy</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcprov-jdk16</artifactId>
+ <overWrite>false</overWrite>
+ <destFileName>bcprov-jdk16.jar</destFileName>
+ </artifactItem>
+ </artifactItems>
+ <outputDirectory>${project.build.directory}</outputDirectory>
+ <overWriteReleases>false</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
View
24 chef-basics/src/main/assembly/jar-with-dependencies.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <!-- copied from jar-with-dependencies (http://maven.apache.org/plugins/maven-assembly-plugin/descriptor-refs.html#jar-with-dependencies) -->
+ <id>jar-with-dependencies</id>
+ <formats>
+ <format>jar</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <containerDescriptorHandlers>
+ <containerDescriptorHandler>
+ <handlerName>metaInf-services</handlerName>
+ </containerDescriptorHandler>
+ </containerDescriptorHandlers>
+ <dependencySets>
+ <dependencySet>
+ <outputDirectory>/</outputDirectory>
+ <useProjectArtifact>true</useProjectArtifact>
+ <unpack>true</unpack>
+ <scope>runtime</scope>
+ </dependencySet>
+ </dependencySets>
+</assembly>
View
310 chef-basics/src/main/java/org/jclouds/examples/chef/basics/MainApp.java
@@ -0,0 +1,310 @@
+/**
+ * Licensed to jclouds, Inc. (jclouds) under one or more
+ * contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. jclouds 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.jclouds.examples.chef.basics;
+
+import static com.google.common.base.Charsets.UTF_8;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Predicates.not;
+import static com.google.common.collect.Iterables.concat;
+import static com.google.common.collect.Iterables.contains;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_AMI_QUERY;
+import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_CC_AMI_QUERY;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE;
+import static org.jclouds.compute.options.TemplateOptions.Builder.overrideLoginCredentials;
+import static org.jclouds.compute.options.TemplateOptions.Builder.runScript;
+import static org.jclouds.compute.predicates.NodePredicates.TERMINATED;
+import static org.jclouds.compute.predicates.NodePredicates.inGroup;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import org.jclouds.ContextBuilder;
+import org.jclouds.apis.ApiMetadata;
+import org.jclouds.apis.Apis;
+import org.jclouds.chef.ChefApiMetadata;
+import org.jclouds.chef.ChefContext;
+import org.jclouds.chef.ChefService;
+import org.jclouds.chef.config.ChefProperties;
+import org.jclouds.chef.util.RunListBuilder;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.compute.RunNodesException;
+import org.jclouds.compute.RunScriptOnNodesException;
+import org.jclouds.compute.domain.ExecResponse;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.enterprise.config.EnterpriseConfigurationModule;
+import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
+import org.jclouds.providers.ProviderMetadata;
+import org.jclouds.providers.Providers;
+import org.jclouds.scriptbuilder.domain.Statement;
+import org.jclouds.scriptbuilder.domain.StatementList;
+import org.jclouds.scriptbuilder.domain.chef.RunList;
+import org.jclouds.scriptbuilder.statements.chef.ChefSolo;
+import org.jclouds.scriptbuilder.statements.git.CloneGitRepo;
+import org.jclouds.scriptbuilder.statements.git.InstallGit;
+import org.jclouds.scriptbuilder.statements.login.AdminAccess;
+import org.jclouds.sshj.config.SshjSshClientModule;
+
+import com.google.common.base.Predicates;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+import com.google.common.io.Files;
+import com.google.inject.Module;
+
+/**
+ * Demonstrates the use of {@link ComputeService}.
+ * <p/>
+ * Usage is:
+ * {@code java MainApp provider identity credential groupName (add|chef|destroy)}
+ * if {@code chef} is used, the following parameter is a list of recipes to be
+ * installed in the node separated by commas.
+ *
+ * @author Adrian Cole
+ * @author Ignasi Barrera
+ */
+public class MainApp {
+
+ public static enum Action {
+ ADD, CHEF, SOLO, DESTROY;
+ }
+
+ public static final Map<String, ApiMetadata> allApis = Maps.uniqueIndex(
+ Apis.viewableAs(ComputeServiceContext.class), Apis.idFunction());
+
+ public static final Map<String, ProviderMetadata> appProviders = Maps.uniqueIndex(
+ Providers.viewableAs(ComputeServiceContext.class), Providers.idFunction());
+
+ public static final Set<String> allKeys = ImmutableSet.copyOf(Iterables.concat(appProviders.keySet(),
+ allApis.keySet()));
+
+ public static int PARAMETERS = 5;
+ public static String INVALID_SYNTAX = "Invalid number of parameters. Syntax is: provider identity credential groupName (add|chef|solo|destroy)";
+
+ public static void main(String[] args) {
+ if (args.length < PARAMETERS) {
+ throw new IllegalArgumentException(INVALID_SYNTAX);
+ }
+
+ String provider = args[0];
+ String identity = args[1];
+ String credential = args[2];
+ String groupName = args[3];
+ Action action = Action.valueOf(args[4].toUpperCase());
+ if ((action == Action.CHEF || action == Action.SOLO) && args.length < PARAMETERS + 1) {
+ throw new IllegalArgumentException("please provide the list of recipes to install, separated by commas");
+ }
+ String recipes = action == Action.CHEF || action == Action.SOLO ? args[5] : "apache2";
+
+ String minRam = System.getProperty("minRam");
+
+ // note that you can check if a provider is present ahead of time
+ checkArgument(contains(allKeys, provider), "provider %s not in supported list: %s", provider, allKeys);
+
+ LoginCredentials login = action != Action.DESTROY ? getLoginForCommandExecution(action) : null;
+
+ ComputeService compute = initComputeService(provider, identity, credential);
+
+ try {
+ switch (action) {
+ case ADD:
+ System.out.printf(">> adding node to group %s%n", groupName);
+
+ // Default template chooses the smallest size on an operating
+ // system that tested to work with java, which tends to be Ubuntu
+ // or CentOS
+ TemplateBuilder templateBuilder = compute.templateBuilder();
+
+ // If you want to up the ram and leave everything default, you
+ // can just tweak minRam
+ if (minRam != null) {
+ templateBuilder.minRam(Integer.parseInt(minRam));
+ }
+
+ // note this will create a user with the same name as you on the
+ // node. ex. you can connect via ssh publicip
+ Statement bootInstructions = AdminAccess.standard();
+
+ // to run commands as root, we use the runScript option in the
+ // template.
+ templateBuilder.options(runScript(bootInstructions));
+
+ NodeMetadata node = getOnlyElement(compute.createNodesInGroup(groupName, 1, templateBuilder.build()));
+ System.out.printf("<< node %s: %s%n", node.getId(),
+ concat(node.getPrivateAddresses(), node.getPublicAddresses()));
+
+ case SOLO:
+ System.out.printf(">> installing [%s] on group %s as %s%n", recipes, groupName, login.identity);
+
+ Iterable<String> recipeList = Splitter.on(',').split(recipes);
+ ImmutableList.Builder<Statement> bootstrapBuilder = ImmutableList.builder();
+ bootstrapBuilder.add(new InstallGit());
+
+ // Clone community cookbooks into the node
+ for (String recipe : recipeList) {
+ bootstrapBuilder.add(CloneGitRepo.builder()
+ .repository("git://github.com/opscode-cookbooks/" + recipe + ".git")
+ .directory("/var/chef/cookbooks/" + recipe) //
+ .build());
+ }
+
+ // Configure Chef Solo to bootstrap the selected recipes
+ bootstrapBuilder.add(ChefSolo.builder() //
+ .cookbookPath("/var/chef/cookbooks") //
+ .runlist(RunList.builder().recipes(recipeList).build()) //
+ .build());
+
+ // Build the statement that will perform all the operations above
+ StatementList bootstrap = new StatementList(bootstrapBuilder.build());
+
+ // Run the script in the nodes of the group
+ runScriptOnGroup(compute, login, groupName, bootstrap);
+ break;
+ case CHEF:
+ // Create the connection to the Chef server
+ ChefService chef = initChefService(System.getProperty("chef.client"),
+ System.getProperty("chef.validator"));
+
+ // Build the runlist for the deployed nodes
+ System.out.println("Configuring node runlist in the Chef server...");
+ List<String> runlist = new RunListBuilder().addRecipes(recipes.split(",")).build();
+ chef.updateRunListForGroup(runlist, groupName);
+ Statement chefServerBootstrap = chef.createBootstrapScriptForGroup(groupName);
+
+ // Run the script in the nodes of the group
+ System.out.printf(">> installing [%s] on group %s as %s%n", recipes, groupName, login.identity);
+ runScriptOnGroup(compute, login, groupName, chefServerBootstrap);
+ break;
+ case DESTROY:
+ System.out.printf(">> destroying nodes in group %s%n", groupName);
+ // you can use predicates to select which nodes you wish to
+ // destroy.
+ Set<? extends NodeMetadata> destroyed = compute.destroyNodesMatching(//
+ Predicates.<NodeMetadata> and(not(TERMINATED), inGroup(groupName)));
+ System.out.printf("<< destroyed nodes %s%n", destroyed);
+ break;
+ }
+ } catch (RunNodesException e) {
+ System.err.println("error adding node to group " + groupName + ": " + e.getMessage());
+ error = 1;
+ } catch (RunScriptOnNodesException e) {
+ System.err.println("error installing " + recipes + " on group " + groupName + ": " + e.getMessage());
+ error = 1;
+ } catch (Exception e) {
+ System.err.println("error: " + e.getMessage());
+ error = 1;
+ } finally {
+ compute.getContext().close();
+ System.exit(error);
+ }
+ }
+
+ static int error = 0;
+
+ private static void runScriptOnGroup(ComputeService compute, LoginCredentials login, String groupName,
+ Statement command) throws RunScriptOnNodesException {
+ // when you run commands, you can pass options to decide whether
+ // to run it as root, supply or own credentials vs from cache,
+ // and wrap in an init script vs directly invoke
+ Map<? extends NodeMetadata, ExecResponse> execResponses = compute.runScriptOnNodesMatching(//
+ inGroup(groupName), // predicate used to select nodes
+ command, // what you actually intend to run
+ overrideLoginCredentials(login) // use the local user & ssh key
+ .runAsRoot(false)); // don't attempt to run as root (sudo)
+
+ for (Entry<? extends NodeMetadata, ExecResponse> response : execResponses.entrySet()) {
+ System.out.printf("<< node %s: %s%n", response.getKey().getId(),
+ concat(response.getKey().getPrivateAddresses(), response.getKey().getPublicAddresses()));
+ System.out.printf("<< %s%n", response.getValue());
+ }
+ }
+
+ private static ComputeService initComputeService(String provider, String identity, String credential) {
+
+ // example of specific properties, in this case optimizing image list to
+ // only amazon supplied
+ Properties properties = new Properties();
+ properties.setProperty(PROPERTY_EC2_AMI_QUERY, "owner-id=137112412989;state=available;image-type=machine");
+ properties.setProperty(PROPERTY_EC2_CC_AMI_QUERY, "");
+ long scriptTimeout = TimeUnit.MILLISECONDS.convert(20, TimeUnit.MINUTES);
+ properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, scriptTimeout + "");
+
+ // example of injecting a ssh implementation
+ Iterable<Module> modules = ImmutableSet.<Module> of(new SshjSshClientModule(), new SLF4JLoggingModule(),
+ new EnterpriseConfigurationModule());
+
+ ContextBuilder builder = ContextBuilder.newBuilder(provider).credentials(identity, credential).modules(modules)
+ .overrides(properties);
+
+ System.out.printf(">> initializing %s%n", builder.getApiMetadata());
+
+ return builder.buildView(ComputeServiceContext.class).getComputeService();
+ }
+
+ private static ChefService initChefService(String client, String validator) {
+ try {
+ Properties chefConfig = new Properties();
+ chefConfig.put(ChefProperties.CHEF_VALIDATOR_NAME, validator);
+ chefConfig.put(ChefProperties.CHEF_VALIDATOR_CREDENTIAL, credentialForClient(validator));
+
+ ContextBuilder builder = ContextBuilder.newBuilder(new ChefApiMetadata()) //
+ .credentials(client, credentialForClient(client)) //
+ .modules(ImmutableSet.<Module> of(new SLF4JLoggingModule())) //
+ .overrides(chefConfig); //
+
+ System.out.printf(">> initializing %s%n", builder.getApiMetadata());
+
+ ChefContext context = builder.build();
+ return context.getChefService();
+ } catch (Exception e) {
+ System.err.println("error reading private key " + e.getMessage());
+ System.exit(1);
+ return null;
+ }
+ }
+
+ private static LoginCredentials getLoginForCommandExecution(Action action) {
+ try {
+ String user = System.getProperty("user.name");
+ String privateKey = Files.toString(new File(System.getProperty("user.home") + "/.ssh/id_rsa"), UTF_8);
+ return LoginCredentials.builder().user(user).privateKey(privateKey).build();
+ } catch (Exception e) {
+ System.err.println("error reading ssh key " + e.getMessage());
+ System.exit(1);
+ return null;
+ }
+ }
+
+ private static String credentialForClient(final String client) throws Exception {
+ String pemFile = System.getProperty("user.home") + "/.chef/" + client + ".pem";
+ return Files.toString(new File(pemFile), UTF_8);
+ }
+
+}
View
18 chef-basics/src/main/resources/logback.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<configuration>
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>- %msg%n</pattern>
+ </encoder>
+ </appender>
+ <root level="info">
+ <appender-ref ref="STDOUT"/>
+ </root>
+ <logger name="jclouds.compute" level="debug"/>
+ <logger name="net.schmizz" level="warn"/>
+<!--
+ <logger name="jclouds.wire" level="debug"/>
+ <logger name="jclouds.headers" level="debug"/>
+ <logger name="jclouds.ssh" level="debug"/>
+-->
+</configuration>
Please sign in to comment.
Something went wrong with that request. Please try again.