Promoted jclouds-chef/enterprise to providers/chef

This commit is contained in:
Ignasi Barrera 2014-10-10 15:11:08 +02:00
commit 8a2de9a5c7
19 changed files with 1502 additions and 0 deletions

View File

@ -0,0 +1,110 @@
<?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.chef</groupId>
<artifactId>chef-project</artifactId>
<version>2.0.0-SNAPSHOT</version>
<relativePath>../project/pom.xml</relativePath>
</parent>
<groupId>org.apache.jclouds.provider</groupId>
<artifactId>enterprisechef</artifactId>
<name>Apache jclouds Chef :: Enterprise</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="${jclouds.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>${jclouds.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.jclouds.driver</groupId>
<artifactId>jclouds-slf4j</artifactId>
<version>${jclouds.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.9</version>
<scope>test</scope>
</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>

View File

@ -0,0 +1,124 @@
/*
* 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.util.Set;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.Constants;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.chef.ChefApi;
import org.jclouds.chef.filters.SignedHeaderAuth;
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.Fallback;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.ParamParser;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.WrapWith;
/**
* Provides synchronous access to the Enterprise Chef Api.
*/
@RequestFilters(SignedHeaderAuth.class)
@Consumes(MediaType.APPLICATION_JSON)
@Headers(keys = "X-Chef-Version", values = "{" + Constants.PROPERTY_API_VERSION + "}")
public interface EnterpriseChefApi extends ChefApi
{
/**
* Retrieves an existing user.
*
* @param name The name of the user to get.
* @return The details of the user or <code>null</code> if not found.
*/
@Named("user:get")
@GET
@Path("/users/{name}")
@Fallback(NullOnNotFoundOr404.class)
User getUser(@PathParam("name") String name);
/**
* List all existing groups.
*
* @return The list of groups.
*/
@Named("group:list")
@GET
@Path("/groups")
@ResponseParser(ParseKeySetFromJson.class)
Set<String> listGroups();
/**
* Retrieves an existing group.
*
* @param name The name of the group to get.
* @return The details of the group or <code>null</code> if not found.
*/
@Named("group:get")
@GET
@Path("/groups/{name}")
@Fallback(NullOnNotFoundOr404.class)
Group getGroup(@PathParam("name") String name);
/**
* Creates a new group.
*
* @param name The name of the group to create.
*/
@Named("group:create")
@POST
@Path("/groups")
void createGroup(@WrapWith("groupname") String name);
/**
* Updates a group.
* <p>
* This method can be used to add actors (clients, groups) to the group.
*
* @param group The group with the updated information.
*/
@Named("group:update")
@PUT
@Path("/groups/{name}")
void updateGroup(
@PathParam("name") @ParamParser(GroupName.class) @BinderParam(BindGroupToUpdateRequestJsonPayload.class) Group group);
/**
* Deletes a group.
*
* @param name The name of the group to delete.
*/
@Named("group:delete")
@DELETE
@Path("/groups/{name}")
void deleteGroup(@PathParam("name") String name);
}

View File

@ -0,0 +1,82 @@
/*
* 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.chef.ChefApiMetadata;
import org.jclouds.chef.ChefContext;
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(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")
.view(ChefContext.class)
.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;
}
}
}

View File

@ -0,0 +1,86 @@
/*
* 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;
/**
* Implementation of @ link org.jclouds.types.ProviderMetadata} for Enterprise Chef
*/
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(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(ProviderMetadata in)
{
super.fromProviderMetadata(in);
return this;
}
}
}

View File

@ -0,0 +1,79 @@
/*
* 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.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.enterprisechef.domain.Group;
import org.jclouds.http.HttpRequest;
import org.jclouds.json.Json;
import org.jclouds.rest.binders.BindToJsonPayload;
/**
* Binds a group to the payload expected for the Put method in the Enterprise Chef
* Api.
*/
@Singleton
public class BindGroupToUpdateRequestJsonPayload extends BindToJsonPayload {
@Inject
public BindGroupToUpdateRequestJsonPayload(Json jsonBinder) {
super(jsonBinder);
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object payload) {
checkArgument(checkNotNull(payload, "payload") instanceof Group, "this binder is only valid for Group objects");
GroupUpdateRequest updateGroup = new GroupUpdateRequest((Group) payload);
return super.bindToRequest(request, updateGroup);
}
@SuppressWarnings("unused")
private static class GroupUpdateRequest {
private String name;
private String groupname;
private String orgname;
private ActorConfiguration actors;
public GroupUpdateRequest(Group group) {
this.name = group.getName();
this.groupname = group.getGroupname();
this.orgname = group.getOrgname();
this.actors = new ActorConfiguration(group);
}
}
@SuppressWarnings("unused")
private static class ActorConfiguration {
private Set<String> clients;
private Set<String> groups;
private Set<String> users;
public ActorConfiguration(Group group) {
this.clients = group.getClients();
this.groups = group.getGroups();
this.users = group.getUsers();
}
}
}

View File

@ -0,0 +1,38 @@
/*
* 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.binders;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Singleton;
import org.jclouds.enterprisechef.domain.Group;
import com.google.common.base.Function;
/**
* Gets the name of a group.
*/
@Singleton
public class GroupName implements Function<Object, String> {
@Override
public String apply(Object from) {
return ((Group) checkNotNull(from, "from")).getGroupname();
}
}

View File

@ -0,0 +1,36 @@
/*
* 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);
}
}

View File

@ -0,0 +1,211 @@
/*
* 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.domain;
import static org.jclouds.chef.util.CollectionUtils.copyOfOrEmpty;
import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.collect.ImmutableSet;
/**
* Group object.
*/
public class Group {
public static Builder builder(String groupname) {
return new Builder(groupname);
}
public static class Builder {
private String name;
private String groupname;
private String orgname;
private ImmutableSet.Builder<String> actors = ImmutableSet.builder();
private ImmutableSet.Builder<String> clients = ImmutableSet.builder();
private ImmutableSet.Builder<String> groups = ImmutableSet.builder();
private ImmutableSet.Builder<String> users = ImmutableSet.builder();
public Builder(String groupname) {
this.groupname = groupname;
}
public Builder name(String name) {
this.name = checkNotNull(name, "name");
return this;
}
public Builder groupname(String groupname) {
this.groupname = checkNotNull(groupname, "groupname");
return this;
}
public Builder orgname(String orgname) {
this.orgname = checkNotNull(orgname, "orgname");
return this;
}
public Builder actor(String actor) {
this.actors.add(checkNotNull(actor, "actor"));
return this;
}
public Builder actors(Iterable<String> actors) {
this.actors.addAll(checkNotNull(actors, "actors"));
return this;
}
public Builder client(String client) {
this.clients.add(checkNotNull(client, "client"));
return this;
}
public Builder clients(Iterable<String> clients) {
this.clients.addAll(checkNotNull(clients, "clients"));
return this;
}
public Builder group(String group) {
this.groups.add(checkNotNull(group, "group"));
return this;
}
public Builder groups(Iterable<String> groups) {
this.groups.addAll(checkNotNull(groups, "groups"));
return this;
}
public Builder user(String user) {
this.users.add(checkNotNull(user, "user"));
return this;
}
public Builder users(Iterable<String> users) {
this.users.addAll(checkNotNull(users, "users"));
return this;
}
public Group build() {
return new Group(name, checkNotNull(groupname, "groupname"), orgname, actors.build(), clients.build(),
groups.build(), users.build());
}
}
private final String name;
private final String groupname;
private final String orgname;
private final Set<String> actors;
private final Set<String> clients;
private final Set<String> groups;
private final Set<String> users;
@ConstructorProperties({ "name", "groupname", "orgname", "actors", "clients", "groups", "users" })
public Group(String name, String groupname, String orgname, @Nullable Set<String> actors,
@Nullable Set<String> clients, @Nullable Set<String> groups, @Nullable Set<String> users) {
this.name = name;
this.groupname = groupname;
this.orgname = orgname;
this.actors = copyOfOrEmpty(actors);
this.clients = copyOfOrEmpty(clients);
this.groups = copyOfOrEmpty(groups);
this.users = copyOfOrEmpty(users);
}
public String getName() {
return name;
}
public String getGroupname() {
return groupname;
}
public String getOrgname() {
return orgname;
}
public Set<String> getActors() {
return actors;
}
public Set<String> getClients() {
return clients;
}
public Set<String> getGroups() {
return groups;
}
public Set<String> getUsers() {
return users;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (groupname == null ? 0 : groupname.hashCode());
result = prime * result + (name == null ? 0 : name.hashCode());
result = prime * result + (orgname == null ? 0 : orgname.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Group other = (Group) obj;
if (groupname == null) {
if (other.groupname != null) {
return false;
}
} else if (!groupname.equals(other.groupname)) {
return false;
}
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
if (orgname == null) {
if (other.orgname != null) {
return false;
}
} else if (!orgname.equals(other.orgname)) {
return false;
}
return true;
}
@Override
public String toString() {
return "Group [name=" + name + ", groupname=" + groupname + ", orgname=" + orgname + ", actors=" + actors
+ ", clients=" + clients + ", groups=" + groups + ", users=" + users + "]";
}
}

View File

@ -0,0 +1,220 @@
/*
* 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.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import java.security.PublicKey;
import com.google.gson.annotations.SerializedName;
/**
* User object.
*/
public class User {
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String username;
private String firstName;
private String middleName;
private String lastName;
private String displayName;
private String email;
private PublicKey publicKey;
public Builder username(String username) {
this.username = checkNotNull(username, "username");
return this;
}
public Builder firstName(String firstName) {
this.firstName = checkNotNull(firstName, "firstName");
return this;
}
public Builder middleName(String middleName) {
this.middleName = checkNotNull(middleName, "middleName");
return this;
}
public Builder lastName(String lastName) {
this.lastName = checkNotNull(lastName, "lastName");
return this;
}
public Builder displayName(String displayName) {
this.displayName = checkNotNull(displayName, "displayName");
return this;
}
public Builder email(String email) {
this.email = checkNotNull(email, "email");
return this;
}
public Builder publicKey(PublicKey publicKey) {
this.publicKey = checkNotNull(publicKey, "publicKey");
return this;
}
public User build() {
return new User(username, firstName, middleName, lastName, displayName, email, publicKey);
}
}
private final String username;
@SerializedName("first_name")
private final String firstName;
@SerializedName("middle_name")
private final String middleName;
@SerializedName("last_name")
private final String lastName;
@SerializedName("display_name")
private final String displayName;
private final String email;
@SerializedName("public_key")
private final PublicKey publicKey;
@ConstructorProperties({ "username", "first_name", "middle_name", "last_name", "display_name", "email", "public_key" })
protected User(String username, String firstName, String middleName, String lastName, String displayName,
String email, PublicKey publicKey) {
this.username = username;
this.firstName = firstName;
this.middleName = middleName;
this.lastName = lastName;
this.displayName = displayName;
this.email = email;
this.publicKey = publicKey;
}
public String getUsername() {
return username;
}
public String getFirstName() {
return firstName;
}
public String getMiddleName() {
return middleName;
}
public String getLastName() {
return lastName;
}
public String getDisplayName() {
return displayName;
}
public String getEmail() {
return email;
}
public PublicKey getPublicKey() {
return publicKey;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (displayName == null ? 0 : displayName.hashCode());
result = prime * result + (email == null ? 0 : email.hashCode());
result = prime * result + (firstName == null ? 0 : firstName.hashCode());
result = prime * result + (lastName == null ? 0 : lastName.hashCode());
result = prime * result + (middleName == null ? 0 : middleName.hashCode());
result = prime * result + (publicKey == null ? 0 : publicKey.hashCode());
result = prime * result + (username == null ? 0 : username.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
User other = (User) obj;
if (displayName == null) {
if (other.displayName != null) {
return false;
}
} else if (!displayName.equals(other.displayName)) {
return false;
}
if (email == null) {
if (other.email != null) {
return false;
}
} else if (!email.equals(other.email)) {
return false;
}
if (firstName == null) {
if (other.firstName != null) {
return false;
}
} else if (!firstName.equals(other.firstName)) {
return false;
}
if (lastName == null) {
if (other.lastName != null) {
return false;
}
} else if (!lastName.equals(other.lastName)) {
return false;
}
if (middleName == null) {
if (other.middleName != null) {
return false;
}
} else if (!middleName.equals(other.middleName)) {
return false;
}
if (publicKey == null) {
if (other.publicKey != null) {
return false;
}
} else if (!publicKey.equals(other.publicKey)) {
return false;
}
if (username == null) {
if (other.username != null) {
return false;
}
} else if (!username.equals(other.username)) {
return false;
}
return true;
}
@Override
public String toString() {
return "User [username=" + username + ", firstName=" + firstName + ", middleName=" + middleName + ", lastName="
+ lastName + ", displayName=" + displayName + ", email=" + email + ", publicKey=" + publicKey + "]";
}
}

View File

@ -0,0 +1 @@
org.jclouds.enterprisechef.EnterpriseChefProviderMetadata

View File

@ -0,0 +1,209 @@
/*
* 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 static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import java.util.Set;
import javax.ws.rs.core.MediaType;
import org.jclouds.chef.BaseChefApiExpectTest;
import org.jclouds.chef.ChefApiMetadata;
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.HttpResponse;
import org.jclouds.providers.ProviderMetadata;
import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.ResourceNotFoundException;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.inject.Module;
/**
* Expect tests for the {@link EnterpriseChefApi} class.
*/
@Test(groups = "unit", testName = "EnterpriseChefApiExpectTest")
public class EnterpriseChefApiExpectTest extends BaseChefApiExpectTest<EnterpriseChefApi> {
public EnterpriseChefApiExpectTest() {
provider = "enterprisechef";
}
public void testGetUserReturns2xx() {
EnterpriseChefApi api = requestSendsResponse(
signed(HttpRequest.builder() //
.method("GET") //
.endpoint("https://api.opscode.com/users/nacx") //
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
.addHeader("Accept", MediaType.APPLICATION_JSON).build()), //
HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/user.json", MediaType.APPLICATION_JSON)) //
.build());
User user = api.getUser("nacx");
assertEquals(user.getUsername(), "nacx");
assertEquals(user.getDisplayName(), "Ignasi Barrera");
}
public void testGetUserReturns404() {
EnterpriseChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
.method("GET") //
.endpoint("https://api.opscode.com/users/foo") //
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
.addHeader("Accept", MediaType.APPLICATION_JSON) //
.build()), //
HttpResponse.builder().statusCode(404).build());
assertNull(api.getUser("foo"));
}
public void testListGroups() {
EnterpriseChefApi api = requestSendsResponse(
signed(HttpRequest.builder() //
.method("GET") //
.endpoint("https://api.opscode.com/groups") //
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
.addHeader("Accept", MediaType.APPLICATION_JSON).build()), //
HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/groups.json", MediaType.APPLICATION_JSON)) //
.build());
Set<String> groups = api.listGroups();
assertEquals(groups.size(), 5);
assertTrue(groups.contains("admins"));
}
public void testGetGroupReturns2xx() {
EnterpriseChefApi api = requestSendsResponse(
signed(HttpRequest.builder() //
.method("GET") //
.endpoint("https://api.opscode.com/groups/admins") //
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
.addHeader("Accept", MediaType.APPLICATION_JSON).build()), //
HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/group.json", MediaType.APPLICATION_JSON)) //
.build());
Group group = api.getGroup("admins");
assertEquals(group.getName(), "admins");
assertEquals(group.getGroupname(), "admins");
}
public void testGetGroupReturns404() {
EnterpriseChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
.method("GET") //
.endpoint("https://api.opscode.com/groups/foo") //
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
.addHeader("Accept", MediaType.APPLICATION_JSON) //
.build()), //
HttpResponse.builder().statusCode(404).build());
assertNull(api.getGroup("foo"));
}
public void testCreateGroupReturns2xx() {
EnterpriseChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
.method("POST") //
.endpoint("https://api.opscode.com/groups") //
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
.addHeader("Accept", MediaType.APPLICATION_JSON) //
.payload(payloadFromStringWithContentType("{\"groupname\":\"foo\"}", MediaType.APPLICATION_JSON)) //
.build()), //
HttpResponse.builder().statusCode(201).build());
api.createGroup("foo");
}
public void testDeleteGroupReturns2xx() {
EnterpriseChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
.method("DELETE") //
.endpoint("https://api.opscode.com/groups/foo") //
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
.addHeader("Accept", MediaType.APPLICATION_JSON) //
.build()), //
HttpResponse.builder().statusCode(200).build());
api.deleteGroup("foo");
}
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testDeleteGroupFailsOn404() {
EnterpriseChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
.method("DELETE") //
.endpoint("https://api.opscode.com/groups/foo") //
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
.addHeader("Accept", MediaType.APPLICATION_JSON) //
.build()), //
HttpResponse.builder().statusCode(404).build());
api.deleteGroup("foo");
}
public void testUpdateGroupReturns2xx() {
EnterpriseChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
.method("PUT") //
.endpoint("https://api.opscode.com/groups/admins") //
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
.addHeader("Accept", MediaType.APPLICATION_JSON) //
.payload(payloadFromResourceWithContentType("/group-update.json", MediaType.APPLICATION_JSON)) //
.build()), //
HttpResponse.builder().statusCode(200).build());
Group group = Group.builder("admins").client("abiquo").group("admins").user("nacx").build();
api.updateGroup(group);
}
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testUpdateGroupFailsOn404() {
EnterpriseChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
.method("PUT") //
.endpoint("https://api.opscode.com/groups/admins") //
.addHeader("X-Chef-Version", ChefApiMetadata.DEFAULT_API_VERSION) //
.addHeader("Accept", MediaType.APPLICATION_JSON) //
.payload(payloadFromResourceWithContentType("/group-update.json", MediaType.APPLICATION_JSON)) //
.build()), //
HttpResponse.builder().statusCode(404).build());
Group group = Group.builder("admins").client("abiquo").group("admins").user("nacx").build();
api.updateGroup(group);
}
@Override
protected Module createModule() {
return new TestEnterpriseChefHttpApiModule();
}
@ConfiguresHttpApi
static class TestEnterpriseChefHttpApiModule extends EnterpriseChefHttpApiModule {
@Override
protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
return "timestamp";
}
}
@Override
protected ProviderMetadata createProviderMetadata() {
return new EnterpriseChefProviderMetadata();
}
}

View File

@ -0,0 +1,122 @@
/*
* 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 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 java.util.Set;
import java.util.UUID;
import org.jclouds.chef.internal.BaseChefApiLiveTest;
import org.jclouds.enterprisechef.domain.Group;
import org.jclouds.enterprisechef.domain.User;
import org.jclouds.rest.ResourceNotFoundException;
import org.testng.annotations.Test;
/**
* Tests behavior of the EnterpriseChefApi.
*/
@Test(groups = "live", singleThreaded = true, testName = "EnterpriseChefApiLiveTest")
public class EnterpriseChefApiLiveTest extends BaseChefApiLiveTest<EnterpriseChefApi> {
private static final String GROUP_NAME = System.getProperty("user.name") + "-jcloudstest";
private static final String ORG_NAME = System.getProperty("test.enterprisechef.org");
public EnterpriseChefApiLiveTest() {
provider = "enterprisechef";
}
@Override
@Test
public void testSearchClientsWithOptions() throws Exception {
// This test will fail because Enterprise Chef does not index client name.
// Once it is fixes, the test should succeed.
// See: http://tickets.opscode.com/browse/CHEF-2477
super.testSearchClientsWithOptions();
}
public void testGetUser() {
User user = api.getUser(identity);
assertEquals(user.getUsername(), identity);
assertNotNull(user.getPublicKey());
}
public void testGetUnexistingUser() {
User user = api.getUser(UUID.randomUUID().toString());
assertNull(user);
}
public void testListGroups() {
Set<String> groups = api.listGroups();
assertNotNull(groups);
assertFalse(groups.isEmpty());
}
public void testGetUnexistingGroup() {
Group group = api.getGroup(UUID.randomUUID().toString());
assertNull(group);
}
public void testCreateGroup() {
api.createGroup(GROUP_NAME);
Group group = api.getGroup(GROUP_NAME);
assertNotNull(group);
assertEquals(group.getGroupname(), GROUP_NAME);
}
@Test(dependsOnMethods = "testCreateGroup")
public void testUpdateGroup() {
Group group = api.getGroup(GROUP_NAME);
Group updated = Group.builder(group.getGroupname()) //
.actors(group.getActors()) //
.orgname(group.getOrgname()) //
.name(group.getName()) //
.groups(group.getGroups()) //
.client(ORG_NAME + "-validator") //
.user(identity) //
.build();
api.updateGroup(updated);
group = api.getGroup(GROUP_NAME);
assertNotNull(group);
assertTrue(group.getUsers().contains(identity));
assertTrue(group.getClients().contains(ORG_NAME + "-validator"));
}
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testUpdateUnexistingGroup() {
api.updateGroup(Group.builder(UUID.randomUUID().toString()).build());
}
@Test(dependsOnMethods = "testUpdateGroup")
public void testDeleteGroup() {
api.deleteGroup(GROUP_NAME);
Group group = api.getGroup(GROUP_NAME);
assertNull(group);
}
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testDeleteUnexistingGroup() {
api.deleteGroup(UUID.randomUUID().toString());
}
}

View File

@ -0,0 +1,31 @@
/*
* 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());
}
}

View File

@ -0,0 +1,82 @@
/*
* 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.binders;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.net.URI;
import org.jclouds.chef.ChefApiMetadata;
import org.jclouds.chef.config.ChefParserModule;
import org.jclouds.enterprisechef.domain.Group;
import org.jclouds.http.HttpRequest;
import org.jclouds.json.config.GsonModule;
import org.jclouds.rest.annotations.ApiVersion;
import org.jclouds.util.Strings2;
import org.testng.annotations.Test;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* Unit tests for the {@link BindGroupToUpdateRequestJsonPayload} class.
*/
@Test(groups = "unit", testName = "BindGroupToUpdateRequestJsonPayloadTest")
public class BindGroupToUpdateRequestJsonPayloadTest {
private Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(String.class).annotatedWith(ApiVersion.class).toInstance(ChefApiMetadata.DEFAULT_API_VERSION);
}
}, new ChefParserModule(), new GsonModule());
private BindGroupToUpdateRequestJsonPayload binder = injector.getInstance(BindGroupToUpdateRequestJsonPayload.class);
@Test(expectedExceptions = NullPointerException.class)
public void testInvalidNullInput() {
HttpRequest request = HttpRequest.builder().method("POST").endpoint(URI.create("http://localhost")).build();
binder.bindToRequest(request, null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testInvalidTypeInput() {
HttpRequest request = HttpRequest.builder().method("POST").endpoint(URI.create("http://localhost")).build();
binder.bindToRequest(request, new Object());
}
public void testBindOnlyName() throws IOException {
HttpRequest request = HttpRequest.builder().method("POST").endpoint(URI.create("http://localhost")).build();
HttpRequest newRequest = binder.bindToRequest(request, Group.builder("foo").build());
String payload = Strings2.toStringAndClose(newRequest.getPayload().getInput());
assertEquals(payload, "{\"groupname\":\"foo\",\"actors\":{\"clients\":[],\"groups\":[],\"users\":[]}}");
}
public void testBindNameAndLists() throws IOException {
Group group = Group.builder("foo").client("nacx-validator").group("admins").user("nacx").build();
HttpRequest request = HttpRequest.builder().method("POST").endpoint(URI.create("http://localhost")).build();
HttpRequest newRequest = binder.bindToRequest(request, group);
String payload = Strings2.toStringAndClose(newRequest.getPayload().getInput());
assertEquals(payload,
"{\"groupname\":\"foo\",\"actors\":{\"clients\":[\"nacx-validator\"],\"groups\":[\"admins\"],\"users\":[\"nacx\"]}}");
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.binders;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import org.jclouds.enterprisechef.domain.Group;
import org.testng.annotations.Test;
/**
* Unit tests for the {@link GroupName} class.
*/
@Test(groups = "unit", testName = "GroupNameTest")
public class GroupNameTest {
@Test(expectedExceptions = NullPointerException.class)
public void testInvalidNullInput() {
new GroupName().apply(null);
}
public void testApplyGroupName() throws IOException {
assertEquals(new GroupName().apply(Group.builder("foo").build()), "foo");
}
}

View File

@ -0,0 +1 @@
{"groupname":"admins","actors":{"clients":["abiquo"],"groups":["admins"],"users":["nacx"]}}

View File

@ -0,0 +1,14 @@
{
"actors" : [ "abiquo",
"nacx",
"pivotal"
],
"clients" : [ "abiquo" ],
"groupname" : "admins",
"groups" : [ "billing-admins" ],
"name" : "admins",
"orgname" : "nacx",
"users" : [ "nacx",
"pivotal"
]
}

View File

@ -0,0 +1,7 @@
{
"965f2db33d302ed4625d172e0bc36920" : "https://api.opscode.com/organizations/nacx/groups/965f2db33d302ed4625d172e0bc36920",
"admins" : "https://api.opscode.com/organizations/nacx/groups/admins",
"billing-admins" : "https://api.opscode.com/organizations/nacx/groups/billing-admins",
"clients" : "https://api.opscode.com/organizations/nacx/groups/clients",
"users" : "https://api.opscode.com/organizations/nacx/groups/users"
}

View File

@ -0,0 +1,9 @@
{
"display_name" : "Ignasi Barrera",
"email" : "myemail@enterprisechef.org",
"first_name" : "Ignasi",
"last_name" : "Barrera",
"middle_name" : "",
"public_key" : "-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAp0ytgXbPzqJwOOixn7bTa6VAiNvVIOn+yDPoWbyEfc0li93BHIwv\n01KW/mn55IXnSbMw86rdxisvwPHFfb7URuKuTzME6yrphBiancmNjushZZeBWb8j\nqJhnFIKbaaOqew0LZSyG9ycYODB/HDK/pWTV4Bd1OtLHBNFrnIf+r3HOjJsa4rmK\nWXgSQIQO7be/iRHysApV9tfVH8lo1ETnA08JTrQwDgo9St9YNbydb5V0CiLiQsOa\nIbY09buUK9lXthh/rrRVbGbSwQM6OYdXIEZTN2BFvQ0p5pH8AiTwFqb0ICO46a0S\njfGcXNjC/QfHljAPY3T5xyIOODM8afHCnwIDAQAB\n-----END RSA PUBLIC KEY-----\n",
"username" : "nacx"
}