You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2015/01/05 14:44:19 UTC
[1/2] jclouds git commit: JCLOUDS-792: Configure chef-client security
attributes
Repository: jclouds
Updated Branches:
refs/heads/master 38ae98e40 -> 6b350fb6b
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/providers/enterprisechef/src/main/java/org/jclouds/enterprisechef/EnterpriseChefApi.java
----------------------------------------------------------------------
diff --git a/providers/enterprisechef/src/main/java/org/jclouds/enterprisechef/EnterpriseChefApi.java b/providers/enterprisechef/src/main/java/org/jclouds/enterprisechef/EnterpriseChefApi.java
index 8f1a0ed..159cb1b 100644
--- a/providers/enterprisechef/src/main/java/org/jclouds/enterprisechef/EnterpriseChefApi.java
+++ b/providers/enterprisechef/src/main/java/org/jclouds/enterprisechef/EnterpriseChefApi.java
@@ -51,74 +51,78 @@ import org.jclouds.rest.annotations.WrapWith;
@RequestFilters(SignedHeaderAuth.class)
@Consumes(MediaType.APPLICATION_JSON)
@Headers(keys = "X-Chef-Version", values = "{" + Constants.PROPERTY_API_VERSION + "}")
-public interface EnterpriseChefApi extends ChefApi
-{
- /**
- * Retrieves an existing user.
- *
- * @param name The name of the user to get.
- * @return The details of the user or <code>null</code> if not found.
- */
- @Named("user:get")
- @GET
- @Path("/users/{name}")
- @Fallback(NullOnNotFoundOr404.class)
- User getUser(@PathParam("name") String name);
+public interface EnterpriseChefApi extends ChefApi {
+ /**
+ * Retrieves an existing user.
+ *
+ * @param name
+ * The name of the user to get.
+ * @return The details of the user or <code>null</code> if not found.
+ */
+ @Named("user:get")
+ @GET
+ @Path("/users/{name}")
+ @Fallback(NullOnNotFoundOr404.class)
+ User getUser(@PathParam("name") String name);
- /**
- * List all existing groups.
- *
- * @return The list of groups.
- */
- @Named("group:list")
- @GET
- @Path("/groups")
- @ResponseParser(ParseKeySetFromJson.class)
- Set<String> listGroups();
+ /**
+ * List all existing groups.
+ *
+ * @return The list of groups.
+ */
+ @Named("group:list")
+ @GET
+ @Path("/groups")
+ @ResponseParser(ParseKeySetFromJson.class)
+ Set<String> listGroups();
- /**
- * Retrieves an existing group.
- *
- * @param name The name of the group to get.
- * @return The details of the group or <code>null</code> if not found.
- */
- @Named("group:get")
- @GET
- @Path("/groups/{name}")
- @Fallback(NullOnNotFoundOr404.class)
- Group getGroup(@PathParam("name") String name);
+ /**
+ * Retrieves an existing group.
+ *
+ * @param name
+ * The name of the group to get.
+ * @return The details of the group or <code>null</code> if not found.
+ */
+ @Named("group:get")
+ @GET
+ @Path("/groups/{name}")
+ @Fallback(NullOnNotFoundOr404.class)
+ Group getGroup(@PathParam("name") String name);
- /**
- * Creates a new group.
- *
- * @param name The name of the group to create.
- */
- @Named("group:create")
- @POST
- @Path("/groups")
- void createGroup(@WrapWith("groupname") String name);
+ /**
+ * Creates a new group.
+ *
+ * @param name
+ * The name of the group to create.
+ */
+ @Named("group:create")
+ @POST
+ @Path("/groups")
+ void createGroup(@WrapWith("groupname") String name);
- /**
- * Updates a group.
- * <p>
- * This method can be used to add actors (clients, groups) to the group.
- *
- * @param group The group with the updated information.
- */
- @Named("group:update")
- @PUT
- @Path("/groups/{name}")
- void updateGroup(
- @PathParam("name") @ParamParser(GroupName.class) @BinderParam(BindGroupToUpdateRequestJsonPayload.class) Group group);
+ /**
+ * Updates a group.
+ * <p>
+ * This method can be used to add actors (clients, groups) to the group.
+ *
+ * @param group
+ * The group with the updated information.
+ */
+ @Named("group:update")
+ @PUT
+ @Path("/groups/{name}")
+ void updateGroup(
+ @PathParam("name") @ParamParser(GroupName.class) @BinderParam(BindGroupToUpdateRequestJsonPayload.class) Group group);
- /**
- * Deletes a group.
- *
- * @param name The name of the group to delete.
- */
- @Named("group:delete")
- @DELETE
- @Path("/groups/{name}")
- void deleteGroup(@PathParam("name") String name);
+ /**
+ * Deletes a group.
+ *
+ * @param name
+ * The name of the group to delete.
+ */
+ @Named("group:delete")
+ @DELETE
+ @Path("/groups/{name}")
+ void deleteGroup(@PathParam("name") String name);
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/providers/enterprisechef/src/main/java/org/jclouds/enterprisechef/EnterpriseChefProviderMetadata.java
----------------------------------------------------------------------
diff --git a/providers/enterprisechef/src/main/java/org/jclouds/enterprisechef/EnterpriseChefProviderMetadata.java b/providers/enterprisechef/src/main/java/org/jclouds/enterprisechef/EnterpriseChefProviderMetadata.java
index 336ea7a..d72cc78 100644
--- a/providers/enterprisechef/src/main/java/org/jclouds/enterprisechef/EnterpriseChefProviderMetadata.java
+++ b/providers/enterprisechef/src/main/java/org/jclouds/enterprisechef/EnterpriseChefProviderMetadata.java
@@ -23,64 +23,55 @@ import org.jclouds.providers.ProviderMetadata;
import org.jclouds.providers.internal.BaseProviderMetadata;
/**
- * Implementation of @ link org.jclouds.types.ProviderMetadata} for Enterprise Chef
+ * Implementation of @ link org.jclouds.types.ProviderMetadata} for Enterprise
+ * Chef
*/
-public class EnterpriseChefProviderMetadata extends BaseProviderMetadata
-{
+public class EnterpriseChefProviderMetadata extends BaseProviderMetadata {
- public static Builder builder()
- {
- return new Builder();
- }
+ public static Builder builder() {
+ return new Builder();
+ }
- @Override
- public Builder toBuilder()
- {
- return builder().fromProviderMetadata(this);
- }
+ @Override
+ public Builder toBuilder() {
+ return builder().fromProviderMetadata(this);
+ }
- public EnterpriseChefProviderMetadata()
- {
- super(builder());
- }
+ public EnterpriseChefProviderMetadata() {
+ super(builder());
+ }
- public EnterpriseChefProviderMetadata(Builder builder)
- {
- super(builder);
- }
+ public EnterpriseChefProviderMetadata(final Builder builder) {
+ super(builder);
+ }
- public static Properties defaultProperties()
- {
- Properties properties = new Properties();
- return properties;
- }
+ public static Properties defaultProperties() {
+ Properties properties = new Properties();
+ return properties;
+ }
- public static class Builder extends BaseProviderMetadata.Builder
- {
+ public static class Builder extends BaseProviderMetadata.Builder {
- protected Builder()
- {
- id("enterprisechef") //
- .name("OpsCode Enterprise Chef") //
- .endpoint("https://api.opscode.com") //
- .homepage(URI.create("https://manage.opscode.com")) //
- .console(URI.create("https://manage.opscode.com")) //
- .apiMetadata(new EnterpriseChefApiMetadata()) //
- .defaultProperties(EnterpriseChefProviderMetadata.defaultProperties());
- }
+ protected Builder() {
+ id("enterprisechef") //
+ .name("OpsCode Enterprise Chef") //
+ .endpoint("https://api.opscode.com") //
+ .homepage(URI.create("https://manage.opscode.com")) //
+ .console(URI.create("https://manage.opscode.com")) //
+ .apiMetadata(new EnterpriseChefApiMetadata()) //
+ .defaultProperties(EnterpriseChefProviderMetadata.defaultProperties());
+ }
- @Override
- public EnterpriseChefProviderMetadata build()
- {
- return new EnterpriseChefProviderMetadata(this);
- }
+ @Override
+ public EnterpriseChefProviderMetadata build() {
+ return new EnterpriseChefProviderMetadata(this);
+ }
- @Override
- public Builder fromProviderMetadata(ProviderMetadata in)
- {
- super.fromProviderMetadata(in);
- return this;
- }
+ @Override
+ public Builder fromProviderMetadata(final ProviderMetadata in) {
+ super.fromProviderMetadata(in);
+ return this;
+ }
- }
+ }
}
[2/2] jclouds git commit: JCLOUDS-792: Configure chef-client security
attributes
Posted by na...@apache.org.
JCLOUDS-792: Configure chef-client security attributes
This commit also improves some internal behavior related to the
bootstrap configuration generation, and deprecated some methods that
will be removed in upcoming versions.
* Removes all methods that return the bootstrap DataBag or the raw
configuration json to return the BootstrapConfig object instead.
* Deprecates all methods that provide support for old Chef versions.
* Formats the Enterprise Chef provider according to the jclouds
formatting guidelines.
* Deprecates the ChefContext view. That view is not an abstraction and
only provides access to the ChefService. It can be obtained from the
ChefApi itself.
Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/6b350fb6
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/6b350fb6
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/6b350fb6
Branch: refs/heads/master
Commit: 6b350fb6b75abbe93a8077d52b50eaa93f2d1165
Parents: 38ae98e
Author: Ignasi Barrera <na...@apache.org>
Authored: Fri Dec 5 16:51:53 2014 +0100
Committer: Ignasi Barrera <na...@apache.org>
Committed: Mon Jan 5 14:15:54 2015 +0100
----------------------------------------------------------------------
.../src/main/java/org/jclouds/chef/ChefApi.java | 8 +
.../main/java/org/jclouds/chef/ChefContext.java | 5 +
.../main/java/org/jclouds/chef/ChefService.java | 24 +--
.../chef/config/BaseChefHttpApiModule.java | 12 +-
.../jclouds/chef/config/ChefParserModule.java | 2 +-
.../org/jclouds/chef/config/CookbookParser.java | 2 +
.../chef/config/CookbookVersionsParser.java | 2 +
.../jclouds/chef/domain/BootstrapConfig.java | 128 +++++++++++++--
.../chef/functions/BootstrapConfigForGroup.java | 27 ++-
.../chef/functions/GroupToBootScript.java | 137 +++++++++-------
...seCookbookDefinitionCheckingChefVersion.java | 2 +
...arseCookbookVersionsCheckingChefVersion.java | 2 +
.../ParseCookbookVersionsV09FromJson.java | 2 +
.../jclouds/chef/functions/RunListForGroup.java | 61 -------
.../jclouds/chef/internal/BaseChefService.java | 105 ++++++------
.../jclouds/chef/internal/ChefContextImpl.java | 7 +
.../functions/BootstrapConfigForGroupTest.java | 51 ++++--
.../chef/functions/GroupToBootScriptTest.java | 163 ++++++++++---------
.../chef/functions/RunListForGroupTest.java | 92 -----------
.../chef/internal/BaseChefServiceTest.java | 14 +-
apis/chef/src/test/resources/bootstrap-env.sh | 11 +-
.../src/test/resources/bootstrap-node-env.sh | 11 +-
apis/chef/src/test/resources/bootstrap-ssl.sh | 93 +++++++++++
apis/chef/src/test/resources/bootstrap.sh | 6 +-
apis/chef/src/test/resources/chef.crt | 30 ++++
project/pom.xml | 1 +
.../enterprisechef/EnterpriseChefApi.java | 132 +++++++--------
.../EnterpriseChefProviderMetadata.java | 89 +++++-----
28 files changed, 667 insertions(+), 552 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/main/java/org/jclouds/chef/ChefApi.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/ChefApi.java b/apis/chef/src/main/java/org/jclouds/chef/ChefApi.java
index 13f4971..0c4889b 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/ChefApi.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/ChefApi.java
@@ -85,6 +85,8 @@ import org.jclouds.rest.annotations.SkipEncoding;
import org.jclouds.rest.annotations.WrapWith;
import org.jclouds.rest.binders.BindToJsonPayload;
+import com.google.inject.Provides;
+
/**
* Provides synchronous access to Chef.
*/
@@ -92,6 +94,12 @@ import org.jclouds.rest.binders.BindToJsonPayload;
@Headers(keys = "X-Chef-Version", values = "{" + Constants.PROPERTY_API_VERSION + "}")
@Consumes(MediaType.APPLICATION_JSON)
public interface ChefApi extends Closeable {
+
+ /**
+ * Provides access to high level Chef features.
+ */
+ @Provides
+ ChefService chefService();
// Clients
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/main/java/org/jclouds/chef/ChefContext.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/ChefContext.java b/apis/chef/src/main/java/org/jclouds/chef/ChefContext.java
index 7809634..794116d 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/ChefContext.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/ChefContext.java
@@ -25,8 +25,13 @@ import com.google.inject.ImplementedBy;
/**
* Provides an entry point to Chef features.
+ *
+ * @deprecated Will be removed in next version. Directly create the
+ * {@link ChefApi} instead and access the {@link ChefService} from
+ * it.
*/
@ImplementedBy(ChefContextImpl.class)
+@Deprecated
public interface ChefContext extends View, Closeable {
/**
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/main/java/org/jclouds/chef/ChefService.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/ChefService.java b/apis/chef/src/main/java/org/jclouds/chef/ChefService.java
index 6f136fa..e15d00c 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/ChefService.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/ChefService.java
@@ -16,23 +16,26 @@
*/
package org.jclouds.chef;
-import com.google.common.io.InputSupplier;
-import com.google.inject.ImplementedBy;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+
+import org.jclouds.chef.config.ChefProperties;
import org.jclouds.chef.domain.BootstrapConfig;
import org.jclouds.chef.domain.Client;
import org.jclouds.chef.domain.CookbookVersion;
import org.jclouds.chef.domain.Environment;
import org.jclouds.chef.domain.Node;
import org.jclouds.chef.internal.BaseChefService;
-import org.jclouds.domain.JsonBall;
+import org.jclouds.chef.util.ChefUtils;
import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.ohai.config.OhaiModule;
import org.jclouds.rest.annotations.SinceApiVersion;
import org.jclouds.scriptbuilder.domain.Statement;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
+import com.google.common.io.InputSupplier;
+import com.google.inject.ImplementedBy;
/**
* Provides high level Chef operations.
@@ -105,19 +108,18 @@ public interface ChefService {
*
* @param The group to get the configured run list for.
* @return run list for all nodes bootstrapped with a certain group
+ * @deprecated USe {{@link #getBootstrapConfigForGroup(String)}.
*/
+ @Deprecated
List<String> getRunListForGroup(String group);
/**
* Gets the bootstrap configuration for a given group.
- * <p/>
- * The bootstrap configuration is a Json object containing the run list and
- * the configured attributes.
*
* @param group The name of the group.
* @return The bootstrap configuration for the given group.
*/
- JsonBall getBootstrapConfigForGroup(String group);
+ BootstrapConfig getBootstrapConfigForGroup(String group);
// Nodes / Clients
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/main/java/org/jclouds/chef/config/BaseChefHttpApiModule.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/config/BaseChefHttpApiModule.java b/apis/chef/src/main/java/org/jclouds/chef/config/BaseChefHttpApiModule.java
index 2fc4201..c8b2faa 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/config/BaseChefHttpApiModule.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/config/BaseChefHttpApiModule.java
@@ -27,17 +27,16 @@ import static org.jclouds.crypto.Pems.privateKeySpec;
import java.io.IOException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
-import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
+import org.jclouds.chef.domain.BootstrapConfig;
import org.jclouds.chef.domain.Client;
import org.jclouds.chef.functions.BootstrapConfigForGroup;
import org.jclouds.chef.functions.ClientForGroup;
-import org.jclouds.chef.functions.RunListForGroup;
import org.jclouds.chef.handlers.ChefApiErrorRetryHandler;
import org.jclouds.chef.handlers.ChefErrorHandler;
import org.jclouds.crypto.Crypto;
@@ -45,7 +44,6 @@ import org.jclouds.crypto.Pems;
import org.jclouds.date.DateService;
import org.jclouds.date.TimeStamp;
import org.jclouds.domain.Credentials;
-import org.jclouds.domain.JsonBall;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.annotation.ClientError;
@@ -177,13 +175,7 @@ public abstract class BaseChefHttpApiModule<S> extends HttpApiModule<S> {
@Provides
@Singleton
- CacheLoader<String, List<String>> runListForGroup(RunListForGroup runListForGroup) {
- return CacheLoader.from(runListForGroup);
- }
-
- @Provides
- @Singleton
- CacheLoader<String, ? extends JsonBall> bootstrapConfigForGroup(BootstrapConfigForGroup bootstrapConfigForGroup) {
+ CacheLoader<String, BootstrapConfig> bootstrapConfigForGroup(BootstrapConfigForGroup bootstrapConfigForGroup) {
return CacheLoader.from(bootstrapConfigForGroup);
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/main/java/org/jclouds/chef/config/ChefParserModule.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/config/ChefParserModule.java b/apis/chef/src/main/java/org/jclouds/chef/config/ChefParserModule.java
index c214236..c00eda5 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/config/ChefParserModule.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/config/ChefParserModule.java
@@ -288,7 +288,7 @@ public class ChefParserModule extends AbstractModule {
return (TypeAdapter<T>) new KeepLastRepeatedKeyMapTypeAdapter<K, V>(keyAdapter, valueAdapter);
}
}
-
+
@Provides
@Singleton
public Map<Type, Object> provideCustomAdapterBindings(DataBagItemAdapter adapter, PrivateKeyAdapter privateAdapter,
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/main/java/org/jclouds/chef/config/CookbookParser.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/config/CookbookParser.java b/apis/chef/src/main/java/org/jclouds/chef/config/CookbookParser.java
index 34eedde..22048c5 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/config/CookbookParser.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/config/CookbookParser.java
@@ -32,10 +32,12 @@ import javax.inject.Qualifier;
* Chef Server version 0.9 and 0.10 return a different Json when rquesting the
* cookbook definitions. This annotation can be used to setup the cookbook
* parser.
+ * @deprecated Support for Chef 0.9 and 0.10 will be removed in upcoming versions.
*/
@Target({ METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
@Qualifier
+@Deprecated
public @interface CookbookParser {
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/main/java/org/jclouds/chef/config/CookbookVersionsParser.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/config/CookbookVersionsParser.java b/apis/chef/src/main/java/org/jclouds/chef/config/CookbookVersionsParser.java
index c946917..5fd2ba5 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/config/CookbookVersionsParser.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/config/CookbookVersionsParser.java
@@ -32,10 +32,12 @@ import javax.inject.Qualifier;
* Chef Server version 0.9 and 0.10 return a different Json when rquesting the
* cookbook versions. This annotation can be used to setup the cookbook versions
* parser.
+ * @deprecated Support for Chef 0.9 and 0.10 will be removed in upcoming versions.
*/
@Target({ METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
@Qualifier
+@Deprecated
public @interface CookbookVersionsParser {
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/main/java/org/jclouds/chef/domain/BootstrapConfig.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/domain/BootstrapConfig.java b/apis/chef/src/main/java/org/jclouds/chef/domain/BootstrapConfig.java
index c10c150..7b10edc 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/domain/BootstrapConfig.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/domain/BootstrapConfig.java
@@ -18,12 +18,14 @@ package org.jclouds.chef.domain;
import static com.google.common.base.Preconditions.checkNotNull;
+import java.beans.ConstructorProperties;
import java.util.List;
import org.jclouds.domain.JsonBall;
+import org.jclouds.javax.annotation.Nullable;
-import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
+import com.google.gson.annotations.SerializedName;
/**
* Configures how the nodes in a group will bootstrap.
@@ -31,6 +33,16 @@ import com.google.common.collect.ImmutableList;
* @since 1.7
*/
public class BootstrapConfig {
+
+ public static enum SSLVerifyMode {
+ NONE, PEER;
+
+ @Override
+ public String toString() {
+ return ":verify_" + name().toLowerCase();
+ }
+ }
+
public static Builder builder() {
return new Builder();
}
@@ -39,6 +51,10 @@ public class BootstrapConfig {
private ImmutableList.Builder<String> runList = ImmutableList.builder();
private String environment;
private JsonBall attribtues;
+ private String sslCAFile;
+ private String sslCAPath;
+ private SSLVerifyMode sslVerifyMode;
+ private Boolean verifyApiCert;
/**
* Sets the run list that will be executed in the nodes of the group.
@@ -64,32 +80,118 @@ public class BootstrapConfig {
return this;
}
+ /**
+ * The file in which the OpenSSL key is saved. To be used by the Chef
+ * client to verify the certificate of the Chef Server.
+ */
+ public Builder sslCAFile(String sslCAFile) {
+ this.sslCAFile = checkNotNull(sslCAFile, "sslCAFile");
+ return this;
+ }
+
+ /**
+ * The path to where the OpenSSL keys that are used by the Chef client are
+ * located.
+ */
+ public Builder sslCAPath(String sslCAPath) {
+ this.sslCAPath = checkNotNull(sslCAPath, "sslCAPath");
+ return this;
+ }
+
+ /**
+ * The verify mode for HTTPS requests.
+ * <ul>
+ * <li>NONE - to do no validation of SSL certificates.</li>
+ * <li>PEER - to do validation of all SSL certificate, including the Chef
+ * server connections</li>
+ * </ul>
+ */
+ public Builder sslVerifyMode(SSLVerifyMode sslVerifyMode) {
+ this.sslVerifyMode = checkNotNull(sslVerifyMode, "sslVerifyMode");
+ return this;
+ }
+
+ /**
+ * Use to only do SSL validation of the Chef server connection; may be
+ * needed if the Chef client needs to talk to other services that have
+ * broken SSL certificates.
+ */
+ public Builder verifyApiCert(boolean verifyApiCert) {
+ this.verifyApiCert = verifyApiCert;
+ return this;
+ }
+
public BootstrapConfig build() {
- return new BootstrapConfig(runList.build(), Optional.fromNullable(environment),
- Optional.fromNullable(attribtues));
+ return new BootstrapConfig(runList.build(), environment, attribtues, sslCAFile, sslCAPath, sslVerifyMode,
+ verifyApiCert);
}
}
+ @SerializedName("run_list")
private final List<String> runList;
- private final Optional<String> environment;
- private final Optional<JsonBall> attribtues;
-
- protected BootstrapConfig(List<String> runList, Optional<String> environment, Optional<JsonBall> attribtues) {
- this.runList = checkNotNull(runList, "runList");
- this.environment = checkNotNull(environment, "environment");
- this.attribtues = checkNotNull(attribtues, "attributes");
+ @Nullable
+ private final String environment;
+ @Nullable
+ private final JsonBall attributes;
+ @SerializedName("ssl_ca_file")
+ @Nullable
+ private final String sslCAFile;
+ @SerializedName("ssl_ca_path")
+ @Nullable
+ private final String sslCAPath;
+ @SerializedName("ssl_verify_mode")
+ @Nullable
+ private final SSLVerifyMode sslVerifyMode;
+ @SerializedName("verify_api_cert")
+ @Nullable
+ private final Boolean verifyApiCert;
+
+ @ConstructorProperties({ "run_list", "environment", "attributes", "ssl_ca_file", "ssl_ca_path", "ssl_verify_mode",
+ "verify_api_cert" })
+ protected BootstrapConfig(List<String> runList, @Nullable String environment, @Nullable JsonBall attributes,
+ @Nullable String sslCAFile, @Nullable String sslCAPath, @Nullable SSLVerifyMode sslVerifyMode,
+ @Nullable Boolean verifyApiCert) {
+ this.runList = ImmutableList.copyOf(checkNotNull(runList, "runList"));
+ this.environment = environment;
+ this.attributes = attributes;
+ this.sslCAFile = sslCAFile;
+ this.sslCAPath = sslCAPath;
+ this.sslVerifyMode = sslVerifyMode;
+ this.verifyApiCert = verifyApiCert;
}
public List<String> getRunList() {
return runList;
}
- public Optional<String> getEnvironment() {
+ @Nullable
+ public String getEnvironment() {
return environment;
}
- public Optional<JsonBall> getAttribtues() {
- return attribtues;
+ @Nullable
+ public JsonBall getAttributes() {
+ return attributes;
+ }
+
+ @Nullable
+ public String getSslCAFile() {
+ return sslCAFile;
+ }
+
+ @Nullable
+ public String getSslCAPath() {
+ return sslCAPath;
+ }
+
+ @Nullable
+ public SSLVerifyMode getSslVerifyMode() {
+ return sslVerifyMode;
+ }
+
+ @Nullable
+ public Boolean getVerifyApiCert() {
+ return verifyApiCert;
}
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/main/java/org/jclouds/chef/functions/BootstrapConfigForGroup.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/BootstrapConfigForGroup.java b/apis/chef/src/main/java/org/jclouds/chef/functions/BootstrapConfigForGroup.java
index ec75e47..32f7c4b 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/functions/BootstrapConfigForGroup.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/functions/BootstrapConfigForGroup.java
@@ -16,46 +16,43 @@
*/
package org.jclouds.chef.functions;
-import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.chef.config.ChefProperties.CHEF_BOOTSTRAP_DATABAG;
-import java.lang.reflect.Type;
-import java.util.Map;
-
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.chef.ChefApi;
+import org.jclouds.chef.domain.BootstrapConfig;
import org.jclouds.chef.domain.DatabagItem;
-import org.jclouds.domain.JsonBall;
+import org.jclouds.json.Json;
import com.google.common.base.Function;
-import com.google.inject.TypeLiteral;
/**
- *
* Retrieves the bootstrap configuration for a specific group
*/
@Singleton
-public class BootstrapConfigForGroup implements Function<String, DatabagItem> {
- public static final Type BOOTSTRAP_CONFIG_TYPE = new TypeLiteral<Map<String, JsonBall>>() {
- }.getType();
+public class BootstrapConfigForGroup implements Function<String, BootstrapConfig> {
+
private final ChefApi api;
private final String databag;
+ private final Json json;
@Inject
- public BootstrapConfigForGroup(@Named(CHEF_BOOTSTRAP_DATABAG) String databag, ChefApi api) {
- this.databag = checkNotNull(databag, "databag");
- this.api = checkNotNull(api, "api");
+ BootstrapConfigForGroup(@Named(CHEF_BOOTSTRAP_DATABAG) String databag, ChefApi api, Json json) {
+ this.databag = databag;
+ this.api = api;
+ this.json = json;
}
@Override
- public DatabagItem apply(String from) {
+ public BootstrapConfig apply(String from) {
DatabagItem bootstrapConfig = api.getDatabagItem(databag, from);
checkState(bootstrapConfig != null, "databag item %s/%s not found", databag, from);
- return bootstrapConfig;
+ // A DatabagItem is already a JsonBall, to we can easily deserialize it
+ return json.fromJson(bootstrapConfig.toString(), BootstrapConfig.class);
}
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/main/java/org/jclouds/chef/functions/GroupToBootScript.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/GroupToBootScript.java b/apis/chef/src/main/java/org/jclouds/chef/functions/GroupToBootScript.java
index 6010353..fad4fb6 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/functions/GroupToBootScript.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/functions/GroupToBootScript.java
@@ -17,17 +17,13 @@
package org.jclouds.chef.functions;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Throwables.propagate;
-import static org.jclouds.scriptbuilder.domain.Statements.appendFile;
+import static com.google.common.collect.Iterables.transform;
+import static org.jclouds.scriptbuilder.domain.Statements.createOrOverwriteFile;
import static org.jclouds.scriptbuilder.domain.Statements.exec;
-import static org.jclouds.scriptbuilder.domain.Statements.newStatementList;
-import java.lang.reflect.Type;
import java.net.URI;
import java.security.PrivateKey;
import java.util.Collections;
-import java.util.List;
-import java.util.Map;
import java.util.regex.Pattern;
import javax.inject.Inject;
@@ -35,100 +31,119 @@ import javax.inject.Singleton;
import org.jclouds.chef.config.InstallChef;
import org.jclouds.chef.config.Validator;
+import org.jclouds.chef.domain.BootstrapConfig;
import org.jclouds.crypto.Pems;
-import org.jclouds.domain.JsonBall;
import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.json.Json;
import org.jclouds.location.Provider;
import org.jclouds.scriptbuilder.ExitInsteadOfReturn;
import org.jclouds.scriptbuilder.domain.Statement;
+import org.jclouds.scriptbuilder.domain.StatementList;
-import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.base.Splitter;
import com.google.common.base.Supplier;
+import com.google.common.base.Throwables;
import com.google.common.cache.CacheLoader;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.inject.TypeLiteral;
/**
- *
* Generates a bootstrap script relevant for a particular group
*/
@Singleton
public class GroupToBootScript {
private static final Pattern newLinePattern = Pattern.compile("(\\r\\n)|(\\n)");
-
- @VisibleForTesting
- static final Type RUN_LIST_TYPE = new TypeLiteral<Map<String, List<String>>>() {
- }.getType();
+
private final Supplier<URI> endpoint;
- private final Json json;
- private final CacheLoader<String, ? extends JsonBall> bootstrapConfigForGroup;
+ private final CacheLoader<String, BootstrapConfig> bootstrapConfigForGroup;
private final Statement installChef;
private final Optional<String> validatorName;
private final Optional<PrivateKey> validatorCredential;
@Inject
- public GroupToBootScript(@Provider Supplier<URI> endpoint, Json json,
- CacheLoader<String, ? extends JsonBall> bootstrapConfigForGroup,
+ GroupToBootScript(@Provider Supplier<URI> endpoint, CacheLoader<String, BootstrapConfig> bootstrapConfigForGroup,
@InstallChef Statement installChef, @Validator Optional<String> validatorName,
@Validator Optional<PrivateKey> validatorCredential) {
- this.endpoint = checkNotNull(endpoint, "endpoint");
- this.json = checkNotNull(json, "json");
- this.bootstrapConfigForGroup = checkNotNull(bootstrapConfigForGroup, "bootstrapConfigForGroup");
- this.installChef = checkNotNull(installChef, "installChef");
- this.validatorName = checkNotNull(validatorName, "validatorName");
- this.validatorCredential = checkNotNull(validatorCredential, validatorCredential);
+ this.endpoint = endpoint;
+ this.bootstrapConfigForGroup = bootstrapConfigForGroup;
+ this.installChef = installChef;
+ this.validatorName = validatorName;
+ this.validatorCredential = validatorCredential;
}
public Statement apply(String group, @Nullable String nodeName) {
- checkNotNull(group, "group");
- String validatorClientName = validatorName.get();
- PrivateKey validatorKey = validatorCredential.get();
-
- JsonBall bootstrapConfig = null;
+ BootstrapConfig config = null;
try {
- bootstrapConfig = bootstrapConfigForGroup.load(group);
- } catch (Exception e) {
- throw propagate(e);
+ config = bootstrapConfigForGroup.load(checkNotNull(group, "group"));
+ } catch (Exception ex) {
+ throw Throwables.propagate(ex);
}
- Map<String, JsonBall> config = json.fromJson(bootstrapConfig.toString(),
- BootstrapConfigForGroup.BOOTSTRAP_CONFIG_TYPE);
- Optional<JsonBall> environment = Optional.fromNullable(config.get("environment"));
-
String chefConfigDir = "{root}etc{fs}chef";
- Statement createChefConfigDir = exec("{md} " + chefConfigDir);
- String createNodeName;
- if (nodeName != null) {
- createNodeName = String.format("node_name \"%s\"", nodeName);
- } else {
- createNodeName = String.format("node_name \"%s-\" + o[:ipaddress]", group);
- }
- Statement createClientRb = appendFile(chefConfigDir + "{fs}client.rb", ImmutableList.of("require 'rubygems'",
- "require 'ohai'", "o = Ohai::System.new", "o.all_plugins", createNodeName, "log_level :info", "log_location STDOUT",
- String.format("validation_client_name \"%s\"", validatorClientName),
- String.format("chef_server_url \"%s\"", endpoint.get())));
+ String chefBootFile = chefConfigDir + "{fs}first-boot.json";
- Statement createValidationPem = appendFile(chefConfigDir + "{fs}validation.pem",
- Splitter.on(newLinePattern).split(Pems.pem(validatorKey)));
+ ImmutableList.Builder<Statement> statements = ImmutableList.builder();
+ statements.add(new ExitInsteadOfReturn(installChef));
+ statements.add(exec("{md} " + chefConfigDir));
+ if (config.getSslCAFile() != null) {
+ statements.add(createOrOverwriteFile(chefConfigDir + "{fs}chef-server.crt",
+ Splitter.on(newLinePattern).split(config.getSslCAFile())));
+ }
+ statements.add(createClientRbFile(chefConfigDir + "{fs}client.rb", group, nodeName, config));
+ statements.add(createOrOverwriteFile(chefConfigDir + "{fs}validation.pem",
+ Splitter.on(newLinePattern).split(Pems.pem(validatorCredential.get()))));
+ statements.add(createAttributesFile(chefBootFile, config));
+ statements.add(exec("chef-client -j " + chefBootFile));
- String chefBootFile = chefConfigDir + "{fs}first-boot.json";
- Statement createFirstBoot = appendFile(chefBootFile, Collections.singleton(json.toJson(bootstrapConfig)));
+ return new StatementList(statements.build());
+ }
- ImmutableMap.Builder<String, String> options = ImmutableMap.builder();
- options.put("-j", chefBootFile);
- if (environment.isPresent()) {
- options.put("-E", environment.get().toString());
+ private Statement createClientRbFile(String clientRbFile, String group, String nodeName, BootstrapConfig config) {
+ ImmutableList.Builder<String> clientRb = ImmutableList.builder();
+ clientRb.add("require 'rubygems'");
+ clientRb.add("require 'ohai'");
+ clientRb.add("o = Ohai::System.new");
+ clientRb.add("o.all_plugins");
+ clientRb.add("node_name \"" + (nodeName != null ? nodeName + "\"" : group + "-\" + o[:ipaddress]"));
+ clientRb.add("log_level :info");
+ clientRb.add("log_location STDOUT");
+ clientRb.add(String.format("validation_client_name \"%s\"", validatorName.get()));
+ clientRb.add(String.format("chef_server_url \"%s\"", endpoint.get()));
+ addIfPresent(clientRb, "environment", config.getEnvironment());
+ if (config.getSslCAFile() != null) {
+ addIfPresent(clientRb, "ssl_ca_file", "/etc/chef/chef-server.crt");
}
- String strOptions = Joiner.on(' ').withKeyValueSeparator(" ").join(options.build());
- Statement runChef = exec("chef-client " + strOptions);
+ addIfPresent(clientRb, "ssl_ca_path", config.getSslCAPath());
+ addIfPresent(clientRb, "ssl_verify_mode", config.getSslVerifyMode());
+ addIfPresent(clientRb, "verify_api_cert", config.getVerifyApiCert());
+ return createOrOverwriteFile(clientRbFile, clientRb.build());
+ }
- return newStatementList(new ExitInsteadOfReturn(installChef), createChefConfigDir, createClientRb, createValidationPem,
- createFirstBoot, runChef);
+ private Statement createAttributesFile(String chefBootFile, BootstrapConfig config) {
+ String attributes = config.getAttributes().toString();
+ String runlist = Joiner.on(',').join(transform(config.getRunList(), new Function<String, String>() {
+ @Override
+ public String apply(String input) {
+ return "\"" + input + "\"";
+ }
+ }));
+
+ // Append the runlist to the json attributes
+ StringBuilder sb = new StringBuilder();
+ // Strip the json ending character
+ sb.append(attributes.trim().substring(0, attributes.length() - 1));
+ sb.append(",\"run_list\":[").append(runlist).append("]");
+ sb.append("}");
+
+ return createOrOverwriteFile(chefBootFile, Collections.singleton(sb.toString()));
+ }
+
+ private void addIfPresent(ImmutableList.Builder<String> lines, String key, Object value) {
+ if (value != null) {
+ // Quote the value if it is a String
+ lines.add(String.format("%s %s", key, value instanceof String ? "\"" + value + "\"" : value.toString()));
+ }
}
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookDefinitionCheckingChefVersion.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookDefinitionCheckingChefVersion.java b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookDefinitionCheckingChefVersion.java
index ffb4201..53c6ea7 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookDefinitionCheckingChefVersion.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookDefinitionCheckingChefVersion.java
@@ -30,8 +30,10 @@ import com.google.common.base.Function;
/**
* Parses a cookbook definition from a Json response, taking care of using the
* appropriate parser.
+ * @deprecated Support for Chef 0.9 and 0.10 will be removed in upcoming verions.
*/
@Singleton
+@Deprecated
public class ParseCookbookDefinitionCheckingChefVersion implements Function<HttpResponse, Set<String>> {
@VisibleForTesting
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsCheckingChefVersion.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsCheckingChefVersion.java b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsCheckingChefVersion.java
index f82a900..e98b27a 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsCheckingChefVersion.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsCheckingChefVersion.java
@@ -30,8 +30,10 @@ import com.google.common.base.Function;
/**
* Parses a cookbook versions from a Json response, taking care of using the
* appropriate parser.
+ * @deprecated Support for Chef 0.9 and 0.10 will be removed in upcoming verions.
*/
@Singleton
+@Deprecated
public class ParseCookbookVersionsCheckingChefVersion implements Function<HttpResponse, Set<String>> {
@VisibleForTesting
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsV09FromJson.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsV09FromJson.java b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsV09FromJson.java
index 4421b3e..4bc76d4 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsV09FromJson.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/functions/ParseCookbookVersionsV09FromJson.java
@@ -30,8 +30,10 @@ import static com.google.common.collect.Iterables.getFirst;
/**
* Parses the cookbook versions in a Chef Server <= 0.9.8.
+ * @deprecated Support for Chef 0.9 and 0.10 will be removed in upcoming versions.
*/
@Singleton
+@Deprecated
public class ParseCookbookVersionsV09FromJson implements Function<HttpResponse, Set<String>> {
private final ParseJson<Map<String, Set<String>>> json;
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/main/java/org/jclouds/chef/functions/RunListForGroup.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/RunListForGroup.java b/apis/chef/src/main/java/org/jclouds/chef/functions/RunListForGroup.java
deleted file mode 100644
index b14ae71..0000000
--- a/apis/chef/src/main/java/org/jclouds/chef/functions/RunListForGroup.java
+++ /dev/null
@@ -1,61 +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.jclouds.chef.functions;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.lang.reflect.Type;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-import org.jclouds.chef.domain.DatabagItem;
-import org.jclouds.domain.JsonBall;
-import org.jclouds.json.Json;
-
-import com.google.common.base.Function;
-import com.google.inject.TypeLiteral;
-
-/**
- * Retrieves the run-list for a specific group
- */
-@Singleton
-public class RunListForGroup implements Function<String, List<String>> {
- public static final Type RUN_LIST_TYPE = new TypeLiteral<List<String>>() {
- }.getType();
- private final BootstrapConfigForGroup bootstrapConfigForGroup;
-
- private final Json json;
-
- @Inject
- public RunListForGroup(BootstrapConfigForGroup bootstrapConfigForGroup, Json json) {
- this.bootstrapConfigForGroup = checkNotNull(bootstrapConfigForGroup, "bootstrapConfigForGroup");
- this.json = checkNotNull(json, "json");
- }
-
- @Override
- public List<String> apply(String from) {
- DatabagItem bootstrapConfig = bootstrapConfigForGroup.apply(from);
- Map<String, JsonBall> config = json.fromJson(bootstrapConfig.toString(),
- BootstrapConfigForGroup.BOOTSTRAP_CONFIG_TYPE);
- JsonBall runlist = config.get("run_list");
- return json.fromJson(runlist.toString(), RUN_LIST_TYPE);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java b/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java
index 838fa4f..ca79b77 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java
@@ -43,7 +43,6 @@ import org.jclouds.chef.domain.Environment;
import org.jclouds.chef.domain.Node;
import org.jclouds.chef.functions.BootstrapConfigForGroup;
import org.jclouds.chef.functions.GroupToBootScript;
-import org.jclouds.chef.functions.RunListForGroup;
import org.jclouds.chef.strategy.CleanupStaleNodesAndClients;
import org.jclouds.chef.strategy.CreateNodeAndPopulateAutomaticAttributes;
import org.jclouds.chef.strategy.DeleteAllClientsInList;
@@ -56,7 +55,6 @@ import org.jclouds.chef.strategy.ListNodes;
import org.jclouds.chef.strategy.ListNodesInEnvironment;
import org.jclouds.chef.strategy.UpdateAutomaticAttributesOnNode;
import org.jclouds.crypto.Crypto;
-import org.jclouds.domain.JsonBall;
import org.jclouds.io.ByteStreams2;
import org.jclouds.io.Payloads;
import org.jclouds.io.payloads.RSADecryptingPayload;
@@ -67,8 +65,8 @@ import org.jclouds.logging.Logger;
import org.jclouds.scriptbuilder.domain.Statement;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
import com.google.common.base.Supplier;
-import com.google.common.collect.Maps;
import com.google.common.io.InputSupplier;
@Singleton
@@ -87,7 +85,6 @@ public class BaseChefService implements ChefService {
private final GroupToBootScript groupToBootScript;
private final String databag;
private final BootstrapConfigForGroup bootstrapConfigForGroup;
- private final RunListForGroup runListForGroup;
private final ListCookbookVersions listCookbookVersions;
private final ListCookbookVersionsInEnvironment listCookbookVersionsInEnvironment;
private final ListEnvironments listEnvironments;
@@ -100,38 +97,34 @@ public class BaseChefService implements ChefService {
protected Logger logger = Logger.NULL;
@Inject
- protected BaseChefService(ChefContext chefContext, ChefApi api,
- CleanupStaleNodesAndClients cleanupStaleNodesAndClients,
+ BaseChefService(ChefContext chefContext, ChefApi api, CleanupStaleNodesAndClients cleanupStaleNodesAndClients,
CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes,
DeleteAllNodesInList deleteAllNodesInList, ListNodes listNodes, DeleteAllClientsInList deleteAllClientsInList,
ListClients listClients, ListCookbookVersions listCookbookVersions,
UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode, Supplier<PrivateKey> privateKey,
@Named(CHEF_BOOTSTRAP_DATABAG) String databag, GroupToBootScript groupToBootScript,
- BootstrapConfigForGroup bootstrapConfigForGroup, RunListForGroup runListForGroup,
- ListEnvironments listEnvironments, ListNodesInEnvironment listNodesInEnvironment,
+ BootstrapConfigForGroup bootstrapConfigForGroup, ListEnvironments listEnvironments,
+ ListNodesInEnvironment listNodesInEnvironment,
ListCookbookVersionsInEnvironment listCookbookVersionsInEnvironment, Json json, Crypto crypto) {
- this.chefContext = checkNotNull(chefContext, "chefContext");
- this.api = checkNotNull(api, "api");
- this.cleanupStaleNodesAndClients = checkNotNull(cleanupStaleNodesAndClients, "cleanupStaleNodesAndClients");
- this.createNodeAndPopulateAutomaticAttributes = checkNotNull(createNodeAndPopulateAutomaticAttributes,
- "createNodeAndPopulateAutomaticAttributes");
- this.deleteAllNodesInList = checkNotNull(deleteAllNodesInList, "deleteAllNodesInList");
- this.listNodes = checkNotNull(listNodes, "listNodes");
- this.deleteAllClientsInList = checkNotNull(deleteAllClientsInList, "deleteAllClientsInList");
- this.listClients = checkNotNull(listClients, "listClients");
- this.listCookbookVersions = checkNotNull(listCookbookVersions, "listCookbookVersions");
- this.updateAutomaticAttributesOnNode = checkNotNull(updateAutomaticAttributesOnNode,
- "updateAutomaticAttributesOnNode");
- this.privateKey = checkNotNull(privateKey, "privateKey");
- this.groupToBootScript = checkNotNull(groupToBootScript, "groupToBootScript");
- this.databag = checkNotNull(databag, "databag");
- this.bootstrapConfigForGroup = checkNotNull(bootstrapConfigForGroup, "bootstrapConfigForGroup");
- this.runListForGroup = checkNotNull(runListForGroup, "runListForGroup");
- this.listEnvironments = checkNotNull(listEnvironments, "listEnvironments");
- this.listNodesInEnvironment = checkNotNull(listNodesInEnvironment, "listNodesInEnvironment");
- this.listCookbookVersionsInEnvironment = checkNotNull(listCookbookVersionsInEnvironment, "listCookbookVersionsInEnvironment");
- this.json = checkNotNull(json, "json");
- this.crypto = checkNotNull(crypto, "crypto");
+ this.chefContext = chefContext;
+ this.api = api;
+ this.cleanupStaleNodesAndClients = cleanupStaleNodesAndClients;
+ this.createNodeAndPopulateAutomaticAttributes = createNodeAndPopulateAutomaticAttributes;
+ this.deleteAllNodesInList = deleteAllNodesInList;
+ this.listNodes = listNodes;
+ this.deleteAllClientsInList = deleteAllClientsInList;
+ this.listClients = listClients;
+ this.listCookbookVersions = listCookbookVersions;
+ this.updateAutomaticAttributesOnNode = updateAutomaticAttributesOnNode;
+ this.privateKey = privateKey;
+ this.groupToBootScript = groupToBootScript;
+ this.databag = databag;
+ this.bootstrapConfigForGroup = bootstrapConfigForGroup;
+ this.listEnvironments = listEnvironments;
+ this.listNodesInEnvironment = listNodesInEnvironment;
+ this.listCookbookVersionsInEnvironment = listCookbookVersionsInEnvironment;
+ this.json = json;
+ this.crypto = crypto;
}
@Override
@@ -141,34 +134,20 @@ public class BaseChefService implements ChefService {
@Override
public byte[] encrypt(InputSupplier<? extends InputStream> supplier) throws IOException {
- return ByteStreams2.toByteArrayAndClose(new RSAEncryptingPayload(crypto, Payloads.newPayload(supplier.getInput()), privateKey
- .get()).openStream());
+ return ByteStreams2.toByteArrayAndClose(new RSAEncryptingPayload(crypto,
+ Payloads.newPayload(supplier.getInput()), privateKey.get()).openStream());
}
@Override
public byte[] decrypt(InputSupplier<? extends InputStream> supplier) throws IOException {
- return ByteStreams2.toByteArrayAndClose(new RSADecryptingPayload(crypto, Payloads.newPayload(supplier.getInput()), privateKey
- .get()).openStream());
+ return ByteStreams2.toByteArrayAndClose(new RSADecryptingPayload(crypto,
+ Payloads.newPayload(supplier.getInput()), privateKey.get()).openStream());
}
- @VisibleForTesting
- String buildBootstrapConfiguration(BootstrapConfig bootstrapConfig) {
- checkNotNull(bootstrapConfig, "bootstrapConfig must not be null");
-
- Map<String, Object> configMap = Maps.newLinkedHashMap();
- configMap.put("run_list", bootstrapConfig.getRunList());
-
- if (bootstrapConfig.getEnvironment().isPresent()) {
- configMap.put("environment", bootstrapConfig.getEnvironment().get());
- }
-
- if (bootstrapConfig.getAttribtues().isPresent()) {
- Map<String, Object> attributes = json.fromJson(bootstrapConfig.getAttribtues().get().toString(),
- BootstrapConfigForGroup.BOOTSTRAP_CONFIG_TYPE);
- configMap.putAll(attributes);
+ private static void putIfPresent(Map<String, Object> configMap, Optional<?> configProperty, String name) {
+ if (configProperty.isPresent()) {
+ configMap.put(name, configProperty.get().toString());
}
-
- return json.toJson(configMap);
}
@Override
@@ -183,6 +162,7 @@ public class BaseChefService implements ChefService {
@Override
public void updateBootstrapConfigForGroup(String group, BootstrapConfig bootstrapConfig) {
+ checkNotNull(bootstrapConfig, "bootstrapConfig cannot be null");
try {
api.createDatabag(databag);
} catch (IllegalStateException e) {
@@ -190,22 +170,31 @@ public class BaseChefService implements ChefService {
}
String jsonConfig = buildBootstrapConfiguration(bootstrapConfig);
- DatabagItem runlist = new DatabagItem(group, jsonConfig);
+ DatabagItem config = new DatabagItem(group, jsonConfig);
if (api.getDatabagItem(databag, group) == null) {
- api.createDatabagItem(databag, runlist);
+ api.createDatabagItem(databag, config);
} else {
- api.updateDatabagItem(databag, runlist);
+ api.updateDatabagItem(databag, config);
}
}
+
+ @VisibleForTesting
+ String buildBootstrapConfiguration(BootstrapConfig config) {
+ return json.toJson(config);
+ }
+ /**
+ * @deprecated Use {{@link #getBootstrapConfigForGroup(String)}.
+ */
@Override
+ @Deprecated
public List<String> getRunListForGroup(String group) {
- return runListForGroup.apply(group);
+ return getBootstrapConfigForGroup(group).getRunList();
}
@Override
- public JsonBall getBootstrapConfigForGroup(String group) {
+ public BootstrapConfig getBootstrapConfigForGroup(String group) {
return bootstrapConfigForGroup.apply(group);
}
@@ -259,8 +248,8 @@ public class BaseChefService implements ChefService {
return listCookbookVersions.execute();
}
- @Override public Iterable<? extends CookbookVersion> listCookbookVersions(
- ExecutorService executorService) {
+ @Override
+ public Iterable<? extends CookbookVersion> listCookbookVersions(ExecutorService executorService) {
return listCookbookVersions.execute(executorService);
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/main/java/org/jclouds/chef/internal/ChefContextImpl.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/internal/ChefContextImpl.java b/apis/chef/src/main/java/org/jclouds/chef/internal/ChefContextImpl.java
index 8aef880..e7d1170 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/internal/ChefContextImpl.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/internal/ChefContextImpl.java
@@ -24,6 +24,7 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.Context;
+import org.jclouds.chef.ChefApi;
import org.jclouds.chef.ChefContext;
import org.jclouds.chef.ChefService;
import org.jclouds.internal.BaseView;
@@ -31,7 +32,13 @@ import org.jclouds.location.Provider;
import com.google.common.reflect.TypeToken;
+/**
+ * @deprecated Will be removed in next version. Directly create the
+ * {@link ChefApi} instead and access the {@link ChefService} from
+ * it.
+ */
@Singleton
+@Deprecated
public class ChefContextImpl extends BaseView implements ChefContext {
private final ChefService chefService;
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/test/java/org/jclouds/chef/functions/BootstrapConfigForGroupTest.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/test/java/org/jclouds/chef/functions/BootstrapConfigForGroupTest.java b/apis/chef/src/test/java/org/jclouds/chef/functions/BootstrapConfigForGroupTest.java
index f326482..c704ee6 100644
--- a/apis/chef/src/test/java/org/jclouds/chef/functions/BootstrapConfigForGroupTest.java
+++ b/apis/chef/src/test/java/org/jclouds/chef/functions/BootstrapConfigForGroupTest.java
@@ -25,50 +25,65 @@ import static org.testng.Assert.assertEquals;
import java.io.IOException;
import org.jclouds.chef.ChefApi;
+import org.jclouds.chef.domain.BootstrapConfig;
import org.jclouds.chef.domain.Client;
import org.jclouds.chef.domain.DatabagItem;
-import org.jclouds.rest.annotations.Api;
+import org.jclouds.json.Json;
+import org.jclouds.json.config.GsonModule;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
@Test(groups = "unit", testName = "BootstrapConfigForGroupTest")
public class BootstrapConfigForGroupTest {
+ private Json json;
+
+ @BeforeClass
+ public void setup() {
+ Injector injector = Guice.createInjector(new GsonModule());
+ json = injector.getInstance(Json.class);
+ }
+
@Test(expectedExceptions = IllegalStateException.class)
public void testWhenNoDatabagItem() throws IOException {
ChefApi chefApi = createMock(ChefApi.class);
Client client = createMock(Client.class);
- BootstrapConfigForGroup fn = new BootstrapConfigForGroup("jclouds", chefApi);
+ BootstrapConfigForGroup fn = new BootstrapConfigForGroup("jclouds", chefApi, json);
expect(chefApi.getDatabagItem("jclouds", "foo")).andReturn(null);
-
- replay(client);
- replay(chefApi);
+ replay(client, chefApi);
fn.apply("foo");
- verify(client);
- verify(chefApi);
+ verify(client, chefApi);
}
@Test
public void testReturnsItem() throws IOException {
ChefApi chefApi = createMock(ChefApi.class);
- Api api = createMock(Api.class);
-
- BootstrapConfigForGroup fn = new BootstrapConfigForGroup("jclouds", chefApi);
- DatabagItem config = new DatabagItem("foo",
- "{\"tomcat6\":{\"ssl_port\":8433},\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}");
+ Client client = createMock(Client.class);
- expect(chefApi.getDatabagItem("jclouds", "foo")).andReturn(config);
+ BootstrapConfigForGroup fn = new BootstrapConfigForGroup("jclouds", chefApi, json);
+ DatabagItem databag = new DatabagItem("foo",
+ "{\"environment\":\"development\",\"ssl_ca_file\":\"/etc/certs/chef-server.crt\","
+ + "\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"],"
+ + "\"attributes\":{\"tomcat6\":{\"ssl_port\":8433}}}");
- replay(api);
- replay(chefApi);
+ expect(chefApi.getDatabagItem("jclouds", "foo")).andReturn(databag);
+ replay(client, chefApi);
- assertEquals(fn.apply("foo"), config);
+ BootstrapConfig config = fn.apply("foo");
+ assertEquals(config.getEnvironment(), "development");
+ assertEquals(config.getSslCAFile(), "/etc/certs/chef-server.crt");
+ assertEquals(config.getRunList().get(0), "recipe[apache2]");
+ assertEquals(config.getRunList().get(1), "role[webserver]");
+ assertEquals(config.getAttributes().toString(), "{\"tomcat6\":{\"ssl_port\":8433}}");
- verify(api);
- verify(chefApi);
+ verify(client, chefApi);
}
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/test/java/org/jclouds/chef/functions/GroupToBootScriptTest.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/test/java/org/jclouds/chef/functions/GroupToBootScriptTest.java b/apis/chef/src/test/java/org/jclouds/chef/functions/GroupToBootScriptTest.java
index 89b6ec0..9cf0690 100644
--- a/apis/chef/src/test/java/org/jclouds/chef/functions/GroupToBootScriptTest.java
+++ b/apis/chef/src/test/java/org/jclouds/chef/functions/GroupToBootScriptTest.java
@@ -33,10 +33,11 @@ import org.jclouds.chef.ChefApiMetadata;
import org.jclouds.chef.config.ChefBootstrapModule;
import org.jclouds.chef.config.ChefParserModule;
import org.jclouds.chef.config.InstallChef;
-import org.jclouds.chef.domain.DatabagItem;
+import org.jclouds.chef.domain.BootstrapConfig;
+import org.jclouds.chef.domain.BootstrapConfig.SSLVerifyMode;
+import org.jclouds.chef.util.RunListBuilder;
import org.jclouds.crypto.PemsTest;
import org.jclouds.domain.JsonBall;
-import org.jclouds.json.Json;
import org.jclouds.json.config.GsonModule;
import org.jclouds.rest.annotations.ApiVersion;
import org.jclouds.scriptbuilder.domain.OsFamily;
@@ -61,7 +62,6 @@ import com.google.inject.name.Names;
@Test(groups = "unit", testName = "GroupToBootScriptTest")
public class GroupToBootScriptTest {
- private Json json;
private Statement installChefGems;
private Statement installChefOmnibus;
private Optional<String> validatorName;
@@ -88,7 +88,6 @@ public class GroupToBootScriptTest {
}
}, new ChefParserModule(), new GsonModule(), new ChefBootstrapModule());
- json = injectorGems.getInstance(Json.class);
installChefGems = injectorGems.getInstance(Key.get(Statement.class, InstallChef.class));
installChefOmnibus = injectorOmnibus.getInstance(Key.get(Statement.class, InstallChef.class));
validatorName = Optional.<String> of("chef-validator");
@@ -97,25 +96,25 @@ public class GroupToBootScriptTest {
@Test(expectedExceptions = IllegalStateException.class)
public void testMustHaveValidatorName() {
Optional<PrivateKey> validatorCredential = Optional.of(createMock(PrivateKey.class));
- GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json,
- CacheLoader.from(Functions.forMap(ImmutableMap.<String, DatabagItem> of())), installChefGems,
- Optional.<String> absent(), validatorCredential);
+ GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")),
+ CacheLoader.from(Functions.forMap(ImmutableMap.of("foo", BootstrapConfig.builder().build()))),
+ installChefOmnibus, Optional.<String> absent(), validatorCredential);
fn.apply("foo", null);
}
@Test(expectedExceptions = IllegalStateException.class)
public void testMustHaveValidatorCredential() {
- GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json,
- CacheLoader.from(Functions.forMap(ImmutableMap.<String, DatabagItem> of())), installChefGems,
- validatorName, Optional.<PrivateKey> absent());
+ GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")),
+ CacheLoader.from(Functions.forMap(ImmutableMap.of("foo", BootstrapConfig.builder().build()))),
+ installChefOmnibus, validatorName, Optional.<PrivateKey> absent());
fn.apply("foo", null);
}
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Key 'foo' not present in map")
public void testMustHaveRunScriptsName() {
Optional<PrivateKey> validatorCredential = Optional.of(createMock(PrivateKey.class));
- GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json,
- CacheLoader.from(Functions.forMap(ImmutableMap.<String, DatabagItem> of())), installChefGems,
+ GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")),
+ CacheLoader.from(Functions.forMap(ImmutableMap.<String, BootstrapConfig> of())), installChefOmnibus,
validatorName, validatorCredential);
fn.apply("foo", null);
}
@@ -123,18 +122,18 @@ public class GroupToBootScriptTest {
@Test(expectedExceptions = NullPointerException.class, expectedExceptionsMessageRegExp = "null value in entry: foo=null")
public void testMustHaveRunScriptsValue() {
Optional<PrivateKey> validatorCredential = Optional.of(createMock(PrivateKey.class));
- GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json,
- CacheLoader.from(Functions.forMap(ImmutableMap.<String, DatabagItem> of("foo", (DatabagItem) null))),
- installChefGems, validatorName, validatorCredential);
+ GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")),
+ CacheLoader.from(Functions.forMap(ImmutableMap.of("foo", (BootstrapConfig) null))), installChefOmnibus,
+ validatorName, validatorCredential);
fn.apply("foo", null);
}
public void testOneRecipe() throws IOException {
Optional<PrivateKey> validatorCredential = Optional.of(createMock(PrivateKey.class));
- GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json,
- CacheLoader.from(Functions.forMap(ImmutableMap.<String, JsonBall> of("foo", new JsonBall(
- "{\"tomcat6\":{\"ssl_port\":8433},\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}")))),
- installChefGems, validatorName, validatorCredential);
+ BootstrapConfig config = BootstrapConfig.builder().attributes(new JsonBall("{\"tomcat6\":{\"ssl_port\":8433}}"))
+ .runList(new RunListBuilder().addRecipe("apache2").addRole("webserver").build()).build();
+
+ GroupToBootScript fn = groupToBootScriptFor(config, validatorCredential, false);
PrivateKey validatorKey = validatorCredential.get();
expect(validatorKey.getEncoded()).andReturn(PemsTest.PRIVATE_KEY.getBytes());
@@ -142,26 +141,19 @@ public class GroupToBootScriptTest {
assertEquals(
fn.apply("foo", null).render(OsFamily.UNIX),
- exitInsteadOfReturn(
- OsFamily.UNIX,
- Resources.toString(Resources.getResource("test_install_ruby." + ShellToken.SH.to(OsFamily.UNIX)),
- Charsets.UTF_8)
- + Resources.toString(
- Resources.getResource("test_install_rubygems." + ShellToken.SH.to(OsFamily.UNIX)),
- Charsets.UTF_8)
- + "gem install chef --no-rdoc --no-ri\n"
- + Resources.toString(Resources.getResource("bootstrap.sh"), Charsets.UTF_8)));
+ exitInsteadOfReturn(OsFamily.UNIX, readContent("test_install_ruby.sh")
+ + readContent("test_install_rubygems.sh"))
+ + "gem install chef --no-rdoc --no-ri\n" + readContent("bootstrap.sh"));
verify(validatorKey);
}
public void testOneRecipeAndEnvironment() throws IOException {
Optional<PrivateKey> validatorCredential = Optional.of(createMock(PrivateKey.class));
- GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json,
- CacheLoader.from(Functions.forMap(ImmutableMap.<String, JsonBall> of("foo", new JsonBall(
- "{\"tomcat6\":{\"ssl_port\":8433},\"environment\":\"env\","
- + "\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}")))), installChefGems,
- validatorName, validatorCredential);
+ BootstrapConfig config = BootstrapConfig.builder().attributes(new JsonBall("{\"tomcat6\":{\"ssl_port\":8433}}"))
+ .environment("env").runList(new RunListBuilder().addRecipe("apache2").addRole("webserver").build()).build();
+
+ GroupToBootScript fn = groupToBootScriptFor(config, validatorCredential, false);
PrivateKey validatorKey = validatorCredential.get();
expect(validatorKey.getEncoded()).andReturn(PemsTest.PRIVATE_KEY.getBytes());
@@ -169,82 +161,99 @@ public class GroupToBootScriptTest {
assertEquals(
fn.apply("foo", null).render(OsFamily.UNIX),
- exitInsteadOfReturn(
- OsFamily.UNIX,
- Resources.toString(Resources.getResource("test_install_ruby." + ShellToken.SH.to(OsFamily.UNIX)),
- Charsets.UTF_8)
- + Resources.toString(
- Resources.getResource("test_install_rubygems." + ShellToken.SH.to(OsFamily.UNIX)),
- Charsets.UTF_8)
- + "gem install chef --no-rdoc --no-ri\n"
- + Resources.toString(Resources.getResource("bootstrap-env.sh"), Charsets.UTF_8)));
+ exitInsteadOfReturn(OsFamily.UNIX, readContent("test_install_ruby.sh")
+ + readContent("test_install_rubygems.sh") + "gem install chef --no-rdoc --no-ri\n"
+ + readContent("bootstrap-env.sh")));
verify(validatorKey);
}
public void testOneRecipeOmnibus() throws IOException {
Optional<PrivateKey> validatorCredential = Optional.of(createMock(PrivateKey.class));
- GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json,
- CacheLoader.from(Functions.forMap(ImmutableMap.<String, JsonBall> of("foo", new JsonBall(
- "{\"tomcat6\":{\"ssl_port\":8433},\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}")))),
- installChefOmnibus, validatorName, validatorCredential);
+ BootstrapConfig config = BootstrapConfig.builder().attributes(new JsonBall("{\"tomcat6\":{\"ssl_port\":8433}}"))
+ .runList(new RunListBuilder().addRecipe("apache2").addRole("webserver").build()).build();
+
+ GroupToBootScript fn = groupToBootScriptFor(config, validatorCredential, true);
PrivateKey validatorKey = validatorCredential.get();
expect(validatorKey.getEncoded()).andReturn(PemsTest.PRIVATE_KEY.getBytes());
replay(validatorKey);
- assertEquals(
- fn.apply("foo", null).render(OsFamily.UNIX),
+ assertEquals(fn.apply("foo", null).render(OsFamily.UNIX),
"setupPublicCurl || exit 1\ncurl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 "
- + "-X GET https://www.opscode.com/chef/install.sh |(bash)\n"
- + Resources.toString(Resources.getResource("bootstrap.sh"), Charsets.UTF_8));
+ + "-X GET https://www.opscode.com/chef/install.sh |(bash)\n" + readContent("bootstrap.sh"));
verify(validatorKey);
}
public void testOneRecipeAndEnvironmentOmnibus() throws IOException {
Optional<PrivateKey> validatorCredential = Optional.of(createMock(PrivateKey.class));
- GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json,
- CacheLoader.from(Functions.forMap(ImmutableMap.<String, JsonBall> of("foo", new JsonBall(
- "{\"tomcat6\":{\"ssl_port\":8433},\"environment\":\"env\","
- + "\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}")))), installChefOmnibus,
- validatorName, validatorCredential);
+ BootstrapConfig config = BootstrapConfig.builder().attributes(new JsonBall("{\"tomcat6\":{\"ssl_port\":8433}}"))
+ .environment("env").runList(new RunListBuilder().addRecipe("apache2").addRole("webserver").build()).build();
+
+ GroupToBootScript fn = groupToBootScriptFor(config, validatorCredential, true);
PrivateKey validatorKey = validatorCredential.get();
expect(validatorKey.getEncoded()).andReturn(PemsTest.PRIVATE_KEY.getBytes());
replay(validatorKey);
- assertEquals(
- fn.apply("foo", null).render(OsFamily.UNIX),
+ assertEquals(fn.apply("foo", null).render(OsFamily.UNIX),
"setupPublicCurl || exit 1\ncurl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 "
- + "-X GET https://www.opscode.com/chef/install.sh |(bash)\n"
- + Resources.toString(Resources.getResource("bootstrap-env.sh"), Charsets.UTF_8));
+ + "-X GET https://www.opscode.com/chef/install.sh |(bash)\n" + readContent("bootstrap-env.sh"));
verify(validatorKey);
}
- private static String exitInsteadOfReturn(OsFamily family, String input) {
- return input.replaceAll(ShellToken.RETURN.to(family), ShellToken.EXIT.to(family));
+ public void testCustomNodeName() throws IOException {
+ Optional<PrivateKey> validatorCredential = Optional.of(createMock(PrivateKey.class));
+ BootstrapConfig config = BootstrapConfig.builder().attributes(new JsonBall("{\"tomcat6\":{\"ssl_port\":8433}}"))
+ .environment("env").runList(new RunListBuilder().addRecipe("apache2").addRole("webserver").build()).build();
+
+ GroupToBootScript fn = groupToBootScriptFor(config, validatorCredential, true);
+
+ PrivateKey validatorKey = validatorCredential.get();
+ expect(validatorKey.getEncoded()).andReturn(PemsTest.PRIVATE_KEY.getBytes());
+ replay(validatorKey);
+
+ assertEquals(fn.apply("foo", "bar").render(OsFamily.UNIX),
+ "setupPublicCurl || exit 1\ncurl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 "
+ + "-X GET https://www.opscode.com/chef/install.sh |(bash)\n" + readContent("bootstrap-node-env.sh"));
+
+ verify(validatorKey);
}
- public void testCustomNodeName() throws IOException {
- Optional<PrivateKey> validatorCredential = Optional.of(createMock(PrivateKey.class));
- GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json,
- CacheLoader.from(Functions.forMap(ImmutableMap.<String, JsonBall> of("foo", new JsonBall(
- "{\"tomcat6\":{\"ssl_port\":8433},\"environment\":\"env\","
- + "\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}")))), installChefOmnibus,
- validatorName, validatorCredential);
+ public void testCustomSecurityOptions() throws IOException {
+ Optional<PrivateKey> validatorCredential = Optional.of(createMock(PrivateKey.class));
+ BootstrapConfig config = BootstrapConfig.builder().attributes(new JsonBall("{\"tomcat6\":{\"ssl_port\":8433}}"))
+ .runList(new RunListBuilder().addRecipe("apache2").addRole("webserver").build())
+ .sslCAFile(readContent("chef.crt")).sslCAPath("/etc/chef").sslVerifyMode(SSLVerifyMode.PEER)
+ .verifyApiCert(true).build();
- PrivateKey validatorKey = validatorCredential.get();
- expect(validatorKey.getEncoded()).andReturn(PemsTest.PRIVATE_KEY.getBytes());
- replay(validatorKey);
+ GroupToBootScript fn = groupToBootScriptFor(config, validatorCredential, true);
- assertEquals(
- fn.apply("foo", "bar").render(OsFamily.UNIX),
+ PrivateKey validatorKey = validatorCredential.get();
+ expect(validatorKey.getEncoded()).andReturn(PemsTest.PRIVATE_KEY.getBytes());
+ replay(validatorKey);
+
+ assertEquals(fn.apply("foo", null).render(OsFamily.UNIX),
"setupPublicCurl || exit 1\ncurl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 "
- + "-X GET https://www.opscode.com/chef/install.sh |(bash)\n"
- + Resources.toString(Resources.getResource("bootstrap-node-env.sh"), Charsets.UTF_8));
+ + "-X GET https://www.opscode.com/chef/install.sh |(bash)\n" + readContent("bootstrap-ssl.sh"));
- verify(validatorKey);
- }
+ verify(validatorKey);
+ }
+
+ private static String exitInsteadOfReturn(OsFamily family, String input) {
+ return input.replaceAll(ShellToken.RETURN.to(family), ShellToken.EXIT.to(family));
+ }
+
+ private GroupToBootScript groupToBootScriptFor(BootstrapConfig config, Optional<PrivateKey> validatorCredential,
+ boolean useOmnibus) {
+ return new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")),
+ CacheLoader.from(Functions.forMap(ImmutableMap.of("foo", config))), useOmnibus ? installChefOmnibus
+ : installChefGems, validatorName, validatorCredential);
+ }
+
+ private static String readContent(String resource) throws IOException {
+ return Resources.toString(Resources.getResource(resource), Charsets.UTF_8);
+ }
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/test/java/org/jclouds/chef/functions/RunListForGroupTest.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/test/java/org/jclouds/chef/functions/RunListForGroupTest.java b/apis/chef/src/test/java/org/jclouds/chef/functions/RunListForGroupTest.java
deleted file mode 100644
index 28b8833..0000000
--- a/apis/chef/src/test/java/org/jclouds/chef/functions/RunListForGroupTest.java
+++ /dev/null
@@ -1,92 +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.jclouds.chef.functions;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.testng.Assert.assertEquals;
-
-import java.io.IOException;
-
-import org.jclouds.chef.ChefApi;
-import org.jclouds.chef.ChefApiMetadata;
-import org.jclouds.chef.config.ChefParserModule;
-import org.jclouds.chef.domain.Client;
-import org.jclouds.chef.domain.DatabagItem;
-import org.jclouds.json.Json;
-import org.jclouds.json.config.GsonModule;
-import org.jclouds.rest.annotations.Api;
-import org.jclouds.rest.annotations.ApiVersion;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-
-@Test(groups = "unit", testName = "RunListForGroupTest")
-public class RunListForGroupTest {
- private Injector injector = Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bind(String.class).annotatedWith(ApiVersion.class).toInstance(ChefApiMetadata.DEFAULT_API_VERSION);
- }
- }, new ChefParserModule(), new GsonModule());
-
- private Json json = injector.getInstance(Json.class);
-
- @Test(expectedExceptions = IllegalStateException.class)
- public void testWhenNoDatabagItem() throws IOException {
- ChefApi chefApi = createMock(ChefApi.class);
- Client client = createMock(Client.class);
-
- RunListForGroup fn = new RunListForGroup(new BootstrapConfigForGroup("jclouds", chefApi), json);
-
- expect(chefApi.getDatabagItem("jclouds", "foo")).andReturn(null);
-
- replay(client);
- replay(chefApi);
-
- fn.apply("foo");
-
- verify(client);
- verify(chefApi);
- }
-
- @Test
- public void testReadRunList() throws IOException {
- ChefApi chefApi = createMock(ChefApi.class);
- Api api = createMock(Api.class);
-
- RunListForGroup fn = new RunListForGroup(new BootstrapConfigForGroup("jclouds", chefApi), json);
- DatabagItem config = new DatabagItem("foo",
- "{\"tomcat6\":{\"ssl_port\":8433},\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}");
-
- expect(chefApi.getDatabagItem("jclouds", "foo")).andReturn(config);
-
- replay(api);
- replay(chefApi);
-
- assertEquals(fn.apply("foo"), ImmutableList.of("recipe[apache2]", "role[webserver]"));
-
- verify(api);
- verify(chefApi);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefServiceTest.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefServiceTest.java b/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefServiceTest.java
index d998534..e6de8e3 100644
--- a/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefServiceTest.java
+++ b/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefServiceTest.java
@@ -53,11 +53,6 @@ public class BaseChefServiceTest {
chefService = injector.getInstance(BaseChefService.class);
}
- @Test(expectedExceptions = NullPointerException.class, expectedExceptionsMessageRegExp = "bootstrapConfig must not be null")
- public void testBuildBootstrapConfigurationWithNullConfig() {
- chefService.buildBootstrapConfiguration(null);
- }
-
public void testBuildBootstrapConfigurationWithEmptyRunlist() {
BootstrapConfig bootstrapConfig = BootstrapConfig.builder().runList(ImmutableList.<String> of()).build();
String config = chefService.buildBootstrapConfiguration(bootstrapConfig);
@@ -76,7 +71,7 @@ public class BaseChefServiceTest {
BootstrapConfig bootstrapConfig = BootstrapConfig.builder().runList(runlist).attributes(new JsonBall("{}"))
.build();
String config = chefService.buildBootstrapConfiguration(bootstrapConfig);
- assertEquals(config, "{\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}");
+ assertEquals(config, "{\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"],\"attributes\":{}}");
}
public void testBuildBootstrapConfigurationWithRunlistAndAttributes() {
@@ -84,7 +79,8 @@ public class BaseChefServiceTest {
BootstrapConfig bootstrapConfig = BootstrapConfig.builder().runList(runlist)
.attributes(new JsonBall("{\"tomcat6\":{\"ssl_port\":8433}}")).build();
String config = chefService.buildBootstrapConfiguration(bootstrapConfig);
- assertEquals(config, "{\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"],\"tomcat6\":{\"ssl_port\":8433}}");
+ assertEquals(config,
+ "{\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"],\"attributes\":{\"tomcat6\":{\"ssl_port\":8433}}}");
}
public void testBuildBootstrapConfigurationWithRunlistAndAttributesAndEnvironment() {
@@ -92,8 +88,8 @@ public class BaseChefServiceTest {
BootstrapConfig bootstrapConfig = BootstrapConfig.builder().runList(runlist)
.attributes(new JsonBall("{\"tomcat6\":{\"ssl_port\":8433}}")).environment("env").build();
String config = chefService.buildBootstrapConfiguration(bootstrapConfig);
- assertEquals(config,
- "{\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"],\"environment\":\"env\",\"tomcat6\":{\"ssl_port\":8433}}");
+ assertEquals(config, "{\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"],\"environment\":\"env\","
+ + "\"attributes\":{\"tomcat6\":{\"ssl_port\":8433}}}");
}
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/test/resources/bootstrap-env.sh
----------------------------------------------------------------------
diff --git a/apis/chef/src/test/resources/bootstrap-env.sh b/apis/chef/src/test/resources/bootstrap-env.sh
index 315e248..0bd241d9 100755
--- a/apis/chef/src/test/resources/bootstrap-env.sh
+++ b/apis/chef/src/test/resources/bootstrap-env.sh
@@ -1,5 +1,5 @@
mkdir -p /etc/chef
-cat >> /etc/chef/client.rb <<-'END_OF_JCLOUDS_FILE'
+cat > /etc/chef/client.rb <<-'END_OF_JCLOUDS_FILE'
require 'rubygems'
require 'ohai'
o = Ohai::System.new
@@ -9,8 +9,9 @@ cat >> /etc/chef/client.rb <<-'END_OF_JCLOUDS_FILE'
log_location STDOUT
validation_client_name "chef-validator"
chef_server_url "http://localhost:4000"
+ environment "env"
END_OF_JCLOUDS_FILE
-cat >> /etc/chef/validation.pem <<-'END_OF_JCLOUDS_FILE'
+cat > /etc/chef/validation.pem <<-'END_OF_JCLOUDS_FILE'
-----BEGIN PRIVATE KEY-----
LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVB
eWIyWkpKcUdtMEtLUis4bmZRSk5zU2QrRjl0WE5NVjdDZk9jVzZqc3FzOEVaZ2lW
@@ -50,7 +51,7 @@ cat >> /etc/chef/validation.pem <<-'END_OF_JCLOUDS_FILE'
-----END PRIVATE KEY-----
END_OF_JCLOUDS_FILE
-cat >> /etc/chef/first-boot.json <<-'END_OF_JCLOUDS_FILE'
- {"tomcat6":{"ssl_port":8433},"environment":"env","run_list":["recipe[apache2]","role[webserver]"]}
+cat > /etc/chef/first-boot.json <<-'END_OF_JCLOUDS_FILE'
+ {"tomcat6":{"ssl_port":8433},"run_list":["recipe[apache2]","role[webserver]"]}
END_OF_JCLOUDS_FILE
-chef-client -j /etc/chef/first-boot.json -E "env"
+chef-client -j /etc/chef/first-boot.json
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/test/resources/bootstrap-node-env.sh
----------------------------------------------------------------------
diff --git a/apis/chef/src/test/resources/bootstrap-node-env.sh b/apis/chef/src/test/resources/bootstrap-node-env.sh
index 84713d6..bf73cc6 100755
--- a/apis/chef/src/test/resources/bootstrap-node-env.sh
+++ b/apis/chef/src/test/resources/bootstrap-node-env.sh
@@ -1,5 +1,5 @@
mkdir -p /etc/chef
-cat >> /etc/chef/client.rb <<-'END_OF_JCLOUDS_FILE'
+cat > /etc/chef/client.rb <<-'END_OF_JCLOUDS_FILE'
require 'rubygems'
require 'ohai'
o = Ohai::System.new
@@ -9,8 +9,9 @@ cat >> /etc/chef/client.rb <<-'END_OF_JCLOUDS_FILE'
log_location STDOUT
validation_client_name "chef-validator"
chef_server_url "http://localhost:4000"
+ environment "env"
END_OF_JCLOUDS_FILE
-cat >> /etc/chef/validation.pem <<-'END_OF_JCLOUDS_FILE'
+cat > /etc/chef/validation.pem <<-'END_OF_JCLOUDS_FILE'
-----BEGIN PRIVATE KEY-----
LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVB
eWIyWkpKcUdtMEtLUis4bmZRSk5zU2QrRjl0WE5NVjdDZk9jVzZqc3FzOEVaZ2lW
@@ -50,7 +51,7 @@ cat >> /etc/chef/validation.pem <<-'END_OF_JCLOUDS_FILE'
-----END PRIVATE KEY-----
END_OF_JCLOUDS_FILE
-cat >> /etc/chef/first-boot.json <<-'END_OF_JCLOUDS_FILE'
- {"tomcat6":{"ssl_port":8433},"environment":"env","run_list":["recipe[apache2]","role[webserver]"]}
+cat > /etc/chef/first-boot.json <<-'END_OF_JCLOUDS_FILE'
+ {"tomcat6":{"ssl_port":8433},"run_list":["recipe[apache2]","role[webserver]"]}
END_OF_JCLOUDS_FILE
-chef-client -j /etc/chef/first-boot.json -E "env"
+chef-client -j /etc/chef/first-boot.json
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/test/resources/bootstrap-ssl.sh
----------------------------------------------------------------------
diff --git a/apis/chef/src/test/resources/bootstrap-ssl.sh b/apis/chef/src/test/resources/bootstrap-ssl.sh
new file mode 100755
index 0000000..0299f8b
--- /dev/null
+++ b/apis/chef/src/test/resources/bootstrap-ssl.sh
@@ -0,0 +1,93 @@
+mkdir -p /etc/chef
+cat > /etc/chef/chef-server.crt <<-'END_OF_JCLOUDS_FILE'
+ -----BEGIN CERTIFICATE-----
+ MIIFDTCCA/WgAwIBAgIQBZ8R1sZP2Lbc8x554UUQ2DANBgkqhkiG9w0BAQsFADBN
+ MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E
+ aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTQxMTEwMDAwMDAwWhcN
+ MTcxMTE0MTIwMDAwWjBlMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
+ bjEQMA4GA1UEBxMHU2VhdHRsZTEbMBkGA1UEChMSQ2hlZiBTb2Z0d2FyZSwgSW5j
+ MRIwEAYDVQQDDAkqLmNoZWYuaW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+ AoIBAQC3xCIczkV10O5jTDpbd4YlPLC6kfnVoOkno2N/OOlcLQu3ulj/Lj1j4r6e
+ 2XthJLcFgTO+y+1/IKnnpLKDfkx1YngWEBXEBP+MrrpDUKKs053s45/bI9QBPISA
+ tXgnYxMH9Glo6FWWd13TUq++OKGw1p1wazH64XK4MAf5y/lkmWXIWumNuO35ZqtB
+ ME3wJISwVHzHB2CQjlDklt+Mb0APEiIFIZflgu9JNBYzLdvUtxiz15FUZQI7SsYL
+ TfXOD1KBNMWqN8snG2e5gRAzB2D161DFvAZt8OiYUe+3QurNlTYVzeHv1ok6UqgM
+ ZcLzg8m801rRip0D7FCGvMCU/ktdAgMBAAGjggHPMIIByzAfBgNVHSMEGDAWgBQP
+ gGEcgjFh1S8o541GOLQs4cbZ4jAdBgNVHQ4EFgQUwldjw4Pb4HV+wxGZ7MSSRh+d
+ pm4wHQYDVR0RBBYwFIIJKi5jaGVmLmlvggdjaGVmLmlvMA4GA1UdDwEB/wQEAwIF
+ oDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwawYDVR0fBGQwYjAvoC2g
+ K4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nMy5jcmwwL6At
+ oCuGKWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zc2NhLXNoYTItZzMuY3JsMEIG
+ A1UdIAQ7MDkwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3
+ LmRpZ2ljZXJ0LmNvbS9DUFMwfAYIKwYBBQUHAQEEcDBuMCQGCCsGAQUFBzABhhho
+ dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jYWNl
+ cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJTZWN1cmVTZXJ2ZXJDQS5jcnQw
+ DAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAvcTWenNuvvrhX2omm8LQ
+ zWOuu8jqpoflACwD4lOSZ4TgOe4pQGCjXq8aRBD5k+goqQrPVf9lHnelUHFQac0Q
+ 5WT4YUmisUbF0S4uY5OGQymM52MvUWG4ODL4gaWhFvN+HAXrDPP/9iitsjV0QOnl
+ CDq7Q4/XYRYW3opu5nLLbfW6v4QvF5yzZagEACGs7Vt32p6l391UcU8f6wiB3uMD
+ eioCvjpv/+2YOUNlDPCM3uBubjUhHOwO817wBxXkzdk1OSRe4jzcw/uX6wL7birt
+ fbaSkpilvVX529pSzB2Lvi9xWOoGMM578dpQ0h3PwhmmvKhhCWP+pI05k3oSkYCP
+ ng==
+ -----END CERTIFICATE-----
+
+END_OF_JCLOUDS_FILE
+cat > /etc/chef/client.rb <<-'END_OF_JCLOUDS_FILE'
+ require 'rubygems'
+ require 'ohai'
+ o = Ohai::System.new
+ o.all_plugins
+ node_name "foo-" + o[:ipaddress]
+ log_level :info
+ log_location STDOUT
+ validation_client_name "chef-validator"
+ chef_server_url "http://localhost:4000"
+ ssl_ca_file "/etc/chef/chef-server.crt"
+ ssl_ca_path "/etc/chef"
+ ssl_verify_mode :verify_peer
+ verify_api_cert true
+END_OF_JCLOUDS_FILE
+cat > /etc/chef/validation.pem <<-'END_OF_JCLOUDS_FILE'
+ -----BEGIN PRIVATE KEY-----
+ LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVB
+ eWIyWkpKcUdtMEtLUis4bmZRSk5zU2QrRjl0WE5NVjdDZk9jVzZqc3FzOEVaZ2lW
+ ClIwOWhEMUlZT2o0WXFNMHFKT05sZ3lnNHhSV2V3ZFNHN1FUUGoxbEpwVkFpZGE5
+ c1h5MitrenlhZ1pBMUFtME8KWmNicWI1aG9lSURnY1grZURhNzlzMHUwRG9tamNm
+ TzlFS2h2SExCeit6TSszUXFQUmtQVjhuWVRiZnMrSGpWegp6T1U2RDFCMFhSMytJ
+ UFpabDJBbldzMmQwcWhuU3RIY0RVdm5SVlEwUDQ4Mll3TjlWZ2NlT1p0cFB6MERD
+ S0VKCjVUeDVTVHViOGswL3p0L1ZBTUhRYWZMU3VRTUxkMnM0Wkx1T1pwdE4vL3VB
+ c1RteGlyZXFkMzd6KzhaVGRCYkoKOExFcEoraUNYdVNmbTVhVWg3aXc2b3h2VG9Z
+ MkFMNTMraksyVVFJREFRQUJBb0lCQVFEQTg4QjNpL3hXbjB2WApCVnhGYW1DWW9l
+ Y3VOakd3WFhrU3laZXc2MTZBK0VPQ3U0N2JoNGFUdXJkRmJZTDBZRmFBdGFXdnps
+ YU4yZUhnCkRiK0hEdVRlZkUyOStXa2NHazZTc2hQbWl6NVQwWE9DQUlDV3c2d1NW
+ RGtIbUd3UzRqWnZiQUZtN1c4bndHazkKWWh4Z3hGaVJuZ3N3SlpGb3BPTG9GNVdY
+ czJ0ZDhndUlZTnNsTXBvN3R1NTBpRm5CSHdLTzJac1BBazh0OW5uUwp4bERhdkty
+ dXltRW1xSENyMytkdGlvNWVhZW5KY3AzZmpvWEJRT0tVazNpcElJMjlYUkI4TnFl
+ Q1ZWLzdLeHdxCmNrcU9CRWJSd0JjbGNreUliRCtSaUFnS3ZPZWxPUmpFaUU5UjQy
+ dnVxdnhSQTZrOWtkOW83dXRsWDBBVXRwRW4KM2daYzZMZXBBb0dCQVA5YWVsNVk3
+ NStzSzJKSlVOT09oTzhhZTQ1Y2RzaWxwMnlJMFgrVUJhU3VRczIrZHlQcAprcEVI
+ QXhkNHBtbVN2bi84YzlUbEVaaHIrcVliQUJYVlBsRG5jeHBJdXcyQWpiazdzL1M0
+ WGFTS3NScXBYTDU3CnpqL1FPcUxrUms4K09WVjlxNmxNZVFOcUx0RWoxdTZKUHZp
+ WDcwUm8rRlF0UnR0Tk9ZYmZkUC9mQW9HQkFNcEEKWGpSNXdvVjVzVWIrUkVnOXZF
+ dVlvOFJTeU9hcnhxS0ZDSVhWVU5zTE94KzIyK0FLNCtDUXBidWVXTjdqb3RybApZ
+ RDZ1VDZzdldpM0FBQzdraVkwVUkvZmpWUFJDVWk4dFZvUVVFMFRhVTVWTElUYVlP
+ QitXL2JCYURFNE05NTYwCjFOdURXTzkwYmFBNWRmVTQ0aXV6dmEwMnJHSlhLOStu
+ UzNvOG5rL1BBb0dCQUxPTDZkam5EZTRtd0FhRzZKY28KY2Q0eHI4amt5UHpDUlp1
+ eUJDU0Jid3BoSVVYTGM3aERwclBreTA2NG5jSkQxVURtd0lka1hkL2ZwTWtnMlFt
+ QQovQ1VrNkxFRmpNaXNxSG9qT2FDTDlnUVpKUGhMTjVRVU4yeDFQSldHanMxdlFo
+ OFRreDBpVVVDT2E4YlFQWE5SCiszNE9Uc1c2VFVuYTRDU1pBeWNMZmhmZkFvR0JB
+ SWdnVnNlZkJDdnVRa0YwTmVVaG1EQ1JaZmhuZDh5NTVSSFIKMUhDdnFLSWxwdity
+ aGNYL3pteUJMdXRlb3BZeVJKUnNPaUUyRlcwMGk4K3JJUFJ1NFozUTVueWJ4N3cz
+ UHpWOQpvSE41UjViYUU5T3lJNEtwWld6dHBZWWl0WkY2N05jbkF2VlVMSEhPdlZK
+ UUduS1lmTEhKWW1ySkY3R0Exb2pNCkF1TWRGYmpGQW9HQVB4VWh4d0Z5OGdhcUJh
+ aEtVRVpuNEY4MUhGUDVpaEdoa1Q0UUw2QUZQTzJlK0poSUdqdVIKMjcrODVoY0Zx
+ UStISFZ0RnNtODFiL2ErUjdQNFV1Q1JnYzhlQ2p4UU1vSjFYbDRuN1ZialBiSE1u
+ SU4wUnl2ZApPNFpwV0RXWW5DTzAyMUpUT1VVT0o0Si95MDQxNkJ2a3cwejU5eTdz
+ Tlg3d0RCQkhIYksvWENjPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
+ -----END PRIVATE KEY-----
+
+END_OF_JCLOUDS_FILE
+cat > /etc/chef/first-boot.json <<-'END_OF_JCLOUDS_FILE'
+ {"tomcat6":{"ssl_port":8433},"run_list":["recipe[apache2]","role[webserver]"]}
+END_OF_JCLOUDS_FILE
+chef-client -j /etc/chef/first-boot.json
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/test/resources/bootstrap.sh
----------------------------------------------------------------------
diff --git a/apis/chef/src/test/resources/bootstrap.sh b/apis/chef/src/test/resources/bootstrap.sh
index 0eb402e..c5381f4 100755
--- a/apis/chef/src/test/resources/bootstrap.sh
+++ b/apis/chef/src/test/resources/bootstrap.sh
@@ -1,5 +1,5 @@
mkdir -p /etc/chef
-cat >> /etc/chef/client.rb <<-'END_OF_JCLOUDS_FILE'
+cat > /etc/chef/client.rb <<-'END_OF_JCLOUDS_FILE'
require 'rubygems'
require 'ohai'
o = Ohai::System.new
@@ -10,7 +10,7 @@ cat >> /etc/chef/client.rb <<-'END_OF_JCLOUDS_FILE'
validation_client_name "chef-validator"
chef_server_url "http://localhost:4000"
END_OF_JCLOUDS_FILE
-cat >> /etc/chef/validation.pem <<-'END_OF_JCLOUDS_FILE'
+cat > /etc/chef/validation.pem <<-'END_OF_JCLOUDS_FILE'
-----BEGIN PRIVATE KEY-----
LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVB
eWIyWkpKcUdtMEtLUis4bmZRSk5zU2QrRjl0WE5NVjdDZk9jVzZqc3FzOEVaZ2lW
@@ -50,7 +50,7 @@ cat >> /etc/chef/validation.pem <<-'END_OF_JCLOUDS_FILE'
-----END PRIVATE KEY-----
END_OF_JCLOUDS_FILE
-cat >> /etc/chef/first-boot.json <<-'END_OF_JCLOUDS_FILE'
+cat > /etc/chef/first-boot.json <<-'END_OF_JCLOUDS_FILE'
{"tomcat6":{"ssl_port":8433},"run_list":["recipe[apache2]","role[webserver]"]}
END_OF_JCLOUDS_FILE
chef-client -j /etc/chef/first-boot.json
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/apis/chef/src/test/resources/chef.crt
----------------------------------------------------------------------
diff --git a/apis/chef/src/test/resources/chef.crt b/apis/chef/src/test/resources/chef.crt
new file mode 100644
index 0000000..d2cfb31
--- /dev/null
+++ b/apis/chef/src/test/resources/chef.crt
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----
+MIIFDTCCA/WgAwIBAgIQBZ8R1sZP2Lbc8x554UUQ2DANBgkqhkiG9w0BAQsFADBN
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E
+aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTQxMTEwMDAwMDAwWhcN
+MTcxMTE0MTIwMDAwWjBlMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
+bjEQMA4GA1UEBxMHU2VhdHRsZTEbMBkGA1UEChMSQ2hlZiBTb2Z0d2FyZSwgSW5j
+MRIwEAYDVQQDDAkqLmNoZWYuaW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQC3xCIczkV10O5jTDpbd4YlPLC6kfnVoOkno2N/OOlcLQu3ulj/Lj1j4r6e
+2XthJLcFgTO+y+1/IKnnpLKDfkx1YngWEBXEBP+MrrpDUKKs053s45/bI9QBPISA
+tXgnYxMH9Glo6FWWd13TUq++OKGw1p1wazH64XK4MAf5y/lkmWXIWumNuO35ZqtB
+ME3wJISwVHzHB2CQjlDklt+Mb0APEiIFIZflgu9JNBYzLdvUtxiz15FUZQI7SsYL
+TfXOD1KBNMWqN8snG2e5gRAzB2D161DFvAZt8OiYUe+3QurNlTYVzeHv1ok6UqgM
+ZcLzg8m801rRip0D7FCGvMCU/ktdAgMBAAGjggHPMIIByzAfBgNVHSMEGDAWgBQP
+gGEcgjFh1S8o541GOLQs4cbZ4jAdBgNVHQ4EFgQUwldjw4Pb4HV+wxGZ7MSSRh+d
+pm4wHQYDVR0RBBYwFIIJKi5jaGVmLmlvggdjaGVmLmlvMA4GA1UdDwEB/wQEAwIF
+oDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwawYDVR0fBGQwYjAvoC2g
+K4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nMy5jcmwwL6At
+oCuGKWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zc2NhLXNoYTItZzMuY3JsMEIG
+A1UdIAQ7MDkwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3
+LmRpZ2ljZXJ0LmNvbS9DUFMwfAYIKwYBBQUHAQEEcDBuMCQGCCsGAQUFBzABhhho
+dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jYWNl
+cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJTZWN1cmVTZXJ2ZXJDQS5jcnQw
+DAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAvcTWenNuvvrhX2omm8LQ
+zWOuu8jqpoflACwD4lOSZ4TgOe4pQGCjXq8aRBD5k+goqQrPVf9lHnelUHFQac0Q
+5WT4YUmisUbF0S4uY5OGQymM52MvUWG4ODL4gaWhFvN+HAXrDPP/9iitsjV0QOnl
+CDq7Q4/XYRYW3opu5nLLbfW6v4QvF5yzZagEACGs7Vt32p6l391UcU8f6wiB3uMD
+eioCvjpv/+2YOUNlDPCM3uBubjUhHOwO817wBxXkzdk1OSRe4jzcw/uX6wL7birt
+fbaSkpilvVX529pSzB2Lvi9xWOoGMM578dpQ0h3PwhmmvKhhCWP+pI05k3oSkYCP
+ng==
+-----END CERTIFICATE-----
http://git-wip-us.apache.org/repos/asf/jclouds/blob/6b350fb6/project/pom.xml
----------------------------------------------------------------------
diff --git a/project/pom.xml b/project/pom.xml
index 0e5eedc..9dfbf74 100644
--- a/project/pom.xml
+++ b/project/pom.xml
@@ -423,6 +423,7 @@
<exclude>**/src/test/resources/**/*.txt</exclude>
<exclude>**/src/test/resources/**/*.gz</exclude>
<exclude>**/src/test/resources/**/*.xml</exclude>
+ <exclude>**/src/test/resources/**/*.crt</exclude>
<!-- META-INF/services files -->
<exclude>**/services/*LoggingModule</exclude>