mirror of https://github.com/apache/jclouds.git
JCLOUDS-717: Join Enterprise and OpenSource Chef
This commit is contained in:
parent
c9306c1fc8
commit
9df30c5a09
|
@ -19,7 +19,7 @@
|
||||||
#^{:author "Adrian Cole"
|
#^{:author "Adrian Cole"
|
||||||
:doc "A clojure binding to the jclouds chef interface.
|
:doc "A clojure binding to the jclouds chef interface.
|
||||||
|
|
||||||
Here's a quick example of how to manipulate a databag on the Opscode Platform,
|
Here's a quick example of how to manipulate a databag on the Chef Platform,
|
||||||
which is basically Chef Server as a Service.
|
which is basically Chef Server as a Service.
|
||||||
|
|
||||||
(use 'org.jclouds.chef)
|
(use 'org.jclouds.chef)
|
||||||
|
@ -28,7 +28,7 @@ which is basically Chef Server as a Service.
|
||||||
;; load the rsa key from ~/.chef/CLIENT_NAME.pem
|
;; load the rsa key from ~/.chef/CLIENT_NAME.pem
|
||||||
(def credential (load-pem client))
|
(def credential (load-pem client))
|
||||||
|
|
||||||
;; create a connection to the opscode platform
|
;; create a connection to the chef platform
|
||||||
(def chef (chef-service \"chef\" client credential :chef.endpoint \"https://api.opscode.com/organizations/YOUR_ORG\"))
|
(def chef (chef-service \"chef\" client credential :chef.endpoint \"https://api.opscode.com/organizations/YOUR_ORG\"))
|
||||||
|
|
||||||
(with-chef-service [chef]
|
(with-chef-service [chef]
|
||||||
|
|
|
@ -55,10 +55,11 @@ import org.jclouds.chef.domain.Role;
|
||||||
import org.jclouds.chef.domain.Sandbox;
|
import org.jclouds.chef.domain.Sandbox;
|
||||||
import org.jclouds.chef.domain.SearchResult;
|
import org.jclouds.chef.domain.SearchResult;
|
||||||
import org.jclouds.chef.domain.UploadSandbox;
|
import org.jclouds.chef.domain.UploadSandbox;
|
||||||
|
import org.jclouds.chef.features.OrganizationApi;
|
||||||
import org.jclouds.chef.filters.SignedHeaderAuth;
|
import org.jclouds.chef.filters.SignedHeaderAuth;
|
||||||
|
import org.jclouds.chef.functions.ParseCookbookDefinitionFromJson;
|
||||||
import org.jclouds.chef.functions.ParseCookbookDefinitionListFromJson;
|
import org.jclouds.chef.functions.ParseCookbookDefinitionListFromJson;
|
||||||
import org.jclouds.chef.functions.ParseCookbookNamesFromJson;
|
import org.jclouds.chef.functions.ParseCookbookNamesFromJson;
|
||||||
import org.jclouds.chef.functions.ParseCookbookDefinitionFromJson;
|
|
||||||
import org.jclouds.chef.functions.ParseCookbookVersionsFromJson;
|
import org.jclouds.chef.functions.ParseCookbookVersionsFromJson;
|
||||||
import org.jclouds.chef.functions.ParseKeySetFromJson;
|
import org.jclouds.chef.functions.ParseKeySetFromJson;
|
||||||
import org.jclouds.chef.functions.ParseSearchClientsFromJson;
|
import org.jclouds.chef.functions.ParseSearchClientsFromJson;
|
||||||
|
@ -71,6 +72,7 @@ import org.jclouds.chef.options.CreateClientOptions;
|
||||||
import org.jclouds.chef.options.SearchOptions;
|
import org.jclouds.chef.options.SearchOptions;
|
||||||
import org.jclouds.io.Payload;
|
import org.jclouds.io.Payload;
|
||||||
import org.jclouds.rest.annotations.BinderParam;
|
import org.jclouds.rest.annotations.BinderParam;
|
||||||
|
import org.jclouds.rest.annotations.Delegate;
|
||||||
import org.jclouds.rest.annotations.EndpointParam;
|
import org.jclouds.rest.annotations.EndpointParam;
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
import org.jclouds.rest.annotations.Headers;
|
import org.jclouds.rest.annotations.Headers;
|
||||||
|
@ -85,6 +87,7 @@ import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
import org.jclouds.rest.annotations.WrapWith;
|
import org.jclouds.rest.annotations.WrapWith;
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
|
import com.google.common.base.Optional;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -100,6 +103,12 @@ public interface ChefApi extends Closeable {
|
||||||
*/
|
*/
|
||||||
@Provides
|
@Provides
|
||||||
ChefService chefService();
|
ChefService chefService();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides access to the organization, user and group management endpoints.
|
||||||
|
*/
|
||||||
|
@Delegate
|
||||||
|
Optional<OrganizationApi> organizationApi();
|
||||||
|
|
||||||
// Clients
|
// Clients
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of {@link ApiMetadata} for OpsCode's Chef api.
|
* Implementation of {@link ApiMetadata} for Chef.
|
||||||
*/
|
*/
|
||||||
@AutoService(ApiMetadata.class)
|
@AutoService(ApiMetadata.class)
|
||||||
public class ChefApiMetadata extends BaseHttpApiMetadata<ChefApi> {
|
public class ChefApiMetadata extends BaseHttpApiMetadata<ChefApi> {
|
||||||
|
@ -48,7 +48,7 @@ public class ChefApiMetadata extends BaseHttpApiMetadata<ChefApi> {
|
||||||
/**
|
/**
|
||||||
* The default Chef Server API version to use.
|
* The default Chef Server API version to use.
|
||||||
*/
|
*/
|
||||||
public static final String DEFAULT_API_VERSION = "0.10.8";
|
public static final String DEFAULT_API_VERSION = "12.0.2";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Builder toBuilder() {
|
public Builder toBuilder() {
|
||||||
|
@ -86,11 +86,11 @@ public class ChefApiMetadata extends BaseHttpApiMetadata<ChefApi> {
|
||||||
|
|
||||||
protected Builder() {
|
protected Builder() {
|
||||||
id("chef")
|
id("chef")
|
||||||
.name("OpsCode Chef Api")
|
.name("Chef Api")
|
||||||
.identityName("User")
|
.identityName("User")
|
||||||
.credentialName("Certificate")
|
.credentialName("Certificate")
|
||||||
.version(DEFAULT_API_VERSION)
|
.version(DEFAULT_API_VERSION)
|
||||||
.documentation(URI.create("http://wiki.opscode.com/display/chef/Server+API"))
|
.documentation(URI.create("https://docs.chef.io/api_chef_server.html"))
|
||||||
.defaultEndpoint("http://localhost:4000")
|
.defaultEndpoint("http://localhost:4000")
|
||||||
.defaultProperties(ChefApiMetadata.defaultProperties())
|
.defaultProperties(ChefApiMetadata.defaultProperties())
|
||||||
.defaultModules(
|
.defaultModules(
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.enterprisechef.binders;
|
package org.jclouds.chef.binders;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
@ -24,7 +24,7 @@ import java.util.Set;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.enterprisechef.domain.Group;
|
import org.jclouds.chef.domain.Group;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.json.Json;
|
import org.jclouds.json.Json;
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
|
@ -14,13 +14,13 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.enterprisechef.binders;
|
package org.jclouds.chef.binders;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.enterprisechef.domain.Group;
|
import org.jclouds.chef.domain.Group;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
|
|
@ -1,204 +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.config;
|
|
||||||
|
|
||||||
import static com.google.common.base.Suppliers.compose;
|
|
||||||
import static com.google.common.base.Suppliers.memoizeWithExpiration;
|
|
||||||
import static com.google.common.base.Throwables.propagate;
|
|
||||||
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
|
||||||
import static org.jclouds.chef.config.ChefProperties.CHEF_VALIDATOR_CREDENTIAL;
|
|
||||||
import static org.jclouds.chef.config.ChefProperties.CHEF_VALIDATOR_NAME;
|
|
||||||
import static org.jclouds.crypto.Pems.privateKeySpec;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.PrivateKey;
|
|
||||||
import java.security.spec.InvalidKeySpecException;
|
|
||||||
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.handlers.ChefApiErrorRetryHandler;
|
|
||||||
import org.jclouds.chef.handlers.ChefErrorHandler;
|
|
||||||
import org.jclouds.crypto.Crypto;
|
|
||||||
import org.jclouds.crypto.Pems;
|
|
||||||
import org.jclouds.date.DateService;
|
|
||||||
import org.jclouds.date.TimeStamp;
|
|
||||||
import org.jclouds.domain.Credentials;
|
|
||||||
import org.jclouds.http.HttpErrorHandler;
|
|
||||||
import org.jclouds.http.HttpRetryHandler;
|
|
||||||
import org.jclouds.http.annotation.ClientError;
|
|
||||||
import org.jclouds.http.annotation.Redirection;
|
|
||||||
import org.jclouds.http.annotation.ServerError;
|
|
||||||
import org.jclouds.rest.ConfiguresHttpApi;
|
|
||||||
import org.jclouds.rest.config.HttpApiModule;
|
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import com.google.common.base.Charsets;
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.base.Optional;
|
|
||||||
import com.google.common.base.Supplier;
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
|
||||||
import com.google.common.cache.CacheLoader;
|
|
||||||
import com.google.common.cache.LoadingCache;
|
|
||||||
import com.google.common.io.ByteSource;
|
|
||||||
import com.google.inject.ConfigurationException;
|
|
||||||
import com.google.inject.Injector;
|
|
||||||
import com.google.inject.Key;
|
|
||||||
import com.google.inject.Provides;
|
|
||||||
import com.google.inject.name.Names;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures the Chef connection.
|
|
||||||
*/
|
|
||||||
@ConfiguresHttpApi
|
|
||||||
public abstract class BaseChefHttpApiModule<S> extends HttpApiModule<S> {
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@TimeStamp
|
|
||||||
protected final String guiceProvideTimeStamp(@TimeStamp Supplier<String> cache) {
|
|
||||||
return provideTimeStamp(cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
|
|
||||||
return cache.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* borrowing concurrency code to ensure that caching takes place properly
|
|
||||||
*/
|
|
||||||
@Provides
|
|
||||||
@TimeStamp
|
|
||||||
final Supplier<String> provideTimeStampCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds, final DateService dateService) {
|
|
||||||
return memoizeWithExpiration(new Supplier<String>() {
|
|
||||||
@Override
|
|
||||||
public String get() {
|
|
||||||
return dateService.iso8601SecondsDateFormat();
|
|
||||||
}
|
|
||||||
}, seconds, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: potentially change this
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
public final Supplier<PrivateKey> supplyKey(final LoadingCache<Credentials, PrivateKey> keyCache,
|
|
||||||
@org.jclouds.location.Provider final Supplier<Credentials> creds) {
|
|
||||||
return compose(new Function<Credentials, PrivateKey>() {
|
|
||||||
@Override
|
|
||||||
public PrivateKey apply(Credentials in) {
|
|
||||||
return keyCache.getUnchecked(in);
|
|
||||||
}
|
|
||||||
}, creds);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
final LoadingCache<Credentials, PrivateKey> privateKeyCache(PrivateKeyForCredentials loader) {
|
|
||||||
// throw out the private key related to old credentials
|
|
||||||
return CacheBuilder.newBuilder().maximumSize(2).build(loader);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* it is relatively expensive to extract a private key from a PEM. cache the
|
|
||||||
* relationship between current credentials so that the private key is only
|
|
||||||
* recalculated once.
|
|
||||||
*/
|
|
||||||
@VisibleForTesting
|
|
||||||
@Singleton
|
|
||||||
private static class PrivateKeyForCredentials extends CacheLoader<Credentials, PrivateKey> {
|
|
||||||
private final Crypto crypto;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private PrivateKeyForCredentials(Crypto crypto) {
|
|
||||||
this.crypto = crypto;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PrivateKey load(Credentials in) {
|
|
||||||
try {
|
|
||||||
return crypto.rsaKeyFactory().generatePrivate(
|
|
||||||
privateKeySpec(ByteSource.wrap(in.credential.getBytes(Charsets.UTF_8))));
|
|
||||||
} catch (InvalidKeySpecException e) {
|
|
||||||
throw propagate(e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw propagate(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Validator
|
|
||||||
public final Optional<String> provideValidatorName(Injector injector) {
|
|
||||||
// Named properties can not be injected as optional here, so let's use the
|
|
||||||
// injector to bypass it
|
|
||||||
Key<String> key = Key.get(String.class, Names.named(CHEF_VALIDATOR_NAME));
|
|
||||||
try {
|
|
||||||
return Optional.<String> of(injector.getInstance(key));
|
|
||||||
} catch (ConfigurationException ex) {
|
|
||||||
return Optional.<String> absent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Validator
|
|
||||||
public final Optional<PrivateKey> provideValidatorCredential(Crypto crypto, Injector injector)
|
|
||||||
throws InvalidKeySpecException, IOException {
|
|
||||||
// Named properties can not be injected as optional here, so let's use the
|
|
||||||
// injector to bypass it
|
|
||||||
Key<String> key = Key.get(String.class, Names.named(CHEF_VALIDATOR_CREDENTIAL));
|
|
||||||
try {
|
|
||||||
String validatorCredential = injector.getInstance(key);
|
|
||||||
PrivateKey validatorKey = crypto.rsaKeyFactory().generatePrivate(
|
|
||||||
Pems.privateKeySpec(ByteSource.wrap(validatorCredential.getBytes(Charsets.UTF_8))));
|
|
||||||
return Optional.<PrivateKey> of(validatorKey);
|
|
||||||
} catch (ConfigurationException ex) {
|
|
||||||
return Optional.<PrivateKey> absent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
final CacheLoader<String, BootstrapConfig> bootstrapConfigForGroup(BootstrapConfigForGroup bootstrapConfigForGroup) {
|
|
||||||
return CacheLoader.from(bootstrapConfigForGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
final CacheLoader<String, Client> groupToClient(ClientForGroup clientForGroup) {
|
|
||||||
return CacheLoader.from(clientForGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void bindErrorHandlers() {
|
|
||||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ChefErrorHandler.class);
|
|
||||||
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ChefErrorHandler.class);
|
|
||||||
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ChefErrorHandler.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void bindRetryHandlers() {
|
|
||||||
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(ChefApiErrorRetryHandler.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -16,13 +16,191 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.chef.config;
|
package org.jclouds.chef.config;
|
||||||
|
|
||||||
|
import static com.google.common.base.Suppliers.compose;
|
||||||
|
import static com.google.common.base.Suppliers.memoizeWithExpiration;
|
||||||
|
import static com.google.common.base.Throwables.propagate;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
||||||
|
import static org.jclouds.chef.config.ChefProperties.CHEF_VALIDATOR_CREDENTIAL;
|
||||||
|
import static org.jclouds.chef.config.ChefProperties.CHEF_VALIDATOR_NAME;
|
||||||
|
import static org.jclouds.crypto.Pems.privateKeySpec;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.chef.ChefApi;
|
import org.jclouds.chef.ChefApi;
|
||||||
|
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.handlers.ChefApiErrorRetryHandler;
|
||||||
|
import org.jclouds.chef.handlers.ChefErrorHandler;
|
||||||
|
import org.jclouds.crypto.Crypto;
|
||||||
|
import org.jclouds.crypto.Pems;
|
||||||
|
import org.jclouds.date.DateService;
|
||||||
|
import org.jclouds.date.TimeStamp;
|
||||||
|
import org.jclouds.domain.Credentials;
|
||||||
|
import org.jclouds.http.HttpErrorHandler;
|
||||||
|
import org.jclouds.http.HttpRetryHandler;
|
||||||
|
import org.jclouds.http.annotation.ClientError;
|
||||||
|
import org.jclouds.http.annotation.Redirection;
|
||||||
|
import org.jclouds.http.annotation.ServerError;
|
||||||
import org.jclouds.rest.ConfiguresHttpApi;
|
import org.jclouds.rest.ConfiguresHttpApi;
|
||||||
|
import org.jclouds.rest.config.HttpApiModule;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
|
import com.google.common.cache.LoadingCache;
|
||||||
|
import com.google.common.io.ByteSource;
|
||||||
|
import com.google.inject.ConfigurationException;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Key;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
import com.google.inject.name.Names;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the Chef connection.
|
* Configures the Chef connection.
|
||||||
*/
|
*/
|
||||||
@ConfiguresHttpApi
|
@ConfiguresHttpApi
|
||||||
public class ChefHttpApiModule extends BaseChefHttpApiModule<ChefApi> {
|
public class ChefHttpApiModule extends HttpApiModule<ChefApi> {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@TimeStamp
|
||||||
|
protected final String guiceProvideTimeStamp(@TimeStamp Supplier<String> cache) {
|
||||||
|
return provideTimeStamp(cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
|
||||||
|
return cache.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* borrowing concurrency code to ensure that caching takes place properly
|
||||||
|
*/
|
||||||
|
@Provides
|
||||||
|
@TimeStamp
|
||||||
|
final Supplier<String> provideTimeStampCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
||||||
|
final DateService dateService) {
|
||||||
|
return memoizeWithExpiration(new Supplier<String>() {
|
||||||
|
@Override
|
||||||
|
public String get() {
|
||||||
|
return dateService.iso8601SecondsDateFormat();
|
||||||
|
}
|
||||||
|
}, seconds, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: potentially change this
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
public final Supplier<PrivateKey> supplyKey(final LoadingCache<Credentials, PrivateKey> keyCache,
|
||||||
|
@org.jclouds.location.Provider final Supplier<Credentials> creds) {
|
||||||
|
return compose(new Function<Credentials, PrivateKey>() {
|
||||||
|
@Override
|
||||||
|
public PrivateKey apply(Credentials in) {
|
||||||
|
return keyCache.getUnchecked(in);
|
||||||
|
}
|
||||||
|
}, creds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
final LoadingCache<Credentials, PrivateKey> privateKeyCache(PrivateKeyForCredentials loader) {
|
||||||
|
// throw out the private key related to old credentials
|
||||||
|
return CacheBuilder.newBuilder().maximumSize(2).build(loader);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* it is relatively expensive to extract a private key from a PEM. cache the
|
||||||
|
* relationship between current credentials so that the private key is only
|
||||||
|
* recalculated once.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
@Singleton
|
||||||
|
private static class PrivateKeyForCredentials extends CacheLoader<Credentials, PrivateKey> {
|
||||||
|
private final Crypto crypto;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private PrivateKeyForCredentials(Crypto crypto) {
|
||||||
|
this.crypto = crypto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PrivateKey load(Credentials in) {
|
||||||
|
try {
|
||||||
|
return crypto.rsaKeyFactory().generatePrivate(
|
||||||
|
privateKeySpec(ByteSource.wrap(in.credential.getBytes(Charsets.UTF_8))));
|
||||||
|
} catch (InvalidKeySpecException e) {
|
||||||
|
throw propagate(e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw propagate(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Validator
|
||||||
|
public final Optional<String> provideValidatorName(Injector injector) {
|
||||||
|
// Named properties can not be injected as optional here, so let's use the
|
||||||
|
// injector to bypass it
|
||||||
|
Key<String> key = Key.get(String.class, Names.named(CHEF_VALIDATOR_NAME));
|
||||||
|
try {
|
||||||
|
return Optional.<String> of(injector.getInstance(key));
|
||||||
|
} catch (ConfigurationException ex) {
|
||||||
|
return Optional.<String> absent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Validator
|
||||||
|
public final Optional<PrivateKey> provideValidatorCredential(Crypto crypto, Injector injector)
|
||||||
|
throws InvalidKeySpecException, IOException {
|
||||||
|
// Named properties can not be injected as optional here, so let's use the
|
||||||
|
// injector to bypass it
|
||||||
|
Key<String> key = Key.get(String.class, Names.named(CHEF_VALIDATOR_CREDENTIAL));
|
||||||
|
try {
|
||||||
|
String validatorCredential = injector.getInstance(key);
|
||||||
|
PrivateKey validatorKey = crypto.rsaKeyFactory().generatePrivate(
|
||||||
|
Pems.privateKeySpec(ByteSource.wrap(validatorCredential.getBytes(Charsets.UTF_8))));
|
||||||
|
return Optional.<PrivateKey> of(validatorKey);
|
||||||
|
} catch (ConfigurationException ex) {
|
||||||
|
return Optional.<PrivateKey> absent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
final CacheLoader<String, BootstrapConfig> bootstrapConfigForGroup(BootstrapConfigForGroup bootstrapConfigForGroup) {
|
||||||
|
return CacheLoader.from(bootstrapConfigForGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
final CacheLoader<String, Client> groupToClient(ClientForGroup clientForGroup) {
|
||||||
|
return CacheLoader.from(clientForGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void bindErrorHandlers() {
|
||||||
|
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ChefErrorHandler.class);
|
||||||
|
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ChefErrorHandler.class);
|
||||||
|
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ChefErrorHandler.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void bindRetryHandlers() {
|
||||||
|
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(ChefApiErrorRetryHandler.class);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.enterprisechef.domain;
|
package org.jclouds.chef.domain;
|
||||||
|
|
||||||
import static org.jclouds.chef.util.CollectionUtils.copyOfOrEmpty;
|
import static org.jclouds.chef.util.CollectionUtils.copyOfOrEmpty;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
|
@ -14,7 +14,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.enterprisechef.domain;
|
package org.jclouds.chef.domain;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.enterprisechef;
|
package org.jclouds.chef.features;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -31,18 +31,19 @@ import javax.ws.rs.core.MediaType;
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||||
import org.jclouds.chef.ChefApi;
|
import org.jclouds.chef.ChefApi;
|
||||||
|
import org.jclouds.chef.binders.BindGroupToUpdateRequestJsonPayload;
|
||||||
|
import org.jclouds.chef.binders.GroupName;
|
||||||
|
import org.jclouds.chef.domain.Group;
|
||||||
|
import org.jclouds.chef.domain.User;
|
||||||
import org.jclouds.chef.filters.SignedHeaderAuth;
|
import org.jclouds.chef.filters.SignedHeaderAuth;
|
||||||
import org.jclouds.chef.functions.ParseKeySetFromJson;
|
import org.jclouds.chef.functions.ParseKeySetFromJson;
|
||||||
import org.jclouds.enterprisechef.binders.BindGroupToUpdateRequestJsonPayload;
|
|
||||||
import org.jclouds.enterprisechef.binders.GroupName;
|
|
||||||
import org.jclouds.enterprisechef.domain.Group;
|
|
||||||
import org.jclouds.enterprisechef.domain.User;
|
|
||||||
import org.jclouds.rest.annotations.BinderParam;
|
import org.jclouds.rest.annotations.BinderParam;
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
import org.jclouds.rest.annotations.Headers;
|
import org.jclouds.rest.annotations.Headers;
|
||||||
import org.jclouds.rest.annotations.ParamParser;
|
import org.jclouds.rest.annotations.ParamParser;
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.annotations.ResponseParser;
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
|
import org.jclouds.rest.annotations.SinceApiVersion;
|
||||||
import org.jclouds.rest.annotations.WrapWith;
|
import org.jclouds.rest.annotations.WrapWith;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,7 +52,8 @@ import org.jclouds.rest.annotations.WrapWith;
|
||||||
@RequestFilters(SignedHeaderAuth.class)
|
@RequestFilters(SignedHeaderAuth.class)
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@Headers(keys = "X-Chef-Version", values = "{" + Constants.PROPERTY_API_VERSION + "}")
|
@Headers(keys = "X-Chef-Version", values = "{" + Constants.PROPERTY_API_VERSION + "}")
|
||||||
public interface EnterpriseChefApi extends ChefApi {
|
@SinceApiVersion("12.0.0")
|
||||||
|
public interface OrganizationApi extends ChefApi {
|
||||||
/**
|
/**
|
||||||
* Retrieves an existing user.
|
* Retrieves an existing user.
|
||||||
*
|
*
|
|
@ -63,7 +63,7 @@ import com.google.common.io.ByteSource;
|
||||||
/**
|
/**
|
||||||
* Ported from mixlib-authentication in order to sign Chef requests.
|
* Ported from mixlib-authentication in order to sign Chef requests.
|
||||||
*
|
*
|
||||||
* @see <a href= "http://github.com/opscode/mixlib-authentication" />
|
* @see <a href= "https://github.com/chef/mixlib-authentication" />
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class SignedHeaderAuth implements HttpRequestFilter {
|
public class SignedHeaderAuth implements HttpRequestFilter {
|
||||||
|
|
|
@ -20,7 +20,7 @@ package org.jclouds.chef.options;
|
||||||
* Options for the create client method.
|
* Options for the create client method.
|
||||||
*/
|
*/
|
||||||
public class CreateClientOptions implements Cloneable {
|
public class CreateClientOptions implements Cloneable {
|
||||||
/** Administrator flag. This flag will be ignored in Opscode Hosted Chef. */
|
/** Administrator flag. This flag will be ignored in Chef 12. */
|
||||||
private boolean admin;
|
private boolean admin;
|
||||||
|
|
||||||
public CreateClientOptions() {
|
public CreateClientOptions() {
|
||||||
|
|
|
@ -33,6 +33,7 @@ public abstract class BaseChefApiExpectTest<S> extends BaseRestApiExpectTest<S>
|
||||||
protected SignedHeaderAuth signedHeaderAuth;
|
protected SignedHeaderAuth signedHeaderAuth;
|
||||||
|
|
||||||
public BaseChefApiExpectTest() {
|
public BaseChefApiExpectTest() {
|
||||||
|
provider = "chef";
|
||||||
credential = PRIVATE_KEY;
|
credential = PRIVATE_KEY;
|
||||||
signedHeaderAuth = createInjector(Functions.forMap(ImmutableMap.<HttpRequest, HttpResponse> of()),
|
signedHeaderAuth = createInjector(Functions.forMap(ImmutableMap.<HttpRequest, HttpResponse> of()),
|
||||||
createModule(), setupProperties()).getInstance(SignedHeaderAuth.class);
|
createModule(), setupProperties()).getInstance(SignedHeaderAuth.class);
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertFalse;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.jclouds.ContextBuilder;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@Test(groups = "unit", testName = "ChefApiDelegationTest")
|
||||||
|
public class ChefApiDelegationTest {
|
||||||
|
|
||||||
|
public void testOrganizationApiNotAvailableInOldVersions() throws IOException {
|
||||||
|
ChefApi chef = ContextBuilder.newBuilder(new ChefApiMetadata())
|
||||||
|
.credentials("foo", "bar")
|
||||||
|
.apiVersion("11.0.4")
|
||||||
|
.buildApi(ChefApi.class);
|
||||||
|
|
||||||
|
try {
|
||||||
|
assertFalse(chef.organizationApi().isPresent());
|
||||||
|
} finally {
|
||||||
|
chef.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testOrganizationApiPresentInRecentVersions() throws IOException {
|
||||||
|
ChefApi chef = ContextBuilder.newBuilder(new ChefApiMetadata())
|
||||||
|
.credentials("foo", "bar")
|
||||||
|
.apiVersion("12.0.4")
|
||||||
|
.buildApi(ChefApi.class);
|
||||||
|
|
||||||
|
try {
|
||||||
|
assertTrue(chef.organizationApi().isPresent());
|
||||||
|
} finally {
|
||||||
|
chef.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,9 +42,6 @@ import com.google.inject.Module;
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", testName = "ChefApiExpectTest")
|
@Test(groups = "unit", testName = "ChefApiExpectTest")
|
||||||
public class ChefApiExpectTest extends BaseChefApiExpectTest<ChefApi> {
|
public class ChefApiExpectTest extends BaseChefApiExpectTest<ChefApi> {
|
||||||
public ChefApiExpectTest() {
|
|
||||||
provider = "chef";
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpRequest.Builder<?> getHttpRequestBuilder(String method, String endPoint) {
|
private HttpRequest.Builder<?> getHttpRequestBuilder(String method, String endPoint) {
|
||||||
return HttpRequest.builder() //
|
return HttpRequest.builder() //
|
||||||
|
|
|
@ -16,17 +16,527 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.chef;
|
package org.jclouds.chef;
|
||||||
|
|
||||||
import org.jclouds.chef.internal.BaseChefApiLiveTest;
|
import static com.google.common.collect.Iterables.any;
|
||||||
|
import static com.google.common.collect.Iterables.isEmpty;
|
||||||
|
import static com.google.common.hash.Hashing.md5;
|
||||||
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
|
import static org.jclouds.util.Closeables2.closeQuietly;
|
||||||
|
import static org.jclouds.util.Predicates2.retry;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertFalse;
|
||||||
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
import static org.testng.Assert.fail;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.chef.domain.ChecksumStatus;
|
||||||
|
import org.jclouds.chef.domain.Client;
|
||||||
|
import org.jclouds.chef.domain.CookbookDefinition;
|
||||||
|
import org.jclouds.chef.domain.CookbookVersion;
|
||||||
|
import org.jclouds.chef.domain.DatabagItem;
|
||||||
|
import org.jclouds.chef.domain.Environment;
|
||||||
|
import org.jclouds.chef.domain.Metadata;
|
||||||
|
import org.jclouds.chef.domain.Node;
|
||||||
|
import org.jclouds.chef.domain.Resource;
|
||||||
|
import org.jclouds.chef.domain.Role;
|
||||||
|
import org.jclouds.chef.domain.Sandbox;
|
||||||
|
import org.jclouds.chef.domain.SearchResult;
|
||||||
|
import org.jclouds.chef.domain.UploadSandbox;
|
||||||
|
import org.jclouds.chef.internal.BaseChefLiveTest;
|
||||||
|
import org.jclouds.chef.options.CreateClientOptions;
|
||||||
|
import org.jclouds.chef.options.SearchOptions;
|
||||||
|
import org.jclouds.crypto.Pems;
|
||||||
|
import org.jclouds.io.ByteStreams2;
|
||||||
|
import org.jclouds.io.Payloads;
|
||||||
|
import org.jclouds.io.payloads.FilePayload;
|
||||||
|
import org.jclouds.rest.ResourceNotFoundException;
|
||||||
|
import org.testng.annotations.AfterClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
import com.google.common.base.Predicate;
|
||||||
* Tests behavior of {@code ChefApi} against a Chef Server <= 0.9.8.
|
import com.google.common.collect.ImmutableList;
|
||||||
*/
|
import com.google.common.collect.ImmutableSet;
|
||||||
@Test(groups = { "live" })
|
import com.google.common.hash.Hashing;
|
||||||
public class ChefApiLiveTest extends BaseChefApiLiveTest<ChefApi> {
|
import com.google.common.io.Files;
|
||||||
|
import com.google.common.primitives.Bytes;
|
||||||
|
|
||||||
protected ChefApiLiveTest() {
|
/**
|
||||||
provider = "chef";
|
* Tests behavior of {@code ChefApi}
|
||||||
|
*/
|
||||||
|
@Test(groups = { "live", "integration" })
|
||||||
|
public class ChefApiLiveTest extends BaseChefLiveTest {
|
||||||
|
public static final String PREFIX = "jcloudstest-" + System.getProperty("user.name");
|
||||||
|
public static final String ADMIN_PREFIX = "jcloudstest-adm-" + System.getProperty("user.name");
|
||||||
|
public static final String ENV_NODE = PREFIX + "-env-node";
|
||||||
|
|
||||||
|
// It may take a bit until the search index is populated
|
||||||
|
protected int maxWaitForIndexInMs = 60000;
|
||||||
|
|
||||||
|
// The id of the data bag item used in search tests
|
||||||
|
private String databagitemId;
|
||||||
|
|
||||||
|
public void testCreateNewCookbook() throws Exception {
|
||||||
|
// Define the file you want in the cookbook
|
||||||
|
File file = new File(System.getProperty("user.dir"), "pom.xml");
|
||||||
|
FilePayload content = uploadAndGetFilePayload(file);
|
||||||
|
|
||||||
|
// Create the metadata of the cookbook
|
||||||
|
Metadata metadata = Metadata.builder() //
|
||||||
|
.name(PREFIX) //
|
||||||
|
.version("0.0.0") //
|
||||||
|
.description("Jclouds test uploaded cookbook") //
|
||||||
|
.maintainer("jclouds") //
|
||||||
|
.maintainerEmail("someone@jclouds.org") //
|
||||||
|
.license("Apache 2.0") //
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Create a new cookbook
|
||||||
|
CookbookVersion cookbook = CookbookVersion.builder(PREFIX, "0.0.0") //
|
||||||
|
.metadata(metadata) //
|
||||||
|
.rootFile(Resource.builder().fromPayload(content).build()) //
|
||||||
|
.attribute(Resource.builder().fromPayload(content).name("default.rb").build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// upload the cookbook to the remote server
|
||||||
|
api.updateCookbook(PREFIX, "0.0.0", cookbook);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private FilePayload uploadAndGetFilePayload(File file) throws IOException {
|
||||||
|
FilePayload content = Payloads.newFilePayload(file);
|
||||||
|
content.getContentMetadata().setContentType("application/x-binary");
|
||||||
|
|
||||||
|
// Get an md5 so that you can see if the server already has it or not
|
||||||
|
content.getContentMetadata().setContentMD5(Files.asByteSource(file).hash(Hashing.md5()).asBytes());
|
||||||
|
|
||||||
|
// Note that java collections cannot effectively do equals or hashcodes on
|
||||||
|
// byte arrays, so let's convert to a list of bytes.
|
||||||
|
List<Byte> md5 = Bytes.asList(content.getContentMetadata().getContentMD5());
|
||||||
|
|
||||||
|
// Request an upload site for this file
|
||||||
|
UploadSandbox site = api.createUploadSandboxForChecksums(ImmutableSet.of(md5));
|
||||||
|
assertTrue(site.getChecksums().containsKey(md5), md5 + " not in " + site.getChecksums());
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Upload the file contents, if still not uploaded
|
||||||
|
ChecksumStatus status = site.getChecksums().get(md5);
|
||||||
|
if (status.needsUpload()) {
|
||||||
|
api.uploadContent(status.getUrl(), content);
|
||||||
|
}
|
||||||
|
Sandbox sandbox = api.commitSandbox(site.getSandboxId(), true);
|
||||||
|
assertTrue(sandbox.isCompleted(), "Sandbox should be completed after uploading");
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
api.commitSandbox(site.getSandboxId(), false);
|
||||||
|
fail("Could not upload content");
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListCookbooks() throws Exception {
|
||||||
|
Set<String> cookbookNames = api.listCookbooks();
|
||||||
|
assertFalse(cookbookNames.isEmpty(), "No cookbooks were found");
|
||||||
|
|
||||||
|
for (String cookbookName : cookbookNames) {
|
||||||
|
Set<String> versions = api.listVersionsOfCookbook(cookbookName);
|
||||||
|
assertFalse(versions.isEmpty(), "There are no versions of the cookbook: " + cookbookName);
|
||||||
|
|
||||||
|
for (String version : api.listVersionsOfCookbook(cookbookName)) {
|
||||||
|
CookbookVersion cookbook = api.getCookbook(cookbookName, version);
|
||||||
|
assertNotNull(cookbook, "Could not get cookbook: " + cookbookName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testListCookbooks")
|
||||||
|
public void testListCookbookVersionsWithChefService() throws Exception {
|
||||||
|
Iterable<? extends CookbookVersion> cookbooks = chefService.listCookbookVersions();
|
||||||
|
assertFalse(isEmpty(cookbooks), "No cookbooks were found");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testListCookbookVersionsWithChefService")
|
||||||
|
public void testDownloadCookbooks() throws Exception {
|
||||||
|
Iterable<? extends CookbookVersion> cookbooks = chefService.listCookbookVersions();
|
||||||
|
for (CookbookVersion cookbook : cookbooks) {
|
||||||
|
for (Resource resource : ImmutableList.<Resource> builder().addAll(cookbook.getDefinitions())
|
||||||
|
.addAll(cookbook.getFiles()).addAll(cookbook.getLibraries()).addAll(cookbook.getSuppliers())
|
||||||
|
.addAll(cookbook.getRecipes()).addAll(cookbook.getResources()).addAll(cookbook.getRootFiles())
|
||||||
|
.addAll(cookbook.getTemplates()).addAll(cookbook.getAttributes()).build()) {
|
||||||
|
|
||||||
|
InputStream stream = api.getResourceContents(resource);
|
||||||
|
assertNotNull(stream, "Resource contents are null for resource: " + resource.getName());
|
||||||
|
|
||||||
|
byte[] md5 = ByteStreams2.hashAndClose(stream, md5()).asBytes();
|
||||||
|
assertEquals(md5, resource.getChecksum());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateNewCookbook")
|
||||||
|
public void testUpdateCookbook() throws Exception {
|
||||||
|
CookbookVersion cookbook = api.getCookbook(PREFIX, "0.0.0");
|
||||||
|
assertNotNull(cookbook, "Cookbook not found: " + PREFIX);
|
||||||
|
assertNotNull(api.updateCookbook(PREFIX, "0.0.0", cookbook), "Updated cookbook was null");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = { "testCreateNewCookbook", "testUpdateCookbook" })
|
||||||
|
public void testDeleteCookbook() throws Exception {
|
||||||
|
assertNotNull(api.deleteCookbook(PREFIX, "0.0.0"), "Deleted cookbook was null");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateClient() throws Exception {
|
||||||
|
api.deleteClient(PREFIX);
|
||||||
|
String credential = Pems.pem(api.createClient(PREFIX).getPrivateKey());
|
||||||
|
assertClientCreated(PREFIX, credential);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateAdminClient() throws Exception {
|
||||||
|
api.deleteClient(ADMIN_PREFIX);
|
||||||
|
String credential = Pems.pem(api.createClient(ADMIN_PREFIX, CreateClientOptions.Builder.admin()).getPrivateKey());
|
||||||
|
assertClientCreated(ADMIN_PREFIX, credential);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateClient")
|
||||||
|
public void testGenerateKeyForClient() throws Exception {
|
||||||
|
String credential = Pems.pem(api.generateKeyForClient(PREFIX).getPrivateKey());
|
||||||
|
assertClientCreated(PREFIX, credential);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testListNodes() throws Exception {
|
||||||
|
Set<String> nodes = api.listNodes();
|
||||||
|
assertNotNull(nodes, "No nodes were found");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateRole")
|
||||||
|
public void testCreateNode() throws Exception {
|
||||||
|
api.deleteNode(PREFIX);
|
||||||
|
api.createNode(Node.builder().name(PREFIX).runListElement("role[" + PREFIX + "]").environment("_default").build());
|
||||||
|
Node node = api.getNode(PREFIX);
|
||||||
|
// TODO check recipes
|
||||||
|
assertNotNull(node, "Created node should not be null");
|
||||||
|
Set<String> nodes = api.listNodes();
|
||||||
|
assertTrue(nodes.contains(PREFIX), String.format("node %s not in %s", PREFIX, nodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateNode")
|
||||||
|
public void testUpdateNode() throws Exception {
|
||||||
|
for (String nodename : api.listNodes()) {
|
||||||
|
Node node = api.getNode(nodename);
|
||||||
|
api.updateNode(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testListRoles() throws Exception {
|
||||||
|
Set<String> roles = api.listRoles();
|
||||||
|
assertNotNull(roles, "Role list was null");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateRole() throws Exception {
|
||||||
|
api.deleteRole(PREFIX);
|
||||||
|
api.createRole(Role.builder().name(PREFIX).runListElement("recipe[java]").build());
|
||||||
|
Role role = api.getRole(PREFIX);
|
||||||
|
assertNotNull(role, "Created role should not be null");
|
||||||
|
assertEquals(role.getName(), PREFIX);
|
||||||
|
assertEquals(role.getRunList(), Collections.singleton("recipe[java]"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateRole")
|
||||||
|
public void testUpdateRole() throws Exception {
|
||||||
|
for (String rolename : api.listRoles()) {
|
||||||
|
Role role = api.getRole(rolename);
|
||||||
|
api.updateRole(role);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testListDatabags() throws Exception {
|
||||||
|
Set<String> databags = api.listDatabags();
|
||||||
|
assertNotNull(databags, "Data bag list was null");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateDatabag() throws Exception {
|
||||||
|
api.deleteDatabag(PREFIX);
|
||||||
|
api.createDatabag(PREFIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateDatabagItem")
|
||||||
|
public void testListDatabagItems() throws Exception {
|
||||||
|
Set<String> databagItems = api.listDatabagItems(PREFIX);
|
||||||
|
assertNotNull(databagItems, "Data bag item list was null");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateDatabag")
|
||||||
|
public void testCreateDatabagItem() throws Exception {
|
||||||
|
Properties config = new Properties();
|
||||||
|
config.setProperty("foo", "bar");
|
||||||
|
api.deleteDatabagItem(PREFIX, PREFIX);
|
||||||
|
DatabagItem databagItem = api.createDatabagItem(PREFIX, new DatabagItem("config", json.toJson(config)));
|
||||||
|
databagitemId = databagItem.getId();
|
||||||
|
assertNotNull(databagItem, "Created data bag item should not be null");
|
||||||
|
assertEquals(databagItem.getId(), "config");
|
||||||
|
|
||||||
|
// The databagItem json contains extra keys: (the name and the type if the
|
||||||
|
// item)
|
||||||
|
Properties props = json.fromJson(databagItem.toString(), Properties.class);
|
||||||
|
for (Object key : config.keySet()) {
|
||||||
|
assertTrue(props.containsKey(key));
|
||||||
|
assertEquals(config.get(key), props.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateDatabagItem")
|
||||||
|
public void testUpdateDatabagItem() throws Exception {
|
||||||
|
for (String databagItemId : api.listDatabagItems(PREFIX)) {
|
||||||
|
DatabagItem databagItem = api.getDatabagItem(PREFIX, databagItemId);
|
||||||
|
api.updateDatabagItem(PREFIX, databagItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testSearchDatabagWithOptions")
|
||||||
|
public void testDeleteDatabagItem() throws Exception {
|
||||||
|
for (String databagItemId : api.listDatabagItems(PREFIX)) {
|
||||||
|
DatabagItem databagItem = api.deleteDatabagItem(PREFIX, databagItemId);
|
||||||
|
assertNotNull(databagItem, "Deleted data bag item should not be null");
|
||||||
|
assertEquals(databagItem.getId(), databagItemId, "Deleted data bag item id must match the original id");
|
||||||
|
assertNull(api.getDatabagItem(PREFIX, databagItemId), "Data bag item should not exist");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testListSearchIndexes() throws Exception {
|
||||||
|
Set<String> indexes = api.listSearchIndexes();
|
||||||
|
assertNotNull(indexes, "The index list should not be null");
|
||||||
|
assertTrue(indexes.contains("node"));
|
||||||
|
assertTrue(indexes.contains("client"));
|
||||||
|
assertTrue(indexes.contains("role"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchNodes() throws Exception {
|
||||||
|
SearchResult<? extends Node> results = api.searchNodes();
|
||||||
|
assertNotNull(results, "Node result list should not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = { "testListSearchIndexes", "testCreateNode" })
|
||||||
|
public void testSearchNodesWithOptions() throws Exception {
|
||||||
|
Predicate<SearchOptions> waitForIndex = retry(new Predicate<SearchOptions>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(SearchOptions input) {
|
||||||
|
SearchResult<? extends Node> results = api.searchNodes(input);
|
||||||
|
assertNotNull(results);
|
||||||
|
if (results.size() > 0) {
|
||||||
|
assertEquals(results.size(), 1);
|
||||||
|
assertEquals(results.iterator().next().getName(), PREFIX);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// The index may still not be populated
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, maxWaitForIndexInMs, 5000L, MILLISECONDS);
|
||||||
|
|
||||||
|
SearchOptions options = SearchOptions.Builder.query("name:" + PREFIX);
|
||||||
|
assertTrue(waitForIndex.apply(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchClients() throws Exception {
|
||||||
|
SearchResult<? extends Client> results = api.searchClients();
|
||||||
|
assertNotNull(results, "Client result list should not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = { "testListSearchIndexes", "testCreateClient" })
|
||||||
|
public void testSearchClientsWithOptions() throws Exception {
|
||||||
|
Predicate<SearchOptions> waitForIndex = retry(new Predicate<SearchOptions>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(SearchOptions input) {
|
||||||
|
SearchResult<? extends Client> results = api.searchClients(input);
|
||||||
|
assertNotNull(results);
|
||||||
|
if (results.size() > 0) {
|
||||||
|
assertEquals(results.size(), 1);
|
||||||
|
assertEquals(results.iterator().next().getName(), PREFIX);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// The index may still not be populated
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, maxWaitForIndexInMs, 5000L, MILLISECONDS);
|
||||||
|
|
||||||
|
SearchOptions options = SearchOptions.Builder.query("name:" + PREFIX);
|
||||||
|
assertTrue(waitForIndex.apply(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchRoles() throws Exception {
|
||||||
|
SearchResult<? extends Role> results = api.searchRoles();
|
||||||
|
assertNotNull(results, "Role result list should not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = { "testListSearchIndexes", "testCreateRole" })
|
||||||
|
public void testSearchRolesWithOptions() throws Exception {
|
||||||
|
Predicate<SearchOptions> waitForIndex = retry(new Predicate<SearchOptions>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(SearchOptions input) {
|
||||||
|
SearchResult<? extends Role> results = api.searchRoles(input);
|
||||||
|
assertNotNull(results);
|
||||||
|
if (results.size() > 0) {
|
||||||
|
assertEquals(results.size(), 1);
|
||||||
|
assertEquals(results.iterator().next().getName(), PREFIX);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// The index may still not be populated
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, maxWaitForIndexInMs, 5000L, MILLISECONDS);
|
||||||
|
|
||||||
|
SearchOptions options = SearchOptions.Builder.query("name:" + PREFIX);
|
||||||
|
assertTrue(waitForIndex.apply(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = { "testListSearchIndexes", "testCreateDatabagItem" })
|
||||||
|
public void testSearchDatabag() throws Exception {
|
||||||
|
SearchResult<? extends DatabagItem> results = api.searchDatabagItems(PREFIX);
|
||||||
|
assertNotNull(results, "Data bag item result list should not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = { "testListSearchIndexes", "testCreateDatabagItem" })
|
||||||
|
public void testSearchDatabagWithOptions() throws Exception {
|
||||||
|
Predicate<SearchOptions> waitForIndex = retry(new Predicate<SearchOptions>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(SearchOptions input) {
|
||||||
|
SearchResult<? extends DatabagItem> results = api.searchDatabagItems(PREFIX, input);
|
||||||
|
assertNotNull(results);
|
||||||
|
if (results.size() > 0) {
|
||||||
|
assertEquals(results.size(), 1);
|
||||||
|
assertEquals(results.iterator().next().getId(), databagitemId);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// The index may still not be populated
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, maxWaitForIndexInMs, 5000L, MILLISECONDS);
|
||||||
|
|
||||||
|
SearchOptions options = SearchOptions.Builder.query("id:" + databagitemId);
|
||||||
|
assertTrue(waitForIndex.apply(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = ResourceNotFoundException.class, dependsOnMethods = "testListSearchIndexes")
|
||||||
|
public void testSearchDatabagNotFound() throws Exception {
|
||||||
|
SearchResult<? extends DatabagItem> results = api.searchDatabagItems("whoopie");
|
||||||
|
assertNotNull(results, "Data bag item result list should not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateEnvironment() {
|
||||||
|
api.deleteEnvironment(PREFIX);
|
||||||
|
api.createEnvironment(Environment.builder().name(PREFIX).description(PREFIX).build());
|
||||||
|
Environment env = api.getEnvironment(PREFIX);
|
||||||
|
assertNotNull(env, "Created environment should not be null");
|
||||||
|
assertEquals(env.getName(), PREFIX);
|
||||||
|
assertEquals(env.getDescription(), PREFIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateEnvironment")
|
||||||
|
public void testListEnvironment() {
|
||||||
|
Set<String> envList = api.listEnvironments();
|
||||||
|
assertNotNull(envList, "Environment list was null");
|
||||||
|
assertTrue(envList.contains(PREFIX));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateEnvironment")
|
||||||
|
public void testSearchEnvironments() throws Exception {
|
||||||
|
SearchResult<? extends Environment> results = api.searchEnvironments();
|
||||||
|
assertNotNull(results, "Environment result list was null");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = { "testListSearchIndexes", "testCreateEnvironment" })
|
||||||
|
public void testSearchEnvironmentsWithOptions() throws Exception {
|
||||||
|
Predicate<SearchOptions> waitForIndex = retry(new Predicate<SearchOptions>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(SearchOptions input) {
|
||||||
|
SearchResult<? extends Environment> results = api.searchEnvironments(input);
|
||||||
|
assertNotNull(results);
|
||||||
|
if (results.size() > 0) {
|
||||||
|
assertEquals(results.size(), 1);
|
||||||
|
assertEquals(results.iterator().next().getName(), PREFIX);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// The index may still not be populated
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, maxWaitForIndexInMs, 5000L, MILLISECONDS);
|
||||||
|
|
||||||
|
SearchOptions options = SearchOptions.Builder.query("name:" + PREFIX);
|
||||||
|
assertTrue(waitForIndex.apply(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateEnvironment")
|
||||||
|
public void testListRecipesInEnvironment() {
|
||||||
|
Set<String> recipeList = api.listRecipesInEnvironment(PREFIX);
|
||||||
|
assertTrue(!recipeList.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateEnvironment")
|
||||||
|
public void testListNodesInEnvironment() {
|
||||||
|
api.deleteNode(ENV_NODE);
|
||||||
|
api.createNode(Node.builder().name(ENV_NODE).runListElement("role[" + PREFIX + "]").environment(PREFIX).build());
|
||||||
|
Node node = api.getNode(ENV_NODE);
|
||||||
|
assertNotNull(node, "Created node should not be null");
|
||||||
|
Set<String> nodeList = api.listNodesInEnvironment(PREFIX);
|
||||||
|
assertTrue(!nodeList.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateNewCookbook")
|
||||||
|
public void testListCookbooksInEnvironment() throws Exception {
|
||||||
|
Set<CookbookDefinition> cookbooks = api.listCookbooksInEnvironment("_default");
|
||||||
|
assertTrue(any(cookbooks, new Predicate<CookbookDefinition>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(CookbookDefinition input) {
|
||||||
|
return PREFIX.equals(input.getName());
|
||||||
|
}}), String.format("Cookbook %s not in %s", PREFIX, cookbooks));
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass(groups = { "live", "integration" })
|
||||||
|
@Override
|
||||||
|
public void tearDown() {
|
||||||
|
api.deleteClient(PREFIX);
|
||||||
|
api.deleteClient(ADMIN_PREFIX);
|
||||||
|
api.deleteNode(PREFIX);
|
||||||
|
api.deleteNode(ENV_NODE);
|
||||||
|
api.deleteRole(PREFIX);
|
||||||
|
api.deleteDatabag(PREFIX);
|
||||||
|
api.deleteEnvironment(PREFIX);
|
||||||
|
super.tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertClientCreated(String identity, String credential) {
|
||||||
|
Properties overrides = super.setupProperties();
|
||||||
|
overrides.setProperty(provider + ".identity", identity);
|
||||||
|
overrides.setProperty(provider + ".credential", credential);
|
||||||
|
|
||||||
|
ChefApi clientApi = create(overrides, setupModules());
|
||||||
|
|
||||||
|
try {
|
||||||
|
Client client = clientApi.getClient(identity);
|
||||||
|
assertNotNull(client, "Client not found: " + identity);
|
||||||
|
} finally {
|
||||||
|
closeQuietly(clientApi);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.enterprisechef.binders;
|
package org.jclouds.chef.binders;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ import java.net.URI;
|
||||||
|
|
||||||
import org.jclouds.chef.ChefApiMetadata;
|
import org.jclouds.chef.ChefApiMetadata;
|
||||||
import org.jclouds.chef.config.ChefParserModule;
|
import org.jclouds.chef.config.ChefParserModule;
|
||||||
import org.jclouds.enterprisechef.domain.Group;
|
import org.jclouds.chef.domain.Group;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.json.config.GsonModule;
|
import org.jclouds.json.config.GsonModule;
|
||||||
import org.jclouds.rest.annotations.ApiVersion;
|
import org.jclouds.rest.annotations.ApiVersion;
|
|
@ -14,13 +14,13 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.enterprisechef.binders;
|
package org.jclouds.chef.binders;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.jclouds.enterprisechef.domain.Group;
|
import org.jclouds.chef.domain.Group;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -14,7 +14,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.enterprisechef;
|
package org.jclouds.chef.features;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertNull;
|
import static org.testng.Assert.assertNull;
|
||||||
|
@ -24,15 +24,16 @@ import java.util.Set;
|
||||||
|
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.apis.ApiMetadata;
|
||||||
import org.jclouds.chef.BaseChefApiExpectTest;
|
import org.jclouds.chef.BaseChefApiExpectTest;
|
||||||
|
import org.jclouds.chef.ChefApi;
|
||||||
import org.jclouds.chef.ChefApiMetadata;
|
import org.jclouds.chef.ChefApiMetadata;
|
||||||
|
import org.jclouds.chef.config.ChefHttpApiModule;
|
||||||
|
import org.jclouds.chef.domain.Group;
|
||||||
|
import org.jclouds.chef.domain.User;
|
||||||
import org.jclouds.date.TimeStamp;
|
import org.jclouds.date.TimeStamp;
|
||||||
import org.jclouds.enterprisechef.config.EnterpriseChefHttpApiModule;
|
|
||||||
import org.jclouds.enterprisechef.domain.Group;
|
|
||||||
import org.jclouds.enterprisechef.domain.User;
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.providers.ProviderMetadata;
|
|
||||||
import org.jclouds.rest.ConfiguresHttpApi;
|
import org.jclouds.rest.ConfiguresHttpApi;
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
import org.jclouds.rest.ResourceNotFoundException;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -41,128 +42,125 @@ import com.google.common.base.Supplier;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expect tests for the {@link EnterpriseChefApi} class.
|
* Expect tests for the {@link OrganizationApi} class.
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", testName = "EnterpriseChefApiExpectTest")
|
@Test(groups = "unit", testName = "OrganizationApiExpectTest")
|
||||||
public class EnterpriseChefApiExpectTest extends BaseChefApiExpectTest<EnterpriseChefApi> {
|
public class OrganizationApiExpectTest extends BaseChefApiExpectTest<ChefApi> {
|
||||||
public EnterpriseChefApiExpectTest() {
|
|
||||||
provider = "enterprisechef";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetUserReturns2xx() {
|
public void testGetUserReturns2xx() {
|
||||||
EnterpriseChefApi api = requestSendsResponse(
|
ChefApi api = requestSendsResponse(
|
||||||
signed(HttpRequest.builder() //
|
signed(HttpRequest.builder() //
|
||||||
.method("GET") //
|
.method("GET") //
|
||||||
.endpoint("https://api.opscode.com/users/nacx") //
|
.endpoint("http://localhost:4000/users/nacx") //
|
||||||
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
||||||
.addHeader("Accept", MediaType.APPLICATION_JSON).build()), //
|
.addHeader("Accept", MediaType.APPLICATION_JSON).build()), //
|
||||||
HttpResponse.builder().statusCode(200)
|
HttpResponse.builder().statusCode(200)
|
||||||
.payload(payloadFromResourceWithContentType("/user.json", MediaType.APPLICATION_JSON)) //
|
.payload(payloadFromResourceWithContentType("/user.json", MediaType.APPLICATION_JSON)) //
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
User user = api.getUser("nacx");
|
User user = api.organizationApi().get().getUser("nacx");
|
||||||
assertEquals(user.getUsername(), "nacx");
|
assertEquals(user.getUsername(), "nacx");
|
||||||
assertEquals(user.getDisplayName(), "Ignasi Barrera");
|
assertEquals(user.getDisplayName(), "Ignasi Barrera");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetUserReturns404() {
|
public void testGetUserReturns404() {
|
||||||
EnterpriseChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
|
ChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
|
||||||
.method("GET") //
|
.method("GET") //
|
||||||
.endpoint("https://api.opscode.com/users/foo") //
|
.endpoint("http://localhost:4000/users/foo") //
|
||||||
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
||||||
.addHeader("Accept", MediaType.APPLICATION_JSON) //
|
.addHeader("Accept", MediaType.APPLICATION_JSON) //
|
||||||
.build()), //
|
.build()), //
|
||||||
HttpResponse.builder().statusCode(404).build());
|
HttpResponse.builder().statusCode(404).build());
|
||||||
|
|
||||||
assertNull(api.getUser("foo"));
|
assertNull(api.organizationApi().get().getUser("foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testListGroups() {
|
public void testListGroups() {
|
||||||
EnterpriseChefApi api = requestSendsResponse(
|
ChefApi api = requestSendsResponse(
|
||||||
signed(HttpRequest.builder() //
|
signed(HttpRequest.builder() //
|
||||||
.method("GET") //
|
.method("GET") //
|
||||||
.endpoint("https://api.opscode.com/groups") //
|
.endpoint("http://localhost:4000/groups") //
|
||||||
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
||||||
.addHeader("Accept", MediaType.APPLICATION_JSON).build()), //
|
.addHeader("Accept", MediaType.APPLICATION_JSON).build()), //
|
||||||
HttpResponse.builder().statusCode(200)
|
HttpResponse.builder().statusCode(200)
|
||||||
.payload(payloadFromResourceWithContentType("/groups.json", MediaType.APPLICATION_JSON)) //
|
.payload(payloadFromResourceWithContentType("/groups.json", MediaType.APPLICATION_JSON)) //
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
Set<String> groups = api.listGroups();
|
Set<String> groups = api.organizationApi().get().listGroups();
|
||||||
assertEquals(groups.size(), 5);
|
assertEquals(groups.size(), 5);
|
||||||
assertTrue(groups.contains("admins"));
|
assertTrue(groups.contains("admins"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetGroupReturns2xx() {
|
public void testGetGroupReturns2xx() {
|
||||||
EnterpriseChefApi api = requestSendsResponse(
|
ChefApi api = requestSendsResponse(
|
||||||
signed(HttpRequest.builder() //
|
signed(HttpRequest.builder() //
|
||||||
.method("GET") //
|
.method("GET") //
|
||||||
.endpoint("https://api.opscode.com/groups/admins") //
|
.endpoint("http://localhost:4000/groups/admins") //
|
||||||
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
||||||
.addHeader("Accept", MediaType.APPLICATION_JSON).build()), //
|
.addHeader("Accept", MediaType.APPLICATION_JSON).build()), //
|
||||||
HttpResponse.builder().statusCode(200)
|
HttpResponse.builder().statusCode(200)
|
||||||
.payload(payloadFromResourceWithContentType("/group.json", MediaType.APPLICATION_JSON)) //
|
.payload(payloadFromResourceWithContentType("/group.json", MediaType.APPLICATION_JSON)) //
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
Group group = api.getGroup("admins");
|
Group group = api.organizationApi().get().getGroup("admins");
|
||||||
assertEquals(group.getName(), "admins");
|
assertEquals(group.getName(), "admins");
|
||||||
assertEquals(group.getGroupname(), "admins");
|
assertEquals(group.getGroupname(), "admins");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetGroupReturns404() {
|
public void testGetGroupReturns404() {
|
||||||
EnterpriseChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
|
ChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
|
||||||
.method("GET") //
|
.method("GET") //
|
||||||
.endpoint("https://api.opscode.com/groups/foo") //
|
.endpoint("http://localhost:4000/groups/foo") //
|
||||||
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
||||||
.addHeader("Accept", MediaType.APPLICATION_JSON) //
|
.addHeader("Accept", MediaType.APPLICATION_JSON) //
|
||||||
.build()), //
|
.build()), //
|
||||||
HttpResponse.builder().statusCode(404).build());
|
HttpResponse.builder().statusCode(404).build());
|
||||||
|
|
||||||
assertNull(api.getGroup("foo"));
|
assertNull(api.organizationApi().get().getGroup("foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCreateGroupReturns2xx() {
|
public void testCreateGroupReturns2xx() {
|
||||||
EnterpriseChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
|
ChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
|
||||||
.method("POST") //
|
.method("POST") //
|
||||||
.endpoint("https://api.opscode.com/groups") //
|
.endpoint("http://localhost:4000/groups") //
|
||||||
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
||||||
.addHeader("Accept", MediaType.APPLICATION_JSON) //
|
.addHeader("Accept", MediaType.APPLICATION_JSON) //
|
||||||
.payload(payloadFromStringWithContentType("{\"groupname\":\"foo\"}", MediaType.APPLICATION_JSON)) //
|
.payload(payloadFromStringWithContentType("{\"groupname\":\"foo\"}", MediaType.APPLICATION_JSON)) //
|
||||||
.build()), //
|
.build()), //
|
||||||
HttpResponse.builder().statusCode(201).build());
|
HttpResponse.builder().statusCode(201).build());
|
||||||
|
|
||||||
api.createGroup("foo");
|
api.organizationApi().get().createGroup("foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDeleteGroupReturns2xx() {
|
public void testDeleteGroupReturns2xx() {
|
||||||
EnterpriseChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
|
ChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
|
||||||
.method("DELETE") //
|
.method("DELETE") //
|
||||||
.endpoint("https://api.opscode.com/groups/foo") //
|
.endpoint("http://localhost:4000/groups/foo") //
|
||||||
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
||||||
.addHeader("Accept", MediaType.APPLICATION_JSON) //
|
.addHeader("Accept", MediaType.APPLICATION_JSON) //
|
||||||
.build()), //
|
.build()), //
|
||||||
HttpResponse.builder().statusCode(200).build());
|
HttpResponse.builder().statusCode(200).build());
|
||||||
|
|
||||||
api.deleteGroup("foo");
|
api.organizationApi().get().deleteGroup("foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = ResourceNotFoundException.class)
|
@Test(expectedExceptions = ResourceNotFoundException.class)
|
||||||
public void testDeleteGroupFailsOn404() {
|
public void testDeleteGroupFailsOn404() {
|
||||||
EnterpriseChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
|
ChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
|
||||||
.method("DELETE") //
|
.method("DELETE") //
|
||||||
.endpoint("https://api.opscode.com/groups/foo") //
|
.endpoint("http://localhost:4000/groups/foo") //
|
||||||
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
||||||
.addHeader("Accept", MediaType.APPLICATION_JSON) //
|
.addHeader("Accept", MediaType.APPLICATION_JSON) //
|
||||||
.build()), //
|
.build()), //
|
||||||
HttpResponse.builder().statusCode(404).build());
|
HttpResponse.builder().statusCode(404).build());
|
||||||
|
|
||||||
api.deleteGroup("foo");
|
api.organizationApi().get().deleteGroup("foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testUpdateGroupReturns2xx() {
|
public void testUpdateGroupReturns2xx() {
|
||||||
EnterpriseChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
|
ChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
|
||||||
.method("PUT") //
|
.method("PUT") //
|
||||||
.endpoint("https://api.opscode.com/groups/admins") //
|
.endpoint("http://localhost:4000/groups/admins") //
|
||||||
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
||||||
.addHeader("Accept", MediaType.APPLICATION_JSON) //
|
.addHeader("Accept", MediaType.APPLICATION_JSON) //
|
||||||
.payload(payloadFromResourceWithContentType("/group-update.json", MediaType.APPLICATION_JSON)) //
|
.payload(payloadFromResourceWithContentType("/group-update.json", MediaType.APPLICATION_JSON)) //
|
||||||
|
@ -170,14 +168,14 @@ public class EnterpriseChefApiExpectTest extends BaseChefApiExpectTest<Enterpris
|
||||||
HttpResponse.builder().statusCode(200).build());
|
HttpResponse.builder().statusCode(200).build());
|
||||||
|
|
||||||
Group group = Group.builder("admins").client("abiquo").group("admins").user("nacx").build();
|
Group group = Group.builder("admins").client("abiquo").group("admins").user("nacx").build();
|
||||||
api.updateGroup(group);
|
api.organizationApi().get().updateGroup(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = ResourceNotFoundException.class)
|
@Test(expectedExceptions = ResourceNotFoundException.class)
|
||||||
public void testUpdateGroupFailsOn404() {
|
public void testUpdateGroupFailsOn404() {
|
||||||
EnterpriseChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
|
ChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
|
||||||
.method("PUT") //
|
.method("PUT") //
|
||||||
.endpoint("https://api.opscode.com/groups/admins") //
|
.endpoint("http://localhost:4000/groups/admins") //
|
||||||
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
|
||||||
.addHeader("Accept", MediaType.APPLICATION_JSON) //
|
.addHeader("Accept", MediaType.APPLICATION_JSON) //
|
||||||
.payload(payloadFromResourceWithContentType("/group-update.json", MediaType.APPLICATION_JSON)) //
|
.payload(payloadFromResourceWithContentType("/group-update.json", MediaType.APPLICATION_JSON)) //
|
||||||
|
@ -185,16 +183,16 @@ public class EnterpriseChefApiExpectTest extends BaseChefApiExpectTest<Enterpris
|
||||||
HttpResponse.builder().statusCode(404).build());
|
HttpResponse.builder().statusCode(404).build());
|
||||||
|
|
||||||
Group group = Group.builder("admins").client("abiquo").group("admins").user("nacx").build();
|
Group group = Group.builder("admins").client("abiquo").group("admins").user("nacx").build();
|
||||||
api.updateGroup(group);
|
api.organizationApi().get().updateGroup(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Module createModule() {
|
protected Module createModule() {
|
||||||
return new TestEnterpriseChefHttpApiModule();
|
return new TestChefHttpApiModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ConfiguresHttpApi
|
@ConfiguresHttpApi
|
||||||
static class TestEnterpriseChefHttpApiModule extends EnterpriseChefHttpApiModule {
|
static class TestChefHttpApiModule extends ChefHttpApiModule {
|
||||||
@Override
|
@Override
|
||||||
protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
|
protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
|
||||||
return "timestamp";
|
return "timestamp";
|
||||||
|
@ -202,8 +200,8 @@ public class EnterpriseChefApiExpectTest extends BaseChefApiExpectTest<Enterpris
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ProviderMetadata createProviderMetadata() {
|
protected ApiMetadata createApiMetadata() {
|
||||||
return new EnterpriseChefProviderMetadata();
|
return new ChefApiMetadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.enterprisechef;
|
package org.jclouds.chef.features;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertFalse;
|
import static org.testng.Assert.assertFalse;
|
||||||
|
@ -25,98 +25,96 @@ import static org.testng.Assert.assertTrue;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.jclouds.chef.internal.BaseChefApiLiveTest;
|
import org.jclouds.chef.domain.Group;
|
||||||
import org.jclouds.enterprisechef.domain.Group;
|
import org.jclouds.chef.domain.User;
|
||||||
import org.jclouds.enterprisechef.domain.User;
|
import org.jclouds.chef.internal.BaseChefLiveTest;
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
import org.jclouds.rest.ResourceNotFoundException;
|
||||||
|
import org.testng.SkipException;
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests behavior of the EnterpriseChefApi.
|
* Tests behavior of the OrganizationApi.
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", singleThreaded = true, testName = "EnterpriseChefApiLiveTest")
|
@Test(groups = "live", singleThreaded = true, testName = "OrganizationApiLiveTest")
|
||||||
public class EnterpriseChefApiLiveTest extends BaseChefApiLiveTest<EnterpriseChefApi> {
|
public class OrganizationApiLiveTest extends BaseChefLiveTest {
|
||||||
|
|
||||||
private static final String GROUP_NAME = System.getProperty("user.name") + "-jcloudstest";
|
private static final String GROUP_NAME = System.getProperty("user.name") + "-jcloudstest";
|
||||||
private static final String ORG_NAME = System.getProperty("test.enterprisechef.org");
|
|
||||||
|
|
||||||
public EnterpriseChefApiLiveTest() {
|
private OrganizationApi orgApi;
|
||||||
provider = "enterprisechef";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@BeforeMethod
|
||||||
@Test
|
public void skipIfApiNotAvailable() {
|
||||||
public void testSearchClientsWithOptions() throws Exception {
|
// Throwing SkipExceptions only works with @Test and @BeforeMethod methods
|
||||||
// This test will fail because Enterprise Chef does not index client name.
|
if (!api.organizationApi().isPresent()) {
|
||||||
// Once it is fixes, the test should succeed.
|
throw new SkipException("Organization api not available in this Chef version");
|
||||||
// See: http://tickets.opscode.com/browse/CHEF-2477
|
}
|
||||||
super.testSearchClientsWithOptions();
|
orgApi = api.organizationApi().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetUser() {
|
public void testGetUser() {
|
||||||
User user = api.getUser(identity);
|
User user = orgApi.getUser(identity);
|
||||||
assertEquals(user.getUsername(), identity);
|
assertEquals(user.getUsername(), identity);
|
||||||
assertNotNull(user.getPublicKey());
|
assertNotNull(user.getPublicKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetUnexistingUser() {
|
public void testGetUnexistingUser() {
|
||||||
User user = api.getUser(UUID.randomUUID().toString());
|
User user = orgApi.getUser(UUID.randomUUID().toString());
|
||||||
assertNull(user);
|
assertNull(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testListGroups() {
|
public void testListGroups() {
|
||||||
Set<String> groups = api.listGroups();
|
Set<String> groups = orgApi.listGroups();
|
||||||
assertNotNull(groups);
|
assertNotNull(groups);
|
||||||
assertFalse(groups.isEmpty());
|
assertFalse(groups.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetUnexistingGroup() {
|
public void testGetUnexistingGroup() {
|
||||||
Group group = api.getGroup(UUID.randomUUID().toString());
|
Group group = orgApi.getGroup(UUID.randomUUID().toString());
|
||||||
assertNull(group);
|
assertNull(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCreateGroup() {
|
public void testCreateGroup() {
|
||||||
api.createGroup(GROUP_NAME);
|
orgApi.createGroup(GROUP_NAME);
|
||||||
Group group = api.getGroup(GROUP_NAME);
|
Group group = orgApi.getGroup(GROUP_NAME);
|
||||||
assertNotNull(group);
|
assertNotNull(group);
|
||||||
assertEquals(group.getGroupname(), GROUP_NAME);
|
assertEquals(group.getGroupname(), GROUP_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateGroup")
|
@Test(dependsOnMethods = "testCreateGroup")
|
||||||
public void testUpdateGroup() {
|
public void testUpdateGroup() {
|
||||||
Group group = api.getGroup(GROUP_NAME);
|
Group group = orgApi.getGroup(GROUP_NAME);
|
||||||
Group updated = Group.builder(group.getGroupname()) //
|
Group updated = Group.builder(group.getGroupname()) //
|
||||||
.actors(group.getActors()) //
|
.actors(group.getActors()) //
|
||||||
.orgname(group.getOrgname()) //
|
.orgname(group.getOrgname()) //
|
||||||
.name(group.getName()) //
|
.name(group.getName()) //
|
||||||
.groups(group.getGroups()) //
|
.groups(group.getGroups()) //
|
||||||
.client(ORG_NAME + "-validator") //
|
.client(group.getOrgname() + "-validator") //
|
||||||
.user(identity) //
|
.user(identity) //
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
api.updateGroup(updated);
|
orgApi.updateGroup(updated);
|
||||||
group = api.getGroup(GROUP_NAME);
|
group = orgApi.getGroup(GROUP_NAME);
|
||||||
|
|
||||||
assertNotNull(group);
|
assertNotNull(group);
|
||||||
assertTrue(group.getUsers().contains(identity));
|
assertTrue(group.getUsers().contains(identity));
|
||||||
assertTrue(group.getClients().contains(ORG_NAME + "-validator"));
|
assertTrue(group.getClients().contains(group.getOrgname() + "-validator"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = ResourceNotFoundException.class)
|
@Test(expectedExceptions = ResourceNotFoundException.class)
|
||||||
public void testUpdateUnexistingGroup() {
|
public void testUpdateUnexistingGroup() {
|
||||||
api.updateGroup(Group.builder(UUID.randomUUID().toString()).build());
|
orgApi.updateGroup(Group.builder(UUID.randomUUID().toString()).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testUpdateGroup")
|
@Test(dependsOnMethods = "testUpdateGroup", alwaysRun = true)
|
||||||
public void testDeleteGroup() {
|
public void testDeleteGroup() {
|
||||||
api.deleteGroup(GROUP_NAME);
|
orgApi.deleteGroup(GROUP_NAME);
|
||||||
Group group = api.getGroup(GROUP_NAME);
|
Group group = orgApi.getGroup(GROUP_NAME);
|
||||||
assertNull(group);
|
assertNull(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = ResourceNotFoundException.class)
|
@Test(expectedExceptions = ResourceNotFoundException.class)
|
||||||
public void testDeleteUnexistingGroup() {
|
public void testDeleteUnexistingGroup() {
|
||||||
api.deleteGroup(UUID.randomUUID().toString());
|
orgApi.deleteGroup(UUID.randomUUID().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -88,7 +88,6 @@ public class ParseClientFromJsonTest {
|
||||||
publicKey = crypto.rsaKeyFactory().generatePublic(publicKeySpec);
|
publicKey = crypto.rsaKeyFactory().generatePublic(publicKeySpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("resource")
|
|
||||||
public void testClientWithPubKey() throws IOException, CertificateException, NoSuchAlgorithmException {
|
public void testClientWithPubKey() throws IOException, CertificateException, NoSuchAlgorithmException {
|
||||||
|
|
||||||
Client user = Client.builder().certificate(certificate).orgname("jclouds").clientname("adriancole-jcloudstest")
|
Client user = Client.builder().certificate(certificate).orgname("jclouds").clientname("adriancole-jcloudstest")
|
||||||
|
@ -99,7 +98,6 @@ public class ParseClientFromJsonTest {
|
||||||
.payload(ParseClientFromJsonTest.class.getResourceAsStream("/client.json")).build()), user);
|
.payload(ParseClientFromJsonTest.class.getResourceAsStream("/client.json")).build()), user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("resource")
|
|
||||||
public void testClientWithoutPubKey() throws IOException, CertificateException, NoSuchAlgorithmException {
|
public void testClientWithoutPubKey() throws IOException, CertificateException, NoSuchAlgorithmException {
|
||||||
|
|
||||||
Client user = Client.builder().certificate(certificate).orgname("jclouds").clientname("adriancole-jcloudstest")
|
Client user = Client.builder().certificate(certificate).orgname("jclouds").clientname("adriancole-jcloudstest")
|
||||||
|
|
|
@ -1,542 +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.internal;
|
|
||||||
|
|
||||||
import static com.google.common.collect.Iterables.any;
|
|
||||||
import static com.google.common.collect.Iterables.isEmpty;
|
|
||||||
import static com.google.common.hash.Hashing.md5;
|
|
||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
|
||||||
import static org.jclouds.util.Closeables2.closeQuietly;
|
|
||||||
import static org.jclouds.util.Predicates2.retry;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
import static org.testng.Assert.assertFalse;
|
|
||||||
import static org.testng.Assert.assertNotNull;
|
|
||||||
import static org.testng.Assert.assertNull;
|
|
||||||
import static org.testng.Assert.assertTrue;
|
|
||||||
import static org.testng.Assert.fail;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.jclouds.chef.ChefApi;
|
|
||||||
import org.jclouds.chef.domain.ChecksumStatus;
|
|
||||||
import org.jclouds.chef.domain.Client;
|
|
||||||
import org.jclouds.chef.domain.CookbookDefinition;
|
|
||||||
import org.jclouds.chef.domain.CookbookVersion;
|
|
||||||
import org.jclouds.chef.domain.DatabagItem;
|
|
||||||
import org.jclouds.chef.domain.Environment;
|
|
||||||
import org.jclouds.chef.domain.Metadata;
|
|
||||||
import org.jclouds.chef.domain.Node;
|
|
||||||
import org.jclouds.chef.domain.Resource;
|
|
||||||
import org.jclouds.chef.domain.Role;
|
|
||||||
import org.jclouds.chef.domain.Sandbox;
|
|
||||||
import org.jclouds.chef.domain.SearchResult;
|
|
||||||
import org.jclouds.chef.domain.UploadSandbox;
|
|
||||||
import org.jclouds.chef.options.CreateClientOptions;
|
|
||||||
import org.jclouds.chef.options.SearchOptions;
|
|
||||||
import org.jclouds.crypto.Pems;
|
|
||||||
import org.jclouds.io.ByteStreams2;
|
|
||||||
import org.jclouds.io.Payloads;
|
|
||||||
import org.jclouds.io.payloads.FilePayload;
|
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
|
||||||
import org.testng.annotations.AfterClass;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.hash.Hashing;
|
|
||||||
import com.google.common.io.Files;
|
|
||||||
import com.google.common.primitives.Bytes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests behavior of {@code ChefApi}
|
|
||||||
*/
|
|
||||||
@Test(groups = { "live", "integration" })
|
|
||||||
public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiveTest<A> {
|
|
||||||
public static final String PREFIX = "jcloudstest-" + System.getProperty("user.name");
|
|
||||||
public static final String ADMIN_PREFIX = "jcloudstest-adm-" + System.getProperty("user.name");
|
|
||||||
public static final String ENV_NODE = PREFIX + "-env-node";
|
|
||||||
|
|
||||||
// It may take a bit until the search index is populated
|
|
||||||
protected int maxWaitForIndexInMs = 60000;
|
|
||||||
|
|
||||||
// The id of the data bag item used in search tests
|
|
||||||
private String databagitemId;
|
|
||||||
|
|
||||||
public void testCreateNewCookbook() throws Exception {
|
|
||||||
// Define the file you want in the cookbook
|
|
||||||
File file = new File(System.getProperty("user.dir"), "pom.xml");
|
|
||||||
FilePayload content = uploadAndGetFilePayload(file);
|
|
||||||
|
|
||||||
// Create the metadata of the cookbook
|
|
||||||
Metadata metadata = Metadata.builder() //
|
|
||||||
.name(PREFIX) //
|
|
||||||
.version("0.0.0") //
|
|
||||||
.description("Jclouds test uploaded cookbook") //
|
|
||||||
.maintainer("jclouds") //
|
|
||||||
.maintainerEmail("someone@jclouds.org") //
|
|
||||||
.license("Apache 2.0") //
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Create a new cookbook
|
|
||||||
CookbookVersion cookbook = CookbookVersion.builder(PREFIX, "0.0.0") //
|
|
||||||
.metadata(metadata) //
|
|
||||||
.rootFile(Resource.builder().fromPayload(content).build()) //
|
|
||||||
.attribute(Resource.builder().fromPayload(content).name("default.rb").build())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// upload the cookbook to the remote server
|
|
||||||
api.updateCookbook(PREFIX, "0.0.0", cookbook);
|
|
||||||
}
|
|
||||||
|
|
||||||
private FilePayload uploadAndGetFilePayload(File file) throws IOException {
|
|
||||||
FilePayload content = Payloads.newFilePayload(file);
|
|
||||||
content.getContentMetadata().setContentType("application/x-binary");
|
|
||||||
|
|
||||||
// Get an md5 so that you can see if the server already has it or not
|
|
||||||
content.getContentMetadata().setContentMD5(Files.asByteSource(file).hash(Hashing.md5()).asBytes());
|
|
||||||
|
|
||||||
// Note that java collections cannot effectively do equals or hashcodes on
|
|
||||||
// byte arrays, so let's convert to a list of bytes.
|
|
||||||
List<Byte> md5 = Bytes.asList(content.getContentMetadata().getContentMD5());
|
|
||||||
|
|
||||||
// Request an upload site for this file
|
|
||||||
UploadSandbox site = api.createUploadSandboxForChecksums(ImmutableSet.of(md5));
|
|
||||||
assertTrue(site.getChecksums().containsKey(md5), md5 + " not in " + site.getChecksums());
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Upload the file contents, if still not uploaded
|
|
||||||
ChecksumStatus status = site.getChecksums().get(md5);
|
|
||||||
if (status.needsUpload()) {
|
|
||||||
api.uploadContent(status.getUrl(), content);
|
|
||||||
}
|
|
||||||
Sandbox sandbox = api.commitSandbox(site.getSandboxId(), true);
|
|
||||||
assertTrue(sandbox.isCompleted(), "Sandbox should be completed after uploading");
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
api.commitSandbox(site.getSandboxId(), false);
|
|
||||||
fail("Could not upload content");
|
|
||||||
}
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testListCookbooks() throws Exception {
|
|
||||||
Set<String> cookbookNames = api.listCookbooks();
|
|
||||||
assertFalse(cookbookNames.isEmpty(), "No cookbooks were found");
|
|
||||||
|
|
||||||
for (String cookbookName : cookbookNames) {
|
|
||||||
Set<String> versions = api.listVersionsOfCookbook(cookbookName);
|
|
||||||
assertFalse(versions.isEmpty(), "There are no versions of the cookbook: " + cookbookName);
|
|
||||||
|
|
||||||
for (String version : api.listVersionsOfCookbook(cookbookName)) {
|
|
||||||
CookbookVersion cookbook = api.getCookbook(cookbookName, version);
|
|
||||||
assertNotNull(cookbook, "Could not get cookbook: " + cookbookName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testListCookbooks")
|
|
||||||
public void testListCookbookVersionsWithChefService() throws Exception {
|
|
||||||
Iterable<? extends CookbookVersion> cookbooks = chefService.listCookbookVersions();
|
|
||||||
assertFalse(isEmpty(cookbooks), "No cookbooks were found");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testListCookbookVersionsWithChefService")
|
|
||||||
public void testDownloadCookbooks() throws Exception {
|
|
||||||
Iterable<? extends CookbookVersion> cookbooks = chefService.listCookbookVersions();
|
|
||||||
for (CookbookVersion cookbook : cookbooks) {
|
|
||||||
for (Resource resource : ImmutableList.<Resource> builder().addAll(cookbook.getDefinitions())
|
|
||||||
.addAll(cookbook.getFiles()).addAll(cookbook.getLibraries()).addAll(cookbook.getSuppliers())
|
|
||||||
.addAll(cookbook.getRecipes()).addAll(cookbook.getResources()).addAll(cookbook.getRootFiles())
|
|
||||||
.addAll(cookbook.getTemplates()).addAll(cookbook.getAttributes()).build()) {
|
|
||||||
|
|
||||||
InputStream stream = api.getResourceContents(resource);
|
|
||||||
assertNotNull(stream, "Resource contents are null for resource: " + resource.getName());
|
|
||||||
|
|
||||||
byte[] md5 = ByteStreams2.hashAndClose(stream, md5()).asBytes();
|
|
||||||
assertEquals(md5, resource.getChecksum());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateNewCookbook")
|
|
||||||
public void testUpdateCookbook() throws Exception {
|
|
||||||
CookbookVersion cookbook = api.getCookbook(PREFIX, "0.0.0");
|
|
||||||
assertNotNull(cookbook, "Cookbook not found: " + PREFIX);
|
|
||||||
assertNotNull(api.updateCookbook(PREFIX, "0.0.0", cookbook), "Updated cookbook was null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = { "testCreateNewCookbook", "testUpdateCookbook" })
|
|
||||||
public void testDeleteCookbook() throws Exception {
|
|
||||||
assertNotNull(api.deleteCookbook(PREFIX, "0.0.0"), "Deleted cookbook was null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateClient() throws Exception {
|
|
||||||
api.deleteClient(PREFIX);
|
|
||||||
String credential = Pems.pem(api.createClient(PREFIX).getPrivateKey());
|
|
||||||
assertClientCreated(PREFIX, credential);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateAdminClient() throws Exception {
|
|
||||||
api.deleteClient(ADMIN_PREFIX);
|
|
||||||
String credential = Pems.pem(api.createClient(ADMIN_PREFIX, CreateClientOptions.Builder.admin()).getPrivateKey());
|
|
||||||
assertClientCreated(ADMIN_PREFIX, credential);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateClient")
|
|
||||||
public void testGenerateKeyForClient() throws Exception {
|
|
||||||
String credential = Pems.pem(api.generateKeyForClient(PREFIX).getPrivateKey());
|
|
||||||
assertClientCreated(PREFIX, credential);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testListNodes() throws Exception {
|
|
||||||
Set<String> nodes = api.listNodes();
|
|
||||||
assertNotNull(nodes, "No nodes were found");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateRole")
|
|
||||||
public void testCreateNode() throws Exception {
|
|
||||||
api.deleteNode(PREFIX);
|
|
||||||
api.createNode(Node.builder().name(PREFIX).runListElement("role[" + PREFIX + "]").environment("_default").build());
|
|
||||||
Node node = api.getNode(PREFIX);
|
|
||||||
// TODO check recipes
|
|
||||||
assertNotNull(node, "Created node should not be null");
|
|
||||||
Set<String> nodes = api.listNodes();
|
|
||||||
assertTrue(nodes.contains(PREFIX), String.format("node %s not in %s", PREFIX, nodes));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateNode")
|
|
||||||
public void testUpdateNode() throws Exception {
|
|
||||||
for (String nodename : api.listNodes()) {
|
|
||||||
Node node = api.getNode(nodename);
|
|
||||||
api.updateNode(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testListRoles() throws Exception {
|
|
||||||
Set<String> roles = api.listRoles();
|
|
||||||
assertNotNull(roles, "Role list was null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateRole() throws Exception {
|
|
||||||
api.deleteRole(PREFIX);
|
|
||||||
api.createRole(Role.builder().name(PREFIX).runListElement("recipe[java]").build());
|
|
||||||
Role role = api.getRole(PREFIX);
|
|
||||||
assertNotNull(role, "Created role should not be null");
|
|
||||||
assertEquals(role.getName(), PREFIX);
|
|
||||||
assertEquals(role.getRunList(), Collections.singleton("recipe[java]"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateRole")
|
|
||||||
public void testUpdateRole() throws Exception {
|
|
||||||
for (String rolename : api.listRoles()) {
|
|
||||||
Role role = api.getRole(rolename);
|
|
||||||
api.updateRole(role);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testListDatabags() throws Exception {
|
|
||||||
Set<String> databags = api.listDatabags();
|
|
||||||
assertNotNull(databags, "Data bag list was null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateDatabag() throws Exception {
|
|
||||||
api.deleteDatabag(PREFIX);
|
|
||||||
api.createDatabag(PREFIX);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateDatabagItem")
|
|
||||||
public void testListDatabagItems() throws Exception {
|
|
||||||
Set<String> databagItems = api.listDatabagItems(PREFIX);
|
|
||||||
assertNotNull(databagItems, "Data bag item list was null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateDatabag")
|
|
||||||
public void testCreateDatabagItem() throws Exception {
|
|
||||||
Properties config = new Properties();
|
|
||||||
config.setProperty("foo", "bar");
|
|
||||||
api.deleteDatabagItem(PREFIX, PREFIX);
|
|
||||||
DatabagItem databagItem = api.createDatabagItem(PREFIX, new DatabagItem("config", json.toJson(config)));
|
|
||||||
databagitemId = databagItem.getId();
|
|
||||||
assertNotNull(databagItem, "Created data bag item should not be null");
|
|
||||||
assertEquals(databagItem.getId(), "config");
|
|
||||||
|
|
||||||
// The databagItem json contains extra keys: (the name and the type if the
|
|
||||||
// item)
|
|
||||||
Properties props = json.fromJson(databagItem.toString(), Properties.class);
|
|
||||||
for (Object key : config.keySet()) {
|
|
||||||
assertTrue(props.containsKey(key));
|
|
||||||
assertEquals(config.get(key), props.get(key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateDatabagItem")
|
|
||||||
public void testUpdateDatabagItem() throws Exception {
|
|
||||||
for (String databagItemId : api.listDatabagItems(PREFIX)) {
|
|
||||||
DatabagItem databagItem = api.getDatabagItem(PREFIX, databagItemId);
|
|
||||||
api.updateDatabagItem(PREFIX, databagItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testSearchDatabagWithOptions")
|
|
||||||
public void testDeleteDatabagItem() throws Exception {
|
|
||||||
for (String databagItemId : api.listDatabagItems(PREFIX)) {
|
|
||||||
DatabagItem databagItem = api.deleteDatabagItem(PREFIX, databagItemId);
|
|
||||||
assertNotNull(databagItem, "Deleted data bag item should not be null");
|
|
||||||
assertEquals(databagItem.getId(), databagItemId, "Deleted data bag item id must match the original id");
|
|
||||||
assertNull(api.getDatabagItem(PREFIX, databagItemId), "Data bag item should not exist");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testListSearchIndexes() throws Exception {
|
|
||||||
Set<String> indexes = api.listSearchIndexes();
|
|
||||||
assertNotNull(indexes, "The index list should not be null");
|
|
||||||
assertTrue(indexes.contains("node"));
|
|
||||||
assertTrue(indexes.contains("client"));
|
|
||||||
assertTrue(indexes.contains("role"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSearchNodes() throws Exception {
|
|
||||||
SearchResult<? extends Node> results = api.searchNodes();
|
|
||||||
assertNotNull(results, "Node result list should not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = { "testListSearchIndexes", "testCreateNode" })
|
|
||||||
public void testSearchNodesWithOptions() throws Exception {
|
|
||||||
Predicate<SearchOptions> waitForIndex = retry(new Predicate<SearchOptions>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(SearchOptions input) {
|
|
||||||
SearchResult<? extends Node> results = api.searchNodes(input);
|
|
||||||
assertNotNull(results);
|
|
||||||
if (results.size() > 0) {
|
|
||||||
assertEquals(results.size(), 1);
|
|
||||||
assertEquals(results.iterator().next().getName(), PREFIX);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
// The index may still not be populated
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, maxWaitForIndexInMs, 5000L, MILLISECONDS);
|
|
||||||
|
|
||||||
SearchOptions options = SearchOptions.Builder.query("name:" + PREFIX);
|
|
||||||
assertTrue(waitForIndex.apply(options));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSearchClients() throws Exception {
|
|
||||||
SearchResult<? extends Client> results = api.searchClients();
|
|
||||||
assertNotNull(results, "Client result list should not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = { "testListSearchIndexes", "testCreateClient" })
|
|
||||||
public void testSearchClientsWithOptions() throws Exception {
|
|
||||||
Predicate<SearchOptions> waitForIndex = retry(new Predicate<SearchOptions>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(SearchOptions input) {
|
|
||||||
SearchResult<? extends Client> results = api.searchClients(input);
|
|
||||||
assertNotNull(results);
|
|
||||||
if (results.size() > 0) {
|
|
||||||
assertEquals(results.size(), 1);
|
|
||||||
assertEquals(results.iterator().next().getName(), PREFIX);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
// The index may still not be populated
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, maxWaitForIndexInMs, 5000L, MILLISECONDS);
|
|
||||||
|
|
||||||
SearchOptions options = SearchOptions.Builder.query("name:" + PREFIX);
|
|
||||||
assertTrue(waitForIndex.apply(options));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSearchRoles() throws Exception {
|
|
||||||
SearchResult<? extends Role> results = api.searchRoles();
|
|
||||||
assertNotNull(results, "Role result list should not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = { "testListSearchIndexes", "testCreateRole" })
|
|
||||||
public void testSearchRolesWithOptions() throws Exception {
|
|
||||||
Predicate<SearchOptions> waitForIndex = retry(new Predicate<SearchOptions>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(SearchOptions input) {
|
|
||||||
SearchResult<? extends Role> results = api.searchRoles(input);
|
|
||||||
assertNotNull(results);
|
|
||||||
if (results.size() > 0) {
|
|
||||||
assertEquals(results.size(), 1);
|
|
||||||
assertEquals(results.iterator().next().getName(), PREFIX);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
// The index may still not be populated
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, maxWaitForIndexInMs, 5000L, MILLISECONDS);
|
|
||||||
|
|
||||||
SearchOptions options = SearchOptions.Builder.query("name:" + PREFIX);
|
|
||||||
assertTrue(waitForIndex.apply(options));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = { "testListSearchIndexes", "testCreateDatabagItem" })
|
|
||||||
public void testSearchDatabag() throws Exception {
|
|
||||||
SearchResult<? extends DatabagItem> results = api.searchDatabagItems(PREFIX);
|
|
||||||
assertNotNull(results, "Data bag item result list should not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = { "testListSearchIndexes", "testCreateDatabagItem" })
|
|
||||||
public void testSearchDatabagWithOptions() throws Exception {
|
|
||||||
Predicate<SearchOptions> waitForIndex = retry(new Predicate<SearchOptions>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(SearchOptions input) {
|
|
||||||
SearchResult<? extends DatabagItem> results = api.searchDatabagItems(PREFIX, input);
|
|
||||||
assertNotNull(results);
|
|
||||||
if (results.size() > 0) {
|
|
||||||
assertEquals(results.size(), 1);
|
|
||||||
assertEquals(results.iterator().next().getId(), databagitemId);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
// The index may still not be populated
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, maxWaitForIndexInMs, 5000L, MILLISECONDS);
|
|
||||||
|
|
||||||
SearchOptions options = SearchOptions.Builder.query("id:" + databagitemId);
|
|
||||||
assertTrue(waitForIndex.apply(options));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expectedExceptions = ResourceNotFoundException.class, dependsOnMethods = "testListSearchIndexes")
|
|
||||||
public void testSearchDatabagNotFound() throws Exception {
|
|
||||||
SearchResult<? extends DatabagItem> results = api.searchDatabagItems("whoopie");
|
|
||||||
assertNotNull(results, "Data bag item result list should not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateEnvironment() {
|
|
||||||
api.deleteEnvironment(PREFIX);
|
|
||||||
api.createEnvironment(Environment.builder().name(PREFIX).description(PREFIX).build());
|
|
||||||
Environment env = api.getEnvironment(PREFIX);
|
|
||||||
assertNotNull(env, "Created environment should not be null");
|
|
||||||
assertEquals(env.getName(), PREFIX);
|
|
||||||
assertEquals(env.getDescription(), PREFIX);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateEnvironment")
|
|
||||||
public void testListEnvironment() {
|
|
||||||
Set<String> envList = api.listEnvironments();
|
|
||||||
assertNotNull(envList, "Environment list was null");
|
|
||||||
assertTrue(envList.contains(PREFIX));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateEnvironment")
|
|
||||||
public void testSearchEnvironments() throws Exception {
|
|
||||||
SearchResult<? extends Environment> results = api.searchEnvironments();
|
|
||||||
assertNotNull(results, "Environment result list was null");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = { "testListSearchIndexes", "testCreateEnvironment" })
|
|
||||||
public void testSearchEnvironmentsWithOptions() throws Exception {
|
|
||||||
Predicate<SearchOptions> waitForIndex = retry(new Predicate<SearchOptions>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(SearchOptions input) {
|
|
||||||
SearchResult<? extends Environment> results = api.searchEnvironments(input);
|
|
||||||
assertNotNull(results);
|
|
||||||
if (results.size() > 0) {
|
|
||||||
assertEquals(results.size(), 1);
|
|
||||||
assertEquals(results.iterator().next().getName(), PREFIX);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
// The index may still not be populated
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, maxWaitForIndexInMs, 5000L, MILLISECONDS);
|
|
||||||
|
|
||||||
SearchOptions options = SearchOptions.Builder.query("name:" + PREFIX);
|
|
||||||
assertTrue(waitForIndex.apply(options));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateEnvironment")
|
|
||||||
public void testListRecipesInEnvironment() {
|
|
||||||
Set<String> recipeList = api.listRecipesInEnvironment(PREFIX);
|
|
||||||
assertTrue(!recipeList.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateEnvironment")
|
|
||||||
public void testListNodesInEnvironment() {
|
|
||||||
api.deleteNode(ENV_NODE);
|
|
||||||
api.createNode(Node.builder().name(ENV_NODE).runListElement("role[" + PREFIX + "]").environment(PREFIX).build());
|
|
||||||
Node node = api.getNode(ENV_NODE);
|
|
||||||
assertNotNull(node, "Created node should not be null");
|
|
||||||
Set<String> nodeList = api.listNodesInEnvironment(PREFIX);
|
|
||||||
assertTrue(!nodeList.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateNewCookbook")
|
|
||||||
public void testListCookbooksInEnvironment() throws Exception {
|
|
||||||
Set<CookbookDefinition> cookbooks = api.listCookbooksInEnvironment("_default");
|
|
||||||
assertTrue(any(cookbooks, new Predicate<CookbookDefinition>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(CookbookDefinition input) {
|
|
||||||
return PREFIX.equals(input.getName());
|
|
||||||
}}), String.format("Cookbook %s not in %s", PREFIX, cookbooks));
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterClass(groups = { "live", "integration" })
|
|
||||||
@Override
|
|
||||||
public void tearDown() {
|
|
||||||
api.deleteClient(PREFIX);
|
|
||||||
api.deleteClient(ADMIN_PREFIX);
|
|
||||||
api.deleteNode(PREFIX);
|
|
||||||
api.deleteNode(ENV_NODE);
|
|
||||||
api.deleteRole(PREFIX);
|
|
||||||
api.deleteDatabag(PREFIX);
|
|
||||||
api.deleteEnvironment(PREFIX);
|
|
||||||
super.tearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertClientCreated(String identity, String credential) {
|
|
||||||
Properties overrides = super.setupProperties();
|
|
||||||
overrides.setProperty(provider + ".identity", identity);
|
|
||||||
overrides.setProperty(provider + ".credential", credential);
|
|
||||||
|
|
||||||
A clientApi = create(overrides, setupModules());
|
|
||||||
|
|
||||||
try {
|
|
||||||
Client client = clientApi.getClient(identity);
|
|
||||||
assertNotNull(client, "Client not found: " + identity);
|
|
||||||
} finally {
|
|
||||||
closeQuietly(clientApi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -16,8 +16,6 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.chef.internal;
|
package org.jclouds.chef.internal;
|
||||||
|
|
||||||
import static org.jclouds.reflect.Types2.checkBound;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
@ -31,12 +29,11 @@ import org.testng.annotations.Test;
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
import com.google.common.io.Files;
|
import com.google.common.io.Files;
|
||||||
import com.google.common.reflect.TypeToken;
|
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
|
||||||
@Test(groups = "live")
|
@Test(groups = "live")
|
||||||
public abstract class BaseChefLiveTest<A extends ChefApi> extends BaseApiLiveTest<A> {
|
public abstract class BaseChefLiveTest extends BaseApiLiveTest<ChefApi> {
|
||||||
|
|
||||||
protected Injector injector;
|
protected Injector injector;
|
||||||
protected ChefService chefService;
|
protected ChefService chefService;
|
||||||
|
@ -64,9 +61,9 @@ public abstract class BaseChefLiveTest<A extends ChefApi> extends BaseApiLiveTes
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected A create(Properties props, Iterable<Module> modules) {
|
protected ChefApi create(Properties props, Iterable<Module> modules) {
|
||||||
injector = newBuilder().modules(modules).overrides(props).buildInjector();
|
injector = newBuilder().modules(modules).overrides(props).buildInjector();
|
||||||
return injector.getInstance(resolveApiClass());
|
return injector.getInstance(ChefApi.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String setCredentialFromPemFile(Properties overrides, String identity, String key) {
|
protected String setCredentialFromPemFile(Properties overrides, String identity, String key) {
|
||||||
|
@ -86,11 +83,4 @@ public abstract class BaseChefLiveTest<A extends ChefApi> extends BaseApiLiveTes
|
||||||
return credentialFromFile;
|
return credentialFromFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private Class<A> resolveApiClass() {
|
|
||||||
return Class.class.cast(checkBound(new TypeToken<A>(getClass()) {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
}).getRawType());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,60 +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.internal;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.jclouds.apis.ApiMetadata;
|
|
||||||
import org.jclouds.chef.ChefApi;
|
|
||||||
import org.jclouds.chef.ChefApiMetadata;
|
|
||||||
import org.jclouds.chef.config.ChefBootstrapModule;
|
|
||||||
import org.jclouds.chef.config.ChefHttpApiModule;
|
|
||||||
import org.jclouds.chef.config.ChefParserModule;
|
|
||||||
import org.jclouds.domain.JsonBall;
|
|
||||||
import org.jclouds.ohai.AutomaticSupplier;
|
|
||||||
import org.jclouds.ohai.config.ConfiguresOhai;
|
|
||||||
import org.jclouds.ohai.config.OhaiModule;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
|
||||||
import com.google.common.base.Suppliers;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.inject.Module;
|
|
||||||
|
|
||||||
@Test(groups = "live")
|
|
||||||
@Deprecated
|
|
||||||
public class BaseStubbedOhaiLiveTest extends BaseChefLiveTest<ChefApi> {
|
|
||||||
|
|
||||||
@ConfiguresOhai
|
|
||||||
static class TestOhaiModule extends OhaiModule {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Supplier<Map<String, JsonBall>> provideAutomatic(AutomaticSupplier in) {
|
|
||||||
return Suppliers.<Map<String, JsonBall>> ofInstance(ImmutableMap.of("foo", new JsonBall("bar")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ApiMetadata createApiMetadata() {
|
|
||||||
return new ChefApiMetadata()
|
|
||||||
.toBuilder()
|
|
||||||
.defaultModules(
|
|
||||||
ImmutableSet.<Class<? extends Module>> of(ChefHttpApiModule.class, ChefParserModule.class,
|
|
||||||
ChefBootstrapModule.class, TestOhaiModule.class)).build();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,7 +19,6 @@ package org.jclouds.chef.strategy.internal;
|
||||||
import static org.testng.Assert.assertNotNull;
|
import static org.testng.Assert.assertNotNull;
|
||||||
import static org.testng.Assert.assertNull;
|
import static org.testng.Assert.assertNull;
|
||||||
|
|
||||||
import org.jclouds.chef.ChefApi;
|
|
||||||
import org.jclouds.chef.internal.BaseChefLiveTest;
|
import org.jclouds.chef.internal.BaseChefLiveTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -29,7 +28,7 @@ import com.google.common.collect.ImmutableSet;
|
||||||
* Tests behavior of {@code CleanupStaleNodesAndClientsImpl} strategies
|
* Tests behavior of {@code CleanupStaleNodesAndClientsImpl} strategies
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", testName = "CleanupStaleNodesAndClientsImplLiveTest")
|
@Test(groups = "live", testName = "CleanupStaleNodesAndClientsImplLiveTest")
|
||||||
public class CleanupStaleNodesAndClientsImplLiveTest extends BaseChefLiveTest<ChefApi> {
|
public class CleanupStaleNodesAndClientsImplLiveTest extends BaseChefLiveTest {
|
||||||
|
|
||||||
private CreateNodeAndPopulateAutomaticAttributesImpl creator;
|
private CreateNodeAndPopulateAutomaticAttributesImpl creator;
|
||||||
private CleanupStaleNodesAndClientsImpl strategy;
|
private CleanupStaleNodesAndClientsImpl strategy;
|
||||||
|
|
|
@ -20,7 +20,6 @@ import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.chef.ChefApi;
|
|
||||||
import org.jclouds.chef.domain.Node;
|
import org.jclouds.chef.domain.Node;
|
||||||
import org.jclouds.chef.internal.BaseChefLiveTest;
|
import org.jclouds.chef.internal.BaseChefLiveTest;
|
||||||
import org.jclouds.ohai.config.OhaiModule.CurrentUserProvider;
|
import org.jclouds.ohai.config.OhaiModule.CurrentUserProvider;
|
||||||
|
@ -33,7 +32,7 @@ import com.google.common.collect.ImmutableSet;
|
||||||
* strategies
|
* strategies
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", testName = "CreateNodeAndPopulateAutomaticAttributesImplLiveTest")
|
@Test(groups = "live", testName = "CreateNodeAndPopulateAutomaticAttributesImplLiveTest")
|
||||||
public class CreateNodeAndPopulateAutomaticAttributesImplLiveTest extends BaseChefLiveTest<ChefApi> {
|
public class CreateNodeAndPopulateAutomaticAttributesImplLiveTest extends BaseChefLiveTest {
|
||||||
|
|
||||||
private CurrentUserProvider currentUserProvider;
|
private CurrentUserProvider currentUserProvider;
|
||||||
private CreateNodeAndPopulateAutomaticAttributesImpl strategy;
|
private CreateNodeAndPopulateAutomaticAttributesImpl strategy;
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.chef.strategy.internal;
|
package org.jclouds.chef.strategy.internal;
|
||||||
|
|
||||||
import static org.easymock.classextension.EasyMock.createMock;
|
import static org.easymock.EasyMock.createMock;
|
||||||
import static org.easymock.classextension.EasyMock.replay;
|
import static org.easymock.EasyMock.replay;
|
||||||
import static org.easymock.classextension.EasyMock.verify;
|
import static org.easymock.EasyMock.verify;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ package org.jclouds.chef.strategy.internal;
|
||||||
import static org.testng.Assert.assertNotNull;
|
import static org.testng.Assert.assertNotNull;
|
||||||
import static org.testng.Assert.assertNull;
|
import static org.testng.Assert.assertNull;
|
||||||
|
|
||||||
import org.jclouds.chef.ChefApi;
|
|
||||||
import org.jclouds.chef.internal.BaseChefLiveTest;
|
import org.jclouds.chef.internal.BaseChefLiveTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -29,7 +28,7 @@ import com.google.common.collect.ImmutableSet;
|
||||||
* Tests behavior of {@code DeleteAllApisAndNodesInListImpl} strategies
|
* Tests behavior of {@code DeleteAllApisAndNodesInListImpl} strategies
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", testName = "DeleteAllApisAndNodesInListImplLiveTest")
|
@Test(groups = "live", testName = "DeleteAllApisAndNodesInListImplLiveTest")
|
||||||
public class DeleteAllApisAndNodesInListImplLiveTest extends BaseChefLiveTest<ChefApi> {
|
public class DeleteAllApisAndNodesInListImplLiveTest extends BaseChefLiveTest {
|
||||||
|
|
||||||
private DeleteAllNodesInListImpl strategy;
|
private DeleteAllNodesInListImpl strategy;
|
||||||
private CreateNodeAndPopulateAutomaticAttributesImpl creator;
|
private CreateNodeAndPopulateAutomaticAttributesImpl creator;
|
||||||
|
|
|
@ -25,9 +25,6 @@ import java.util.List;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
|
||||||
import org.jclouds.chef.ChefApi;
|
|
||||||
import org.jclouds.chef.domain.ChecksumStatus;
|
import org.jclouds.chef.domain.ChecksumStatus;
|
||||||
import org.jclouds.chef.domain.CookbookVersion;
|
import org.jclouds.chef.domain.CookbookVersion;
|
||||||
import org.jclouds.chef.domain.Metadata;
|
import org.jclouds.chef.domain.Metadata;
|
||||||
|
@ -44,12 +41,14 @@ import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.hash.Hashing;
|
import com.google.common.hash.Hashing;
|
||||||
import com.google.common.io.Files;
|
import com.google.common.io.Files;
|
||||||
import com.google.common.primitives.Bytes;
|
import com.google.common.primitives.Bytes;
|
||||||
|
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests behavior of {@code ListCookbookVersionsInEnvironmentImpl} strategies
|
* Tests behavior of {@code ListCookbookVersionsInEnvironmentImpl} strategies
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", testName = "ListCookbookVersionsInEnvironmentImplLiveTest")
|
@Test(groups = "live", testName = "ListCookbookVersionsInEnvironmentImplLiveTest")
|
||||||
public class ListCookbookVersionsInEnvironmentImplLiveTest extends BaseChefLiveTest<ChefApi> {
|
public class ListCookbookVersionsInEnvironmentImplLiveTest extends BaseChefLiveTest {
|
||||||
public static final String PREFIX = "jcloudstest-strategy-" + System.getProperty("user.name");
|
public static final String PREFIX = "jcloudstest-strategy-" + System.getProperty("user.name");
|
||||||
|
|
||||||
private ListCookbookVersionsInEnvironmentImpl strategy;
|
private ListCookbookVersionsInEnvironmentImpl strategy;
|
||||||
|
|
|
@ -19,23 +19,22 @@ package org.jclouds.chef.strategy.internal;
|
||||||
import static com.google.common.collect.Iterables.size;
|
import static com.google.common.collect.Iterables.size;
|
||||||
import static org.testng.Assert.assertTrue;
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import java.util.concurrent.Executors;
|
||||||
import org.jclouds.chef.ChefApi;
|
|
||||||
import org.jclouds.chef.internal.BaseChefLiveTest;
|
import org.jclouds.chef.internal.BaseChefLiveTest;
|
||||||
import org.testng.annotations.AfterClass;
|
import org.testng.annotations.AfterClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
import java.util.concurrent.ExecutorService;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests behavior of {@code ListNodesImpl} strategies
|
* Tests behavior of {@code ListNodesImpl} strategies
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", testName = "ListNodesImplLiveTest")
|
@Test(groups = "live", testName = "ListNodesImplLiveTest")
|
||||||
public class ListNodesImplLiveTest extends BaseChefLiveTest<ChefApi> {
|
public class ListNodesImplLiveTest extends BaseChefLiveTest {
|
||||||
|
|
||||||
private ListNodesImpl strategy;
|
private ListNodesImpl strategy;
|
||||||
private CreateNodeAndPopulateAutomaticAttributesImpl creator;
|
private CreateNodeAndPopulateAutomaticAttributesImpl creator;
|
||||||
|
|
|
@ -19,23 +19,22 @@ package org.jclouds.chef.strategy.internal;
|
||||||
import static com.google.common.collect.Iterables.size;
|
import static com.google.common.collect.Iterables.size;
|
||||||
import static org.testng.Assert.assertTrue;
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import java.util.concurrent.Executors;
|
||||||
import org.jclouds.chef.ChefApi;
|
|
||||||
import org.jclouds.chef.internal.BaseChefLiveTest;
|
import org.jclouds.chef.internal.BaseChefLiveTest;
|
||||||
import org.testng.annotations.AfterClass;
|
import org.testng.annotations.AfterClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
import java.util.concurrent.ExecutorService;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests behavior of {@code ListNodesInEnvironmentImpl} strategies
|
* Tests behavior of {@code ListNodesInEnvironmentImpl} strategies
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", testName = "ListNodesInEnvironmentImplLiveTest")
|
@Test(groups = "live", testName = "ListNodesInEnvironmentImplLiveTest")
|
||||||
public class ListNodesInEnvironmentImplLiveTest extends BaseChefLiveTest<ChefApi> {
|
public class ListNodesInEnvironmentImplLiveTest extends BaseChefLiveTest {
|
||||||
|
|
||||||
private ListNodesInEnvironmentImpl strategy;
|
private ListNodesInEnvironmentImpl strategy;
|
||||||
private CreateNodeAndPopulateAutomaticAttributesImpl creator;
|
private CreateNodeAndPopulateAutomaticAttributesImpl creator;
|
||||||
|
|
|
@ -20,7 +20,6 @@ import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.chef.ChefApi;
|
|
||||||
import org.jclouds.chef.domain.Node;
|
import org.jclouds.chef.domain.Node;
|
||||||
import org.jclouds.chef.internal.BaseChefLiveTest;
|
import org.jclouds.chef.internal.BaseChefLiveTest;
|
||||||
import org.jclouds.ohai.config.OhaiModule.CurrentUserProvider;
|
import org.jclouds.ohai.config.OhaiModule.CurrentUserProvider;
|
||||||
|
@ -32,7 +31,7 @@ import com.google.common.collect.ImmutableSet;
|
||||||
* Tests behavior of {@code UpdateAutomaticAttributesOnNodeImpl} strategies
|
* Tests behavior of {@code UpdateAutomaticAttributesOnNodeImpl} strategies
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", testName = "UpdateAutomaticAttributesOnNodeImplLiveTest")
|
@Test(groups = "live", testName = "UpdateAutomaticAttributesOnNodeImplLiveTest")
|
||||||
public class UpdateAutomaticAttributesOnNodeImplLiveTest extends BaseChefLiveTest<ChefApi> {
|
public class UpdateAutomaticAttributesOnNodeImplLiveTest extends BaseChefLiveTest {
|
||||||
|
|
||||||
private CurrentUserProvider currentUserProvider;
|
private CurrentUserProvider currentUserProvider;
|
||||||
private UpdateAutomaticAttributesOnNodeImpl strategy;
|
private UpdateAutomaticAttributesOnNodeImpl strategy;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"display_name" : "Ignasi Barrera",
|
"display_name" : "Ignasi Barrera",
|
||||||
"email" : "myemail@enterprisechef.org",
|
"email" : "myemail@chef.org",
|
||||||
"first_name" : "Ignasi",
|
"first_name" : "Ignasi",
|
||||||
"last_name" : "Barrera",
|
"last_name" : "Barrera",
|
||||||
"middle_name" : "",
|
"middle_name" : "",
|
|
@ -1,114 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<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/maven-v4_0_0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>org.apache.jclouds</groupId>
|
|
||||||
<artifactId>jclouds-project</artifactId>
|
|
||||||
<version>2.0.0-SNAPSHOT</version>
|
|
||||||
<relativePath>../../project/pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
<groupId>org.apache.jclouds.provider</groupId>
|
|
||||||
<artifactId>enterprisechef</artifactId>
|
|
||||||
<name>jclouds Enterprise Chef provider</name>
|
|
||||||
<description>jclouds components to access Enterprise Chef</description>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<test.enterprisechef.org>YOUR_ORG</test.enterprisechef.org>
|
|
||||||
<test.enterprisechef.endpoint>https://api.opscode.com/organizations/${test.enterprisechef.org}</test.enterprisechef.endpoint>
|
|
||||||
<test.enterprisechef.api-version />
|
|
||||||
<test.enterprisechef.build-version />
|
|
||||||
<test.enterprisechef.identity>YOUR_USER</test.enterprisechef.identity>
|
|
||||||
<test.enterprisechef.credential>${user.home}/.chef/${test.enterprisechef.org}/${test.enterprisechef.identity}.pem</test.enterprisechef.credential>
|
|
||||||
<jclouds.osgi.export>org.jclouds.enterprisechef*;version="${project.version}"</jclouds.osgi.export>
|
|
||||||
<jclouds.osgi.import>org.jclouds*;version="${project.version}",*</jclouds.osgi.import>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.jclouds.api</groupId>
|
|
||||||
<artifactId>chef</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.jclouds.api</groupId>
|
|
||||||
<artifactId>chef</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<type>test-jar</type>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.jclouds</groupId>
|
|
||||||
<artifactId>jclouds-core</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<type>test-jar</type>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.jclouds.driver</groupId>
|
|
||||||
<artifactId>jclouds-slf4j</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>ch.qos.logback</groupId>
|
|
||||||
<artifactId>logback-classic</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.auto.service</groupId>
|
|
||||||
<artifactId>auto-service</artifactId>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<profiles>
|
|
||||||
<profile>
|
|
||||||
<id>live</id>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>integration</id>
|
|
||||||
<phase>integration-test</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>test</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<systemPropertyVariables>
|
|
||||||
<test.enterprisechef.org>${test.enterprisechef.org}</test.enterprisechef.org>
|
|
||||||
<test.enterprisechef.endpoint>${test.enterprisechef.endpoint}</test.enterprisechef.endpoint>
|
|
||||||
<test.enterprisechef.api-version>${test.enterprisechef.api-version}</test.enterprisechef.api-version>
|
|
||||||
<test.enterprisechef.build-version>${test.enterprisechef.build-version}</test.enterprisechef.build-version>
|
|
||||||
<test.enterprisechef.identity>${test.enterprisechef.identity}</test.enterprisechef.identity>
|
|
||||||
<test.enterprisechef.credential>${test.enterprisechef.credential}</test.enterprisechef.credential>
|
|
||||||
</systemPropertyVariables>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
</project>
|
|
|
@ -1,81 +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.enterprisechef;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.jclouds.apis.ApiMetadata;
|
|
||||||
import org.jclouds.chef.ChefApiMetadata;
|
|
||||||
import org.jclouds.chef.config.ChefBootstrapModule;
|
|
||||||
import org.jclouds.chef.config.ChefParserModule;
|
|
||||||
import org.jclouds.enterprisechef.config.EnterpriseChefHttpApiModule;
|
|
||||||
import org.jclouds.ohai.config.JMXOhaiModule;
|
|
||||||
import org.jclouds.rest.internal.BaseHttpApiMetadata;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.inject.Module;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of {@link ApiMetadata} for the Enterprise Chef api.
|
|
||||||
*/
|
|
||||||
public class EnterpriseChefApiMetadata extends BaseHttpApiMetadata<EnterpriseChefApi> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Builder toBuilder() {
|
|
||||||
return new Builder().fromApiMetadata(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public EnterpriseChefApiMetadata() {
|
|
||||||
this(new Builder());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected EnterpriseChefApiMetadata(final Builder builder) {
|
|
||||||
super(builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Properties defaultProperties() {
|
|
||||||
return ChefApiMetadata.defaultProperties();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Builder extends BaseHttpApiMetadata.Builder<EnterpriseChefApi, Builder> {
|
|
||||||
|
|
||||||
protected Builder() {
|
|
||||||
id("enterprisechef")
|
|
||||||
.name("Enterprise Chef Api")
|
|
||||||
.identityName("User")
|
|
||||||
.credentialName("Certificate")
|
|
||||||
.version(ChefApiMetadata.DEFAULT_API_VERSION)
|
|
||||||
.documentation(URI.create("http://www.opscode.com/support"))
|
|
||||||
.defaultEndpoint("https://api.opscode.com")
|
|
||||||
.defaultProperties(EnterpriseChefApiMetadata.defaultProperties())
|
|
||||||
.defaultModules(
|
|
||||||
ImmutableSet.<Class<? extends Module>> of(EnterpriseChefHttpApiModule.class,
|
|
||||||
ChefParserModule.class, ChefBootstrapModule.class, JMXOhaiModule.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnterpriseChefApiMetadata build() {
|
|
||||||
return new EnterpriseChefApiMetadata(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Builder self() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,79 +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.enterprisechef;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.jclouds.providers.ProviderMetadata;
|
|
||||||
import org.jclouds.providers.internal.BaseProviderMetadata;
|
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of @ link ProviderMetadata} for Enterprise Chef
|
|
||||||
*/
|
|
||||||
@AutoService(ProviderMetadata.class)
|
|
||||||
public class EnterpriseChefProviderMetadata extends BaseProviderMetadata {
|
|
||||||
|
|
||||||
public static Builder builder() {
|
|
||||||
return new Builder();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Builder toBuilder() {
|
|
||||||
return builder().fromProviderMetadata(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public EnterpriseChefProviderMetadata() {
|
|
||||||
super(builder());
|
|
||||||
}
|
|
||||||
|
|
||||||
public EnterpriseChefProviderMetadata(final Builder builder) {
|
|
||||||
super(builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Properties defaultProperties() {
|
|
||||||
Properties properties = new Properties();
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EnterpriseChefProviderMetadata build() {
|
|
||||||
return new EnterpriseChefProviderMetadata(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Builder fromProviderMetadata(final ProviderMetadata in) {
|
|
||||||
super.fromProviderMetadata(in);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +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.enterprisechef.config;
|
|
||||||
|
|
||||||
import org.jclouds.chef.ChefApi;
|
|
||||||
import org.jclouds.chef.config.BaseChefHttpApiModule;
|
|
||||||
import org.jclouds.enterprisechef.EnterpriseChefApi;
|
|
||||||
import org.jclouds.rest.ConfiguresHttpApi;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures the Enterprise Chef connection.
|
|
||||||
*/
|
|
||||||
@ConfiguresHttpApi
|
|
||||||
public class EnterpriseChefHttpApiModule extends BaseChefHttpApiModule<EnterpriseChefApi> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure() {
|
|
||||||
super.configure();
|
|
||||||
bind(ChefApi.class).to(EnterpriseChefApi.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,31 +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.enterprisechef;
|
|
||||||
|
|
||||||
import org.jclouds.providers.internal.BaseProviderMetadataTest;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unit tests for the {@link EnterpriseChefProviderMetadata} class.
|
|
||||||
*/
|
|
||||||
@Test(groups = "unit", testName = "EnterpriseChefProviderTest")
|
|
||||||
public class EnterpriseChefProviderMetadataTest extends BaseProviderMetadataTest {
|
|
||||||
|
|
||||||
public EnterpriseChefProviderMetadataTest() {
|
|
||||||
super(new EnterpriseChefProviderMetadata(), new EnterpriseChefApiMetadata());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -72,6 +72,5 @@
|
||||||
<module>aws-route53</module>
|
<module>aws-route53</module>
|
||||||
<module>ultradns-ws</module>
|
<module>ultradns-ws</module>
|
||||||
<module>dynect</module>
|
<module>dynect</module>
|
||||||
<module>enterprisechef</module>
|
|
||||||
</modules>
|
</modules>
|
||||||
</project>
|
</project>
|
||||||
|
|
Loading…
Reference in New Issue