Merge pull request #1353 from jclouds/iam-role-crud

Iam role crud
This commit is contained in:
Adrian Cole 2013-02-24 20:05:57 -08:00
commit 55925e4bf6
24 changed files with 1415 additions and 53 deletions

View File

@ -0,0 +1,32 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.aws.iam.features;
import org.jclouds.iam.features.RoleApiLiveTest;
import org.testng.annotations.Test;
/**
* @author Adrian Cole
*/
@Test(groups = "live", testName = "AWSRoleApiLiveTest")
public class AWSRoleApiLiveTest extends RoleApiLiveTest {
public AWSRoleApiLiveTest() {
provider = "aws-iam";
}
}

View File

@ -19,6 +19,7 @@
package org.jclouds.iam;
import org.jclouds.iam.domain.User;
import org.jclouds.iam.features.RoleApi;
import org.jclouds.iam.features.UserApi;
import org.jclouds.rest.annotations.Delegate;
@ -42,4 +43,10 @@ public interface IAMApi {
*/
@Delegate
UserApi getUserApi();
/**
* Provides synchronous access to Role features.
*/
@Delegate
RoleApi getRoleApi();
}

View File

@ -24,6 +24,7 @@ import javax.ws.rs.Path;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.iam.domain.User;
import org.jclouds.iam.features.RoleAsyncApi;
import org.jclouds.iam.features.UserAsyncApi;
import org.jclouds.iam.xml.UserHandler;
import org.jclouds.rest.annotations.Delegate;
@ -62,4 +63,10 @@ public interface IAMAsyncApi {
*/
@Delegate
UserAsyncApi getUserApi();
/**
* Provides asynchronous access to Role features.
*/
@Delegate
RoleAsyncApi getRoleApi();
}

View File

@ -25,6 +25,8 @@ import java.util.Map;
import org.jclouds.aws.config.FormSigningRestClientModule;
import org.jclouds.iam.IAMApi;
import org.jclouds.iam.IAMAsyncApi;
import org.jclouds.iam.features.RoleApi;
import org.jclouds.iam.features.RoleAsyncApi;
import org.jclouds.iam.features.UserApi;
import org.jclouds.iam.features.UserAsyncApi;
import org.jclouds.rest.ConfiguresRestClient;
@ -40,6 +42,7 @@ import com.google.common.collect.ImmutableMap;
public class IAMRestClientModule extends FormSigningRestClientModule<IAMApi, IAMAsyncApi> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
.put(UserApi.class, UserAsyncApi.class)
.put(RoleApi.class, RoleAsyncApi.class)
.build();
public IAMRestClientModule() {

View File

@ -0,0 +1,190 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.iam.domain;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Date;
import com.google.common.base.Objects;
/**
* @see <a href="http://docs.amazonwebservices.com/IAM/latest/APIReference/API_GetRole.html" />
*
* @author Adrian Cole
*/
public final class Role {
private final String arn;
private final String id;
private final String name;
private final String path;
private final Date createDate;
private final String assumeRolePolicy;
private Role(String arn, String id, String name, String path, Date createDate, String assumeRolePolicy) {
this.arn = checkNotNull(arn, "arn");
this.id = checkNotNull(id, "id for %s", arn);
this.name = checkNotNull(name, "name for %s", arn);
this.path = checkNotNull(path, "path for %s", arn);
this.createDate = checkNotNull(createDate, "createDate for %s", arn);
this.assumeRolePolicy = checkNotNull(assumeRolePolicy, "assumeRolePolicy for %s",
assumeRolePolicy);
}
/**
* how to specify the resource in the access policy language ex.
* {@code arn:aws:<service>:<region>:<namespace>:<relative-id>}
*/
public String getArn() {
return arn;
}
/**
* a globally unique identifier (GUID), returned from the api.
*/
public String getId() {
return id;
}
/**
* friendly name ex. {@code Developers}
*/
public String getName() {
return name;
}
/**
* path ex {@code /division_abc/subdivision_xyz/product_1234/engineering/}
*/
public String getPath() {
return path;
}
/**
* Date the role was created
*/
public Date getCreateDate() {
return createDate;
}
/**
* The policy that grants an entity permission to assume the role.
*/
public String getAssumeRolePolicy() {
return assumeRolePolicy;
}
@Override
public int hashCode() {
return Objects.hashCode(arn, id);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
Role that = Role.class.cast(obj);
return equal(this.arn, that.arn) && equal(this.id, that.id);
}
@Override
public String toString() {
return toStringHelper(this).add("arn", arn).add("id", id).add("name", name).add("path", path)
.add("createDate", createDate).add("assumeRolePolicy", assumeRolePolicy).toString();
}
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return builder().from(this);
}
public static class Builder {
private String arn;
private String id;
private String name;
private String path;
private Date createDate;
private String assumeRolePolicy;
/**
* @see Role#getArn()
*/
public Builder arn(String arn) {
this.arn = arn;
return this;
}
/**
* @see Role#getId()
*/
public Builder id(String id) {
this.id = id;
return this;
}
/**
* @see Role#getName()
*/
public Builder name(String name) {
this.name = name;
return this;
}
/**
* @see Role#getPath()
*/
public Builder path(String path) {
this.path = path;
return this;
}
/**
* @see Role#getCreateDate()
*/
public Builder createDate(Date createDate) {
this.createDate = createDate;
return this;
}
/**
* @see Role#getAssumeRolePolicy()
*/
public Builder assumeRolePolicy(String assumeRolePolicy) {
this.assumeRolePolicy = assumeRolePolicy;
return this;
}
public Role build() {
return new Role(arn, id, name, path, createDate, assumeRolePolicy);
}
public Builder from(Role in) {
return arn(in.arn).id(in.id).name(in.name).path(in.path).createDate(in.createDate)
.assumeRolePolicy(in.assumeRolePolicy);
}
}
}

View File

@ -18,6 +18,8 @@
*/
package org.jclouds.iam.domain;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Date;
@ -32,27 +34,20 @@ import com.google.common.base.Optional;
*/
public final class User {
private final Optional<String> path;
private final Optional<String> name;
private final String id;
private final String arn;
private final String id;
private final Optional<String> name;
private final Optional<String> path;
private final Date createDate;
private User(String id, String arn, Optional<String> path, Optional<String> name, Date createDate) {
this.id = checkNotNull(id, "id");
this.arn = checkNotNull(arn, "arn for %s", id);
this.path = checkNotNull(path, "path for %s", arn);
private User(String arn, String id, Optional<String> name, Optional<String> path, Date createDate) {
this.arn = checkNotNull(arn, "arn");
this.id = checkNotNull(id, "id for %s", arn);
this.name = checkNotNull(name, "name for %s", arn);
this.path = checkNotNull(path, "path for %s", arn);
this.createDate = checkNotNull(createDate, "createDate for %s", arn);
}
/**
* a globally unique identifier (GUID), returned from the api.
*/
public String getId() {
return id;
}
/**
* how to specify the resource in the access policy language ex.
* {@code arn:aws:<service>:<region>:<namespace>:<relative-id>}
@ -62,10 +57,10 @@ public final class User {
}
/**
* path ex {@code /division_abc/subdivision_xyz/product_1234/engineering/}
* a globally unique identifier (GUID), returned from the api.
*/
public Optional<String> getPath() {
return path;
public String getId() {
return id;
}
/**
@ -75,6 +70,13 @@ public final class User {
return name;
}
/**
* path ex {@code /division_abc/subdivision_xyz/product_1234/engineering/}
*/
public Optional<String> getPath() {
return path;
}
/**
* Date the user was created
*/
@ -82,34 +84,25 @@ public final class User {
return createDate;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return Objects.hashCode(id, arn);
return Objects.hashCode(arn, id);
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
User other = (User) obj;
return Objects.equal(this.id, other.id) && Objects.equal(this.arn, other.arn);
User that = User.class.cast(obj);
return equal(this.arn, that.arn) && equal(this.id, that.id);
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return Objects.toStringHelper(this).add("path", path).add("name", name).add("id", id).add("arn", arn)
.add("createDate", createDate).toString();
return toStringHelper(this).omitNullValues().add("arn", arn).add("id", id).add("name", name.orNull())
.add("path", path.orNull()).add("createDate", createDate).toString();
}
public static Builder builder() {
@ -121,17 +114,17 @@ public final class User {
}
public static class Builder {
private Optional<String> path = Optional.absent();
private String arn;
private String id;
private Optional<String> name = Optional.absent();
private String arn;
private Optional<String> path = Optional.absent();
private Date createDate;
/**
* @see User#getPath()
* @see User#getArn()
*/
public Builder path(String path) {
this.path = Optional.fromNullable(path);
public Builder arn(String arn) {
this.arn = arn;
return this;
}
@ -152,10 +145,10 @@ public final class User {
}
/**
* @see User#getArn()
* @see User#getPath()
*/
public Builder arn(String arn) {
this.arn = arn;
public Builder path(String path) {
this.path = Optional.fromNullable(path);
return this;
}
@ -168,11 +161,11 @@ public final class User {
}
public User build() {
return new User(id, arn, path, name, createDate);
return new User(arn, id, name, path, createDate);
}
public Builder from(User in) {
return this.path(in.path.orNull()).name(in.name.orNull()).id(in.id).arn(in.arn).createDate(in.createDate);
return arn(in.arn).id(in.id).name(in.name.orNull()).path(in.path.orNull()).createDate(in.createDate);
}
}
}

View File

@ -0,0 +1,109 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.iam.features;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.PagedIterable;
import org.jclouds.iam.domain.Role;
import org.jclouds.javax.annotation.Nullable;
/**
* @see RoleAsyncApi
* @author Adrian Cole
*/
public interface RoleApi {
/**
* Creates a new role for your AWS account
*
* @param name
* Name of the role to create.
* @param assumeRolePolicy
* The policy that grants an entity permission to assume the role.}
* @return the new role
*/
Role createWithPolicy(String name, String assumeRolePolicy);
/**
* like {@link #createWithPolicy(String, String)}, except you can specify a path.
*/
Role createWithPolicyAndPath(String name, String assumeRolePolicy, String path);
/**
* returns all roles in order.
*/
PagedIterable<Role> list();
/**
* retrieves up to 100 roles in order.
*/
IterableWithMarker<Role> listFirstPage();
/**
* retrieves up to 100 roles in order, starting at {@code marker}
*
* @param marker
* starting point to resume the list
*/
IterableWithMarker<Role> listAt(String marker);
/**
* returns all roles in order at the specified {@code pathPrefix}.
*
* @param pathPrefix
* ex. {@code /division_abc/subdivision_xyz/}
*/
PagedIterable<Role> listPathPrefix(String pathPrefix);
/**
* retrieves up to 100 roles in order at the specified {@code pathPrefix}.
*
* @param pathPrefix
* ex. {@code /division_abc/subdivision_xyz/}
*/
IterableWithMarker<Role> listPathPrefixFirstPage(String pathPrefix);
/**
* retrieves up to 100 roles in order at the specified {@code pathPrefix}, starting at {@code marker}.
*
* @param pathPrefix
* ex. {@code /division_abc/subdivision_xyz/}
* @param marker
* starting point to resume the list
*/
IterableWithMarker<Role> listPathPrefixAt(String pathPrefix, String marker);
/**
* Retrieves information about the specified role, including the role's path, GUID, and ARN.
*
* @param name
* Name of the role to get information about.
* @return null if not found
*/
@Nullable
Role get(String name);
/**
* Deletes the specified role. The role must not have any policies attached.
*
* @param name
* Name of the role to delete
*/
void delete(String name);
}

View File

@ -0,0 +1,159 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.iam.features;
import javax.inject.Named;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.PagedIterable;
import org.jclouds.iam.domain.Role;
import org.jclouds.iam.functions.RolesToPagedIterable;
import org.jclouds.iam.xml.ListRolesResultHandler;
import org.jclouds.iam.xml.RoleHandler;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides access to Amazon IAM via the Query API
* <p/>
*
* @see <a href="http://docs.amazonwebservices.com/IAM/latest/APIReference" />
* @author Adrian Cole
*/
@RequestFilters(FormSigner.class)
@VirtualHost
public interface RoleAsyncApi {
/**
* @see RoleApi#createWithPolicy
*/
@Named("CreateRole")
@POST
@Path("/")
@FormParams(keys = "Action", values = "CreateRole")
@XMLResponseParser(RoleHandler.class)
ListenableFuture<Role> createWithPolicy(@FormParam("RoleName") String name,
@FormParam("AssumeRolePolicyDocument") String assumeRolePolicy);
/**
* @see RoleApi#createWithPolicyAndPath
*/
@Named("CreateRole")
@POST
@Path("/")
@FormParams(keys = "Action", values = "CreateRole")
@XMLResponseParser(RoleHandler.class)
ListenableFuture<Role> createWithPolicyAndPath(@FormParam("RoleName") String name,
@FormParam("AssumeRolePolicyDocument") String assumeRolePolicy, @FormParam("Path") String path);
/**
* @see RoleApi#list()
*/
@Named("ListRoles")
@POST
@Path("/")
@FormParams(keys = "Action", values = "ListRoles")
@XMLResponseParser(ListRolesResultHandler.class)
@Transform(RolesToPagedIterable.class)
ListenableFuture<PagedIterable<Role>> list();
/**
* @see RoleApi#listFirstPage
*/
@Named("ListRoles")
@POST
@Path("/")
@FormParams(keys = "Action", values = "ListRoles")
@XMLResponseParser(ListRolesResultHandler.class)
ListenableFuture<IterableWithMarker<Role>> listFirstPage();
/**
* @see RoleApi#listAt(String)
*/
@Named("ListRoles")
@POST
@Path("/")
@FormParams(keys = "Action", values = "ListRoles")
@XMLResponseParser(ListRolesResultHandler.class)
ListenableFuture<IterableWithMarker<Role>> listAt(@FormParam("Marker") String marker);
/**
* @see RoleApi#listPathPrefix(String)
*/
@Named("ListRoles")
@POST
@Path("/")
@FormParams(keys = "Action", values = "ListRoles")
@XMLResponseParser(ListRolesResultHandler.class)
@Transform(RolesToPagedIterable.class)
ListenableFuture<PagedIterable<Role>> listPathPrefix(@FormParam("PathPrefix") String pathPrefix);
/**
* @see RoleApi#listPathPrefixFirstPage(String)
*/
@Named("ListRoles")
@POST
@Path("/")
@FormParams(keys = "Action", values = "ListRoles")
@XMLResponseParser(ListRolesResultHandler.class)
ListenableFuture<IterableWithMarker<Role>> listPathPrefixFirstPage(@FormParam("PathPrefix") String pathPrefix);
/**
* @see RoleApi#listPathPrefixAt(String, String)
*/
@Named("ListRoles")
@POST
@Path("/")
@FormParams(keys = "Action", values = "ListRoles")
@XMLResponseParser(ListRolesResultHandler.class)
ListenableFuture<IterableWithMarker<Role>> listPathPrefixAt(@FormParam("PathPrefix") String pathPrefix,
@FormParam("Marker") String marker);
/**
* @see RoleApi#get()
*/
@Named("GetRole")
@POST
@Path("/")
@XMLResponseParser(RoleHandler.class)
@FormParams(keys = "Action", values = "GetRole")
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Role> get(@FormParam("RoleName") String name);
/**
* @see RoleApi#delete()
*/
@Named("DeleteRole")
@POST
@Path("/")
@FormParams(keys = "Action", values = "DeleteRole")
@Fallback(VoidOnNotFoundOr404.class)
ListenableFuture<Void> delete(@FormParam("RoleName") String name);
}

View File

@ -24,10 +24,8 @@ import org.jclouds.iam.domain.User;
import org.jclouds.javax.annotation.Nullable;
/**
* Provides access to Amazon IAM via the Query API
* <p/>
*
* @see <a href="http://docs.amazonwebservices.com/IAM/latest/APIReference" />
* @see UserAsyncApi
* @author Adrian Cole
*/
public interface UserApi {

View File

@ -0,0 +1,90 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.iam.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Inject;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.internal.Arg0ToPagedIterable;
import org.jclouds.iam.IAMApi;
import org.jclouds.iam.domain.Role;
import org.jclouds.iam.features.RoleApi;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.base.Optional;
/**
* @author Adrian Cole
*/
@Beta
public class RolesToPagedIterable extends Arg0ToPagedIterable<Role, RolesToPagedIterable> {
private final RoleApi api;
@Inject
protected RolesToPagedIterable(IAMApi api) {
this.api = checkNotNull(api, "api").getRoleApi();
}
@Override
protected Function<Object, IterableWithMarker<Role>> markerToNextForArg0(Optional<Object> pathPrefix) {
if (pathPrefix.isPresent())
return new ListRolesUnderPathPrefixAtMarker(api, pathPrefix.get().toString());
return new ListRolesAtMarker(api);
}
private static class ListRolesUnderPathPrefixAtMarker implements Function<Object, IterableWithMarker<Role>> {
private final RoleApi api;
private final String pathPrefix;
@Inject
protected ListRolesUnderPathPrefixAtMarker(RoleApi api, String pathPrefix) {
this.api = checkNotNull(api, "api");
this.pathPrefix = checkNotNull(pathPrefix, "pathPrefix");
}
public IterableWithMarker<Role> apply(Object input) {
return api.listPathPrefixAt(pathPrefix, input.toString());
}
public String toString() {
return "ListRolesUnderPathPrefixAtMarker(" + pathPrefix + ")";
}
}
private static class ListRolesAtMarker implements Function<Object, IterableWithMarker<Role>> {
private final RoleApi api;
@Inject
protected ListRolesAtMarker(RoleApi api) {
this.api = checkNotNull(api, "api");
}
public IterableWithMarker<Role> apply(Object input) {
return api.listAt(input.toString());
}
public String toString() {
return "listRolesAtMarker()";
}
}
}

View File

@ -0,0 +1,97 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.iam.xml;
import static org.jclouds.util.SaxUtils.currentOrNull;
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.IterableWithMarkers;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.iam.domain.Role;
import org.xml.sax.Attributes;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.inject.Inject;
/**
* @see <a href="http://docs.aws.amazon.com/IAM/latest/APIReference/API_ListRoles.html" />
*
* @author Adrian Cole
*/
public class ListRolesResultHandler extends ParseSax.HandlerForGeneratedRequestWithResult<IterableWithMarker<Role>> {
private final RoleHandler roleHandler;
private StringBuilder currentText = new StringBuilder();
private Builder<Role> roles = ImmutableList.<Role> builder();
private boolean inRoles;
private String afterMarker;
@Inject
public ListRolesResultHandler(RoleHandler roleHandler) {
this.roleHandler = roleHandler;
}
@Override
public IterableWithMarker<Role> getResult() {
try {
return IterableWithMarkers.from(roles.build(), afterMarker);
} finally {
roles = ImmutableList.<Role> builder();
}
}
@Override
public void startElement(String url, String name, String qName, Attributes attributes) {
if (equalsOrSuffix(qName, "Roles")) {
inRoles = true;
}
if (inRoles) {
roleHandler.startElement(url, name, qName, attributes);
}
}
@Override
public void endElement(String uri, String name, String qName) {
if (inRoles) {
if (qName.equals("Roles")) {
inRoles = false;
} else if (qName.equals("member")) {
roles.add(roleHandler.getResult());
} else {
roleHandler.endElement(uri, name, qName);
}
} else if (qName.equals("Marker")) {
afterMarker = currentOrNull(currentText);
}
currentText = new StringBuilder();
}
@Override
public void characters(char ch[], int start, int length) {
if (inRoles) {
roleHandler.characters(ch, start, length);
} else {
currentText.append(ch, start, length);
}
}
}

View File

@ -0,0 +1,87 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.iam.xml;
import static org.jclouds.util.SaxUtils.currentOrNull;
import static org.jclouds.util.Strings2.urlDecode;
import javax.inject.Inject;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.iam.domain.Role;
import org.xml.sax.Attributes;
/**
* @see <a href="http://docs.aws.amazon.com/IAM/latest/APIReference/API_GetRole.html" />
*
* @author Adrian Cole
*/
public class RoleHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Role> {
private final DateService dateService;
@Inject
protected RoleHandler(DateService dateService) {
this.dateService = dateService;
}
private StringBuilder currentText = new StringBuilder();
private Role.Builder builder = Role.builder();
@Override
public Role getResult() {
try {
return builder.build();
} finally {
builder = Role.builder();
}
}
@Override
public void startElement(String url, String name, String qName, Attributes attributes) {
}
@Override
public void endElement(String uri, String name, String qName) {
if (qName.equals("Path")) {
builder.path(currentOrNull(currentText));
} else if (qName.equals("RoleName")) {
builder.name(currentOrNull(currentText));
} else if (qName.equals("RoleId")) {
builder.id(currentOrNull(currentText));
} else if (qName.equals("Arn")) {
builder.arn(currentOrNull(currentText));
} else if (qName.equals("AssumeRolePolicyDocument")) {
builder.assumeRolePolicy(urlDecode(currentOrNull(currentText)));
} else if (qName.equals("CreateDate")) {
try {
builder.createDate(dateService.iso8601SecondsDateParse(currentOrNull(currentText)));
} catch (IllegalArgumentException e) {
// on create, milliseconds are present
builder.createDate(dateService.iso8601DateParse(currentOrNull(currentText)));
}
}
currentText = new StringBuilder();
}
@Override
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
}

View File

@ -0,0 +1,272 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unles 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 expres or implied. See the License for the
* specific language governing permisions and limitations
* under the License.
*/
package org.jclouds.iam.features;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.iam.IAMApi;
import org.jclouds.iam.internal.BaseIAMApiExpectTest;
import org.jclouds.iam.parse.GetRoleResponseTest;
import org.jclouds.iam.parse.ListRolesResponseTest;
import org.jclouds.rest.ResourceNotFoundException;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
/**
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "RoleApiExpectTest")
public class RoleApiExpectTest extends BaseIAMApiExpectTest {
String policy = "{\"Version\":\"2008-10-17\",\"Statement\":[{\"Sid\":\"\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"ec2.amazonaws.com\"},\"Action\":\"sts:AssumeRole\"}]}";
HttpRequest create = HttpRequest.builder()
.method("POST")
.endpoint("https://iam.amazonaws.com/")
.addHeader("Host", "iam.amazonaws.com")
.addFormParam("Action", "CreateRole")
.addFormParam("AssumeRolePolicyDocument", policy)
.addFormParam("RoleName", "name")
.addFormParam("Signature", "zl7UtZElpvnkjo81NmA%2BCvYu0xFEeXQlSRtqTgok2OU%3D")
.addFormParam("SignatureMethod", "HmacSHA256")
.addFormParam("SignatureVersion", "2")
.addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z")
.addFormParam("Version", "2010-05-08")
.addFormParam("AWSAccessKeyId", "identity").build();
public void testCreateWhenResponseIs2xx() throws Exception {
HttpResponse getResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/get_role.xml", "text/xml")).build();
IAMApi apiWhenExist = requestSendsResponse(create, getResponse);
assertEquals(apiWhenExist.getRoleApi().createWithPolicy("name", policy).toString(), new GetRoleResponseTest().expected().toString());
}
HttpRequest get = HttpRequest.builder()
.method("POST")
.endpoint("https://iam.amazonaws.com/")
.addHeader("Host", "iam.amazonaws.com")
.addFormParam("Action", "GetRole")
.addFormParam("RoleName", "name")
.addFormParam("Signature", "OhV4oxbGMEJtWEDOUhR5n4u5TfGT9YtX/nVXHRyxDrs%3D")
.addFormParam("SignatureMethod", "HmacSHA256")
.addFormParam("SignatureVersion", "2")
.addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z")
.addFormParam("Version", "2010-05-08")
.addFormParam("AWSAccessKeyId", "identity").build();
public void testGetWhenResponseIs2xx() throws Exception {
HttpResponse getResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/get_role.xml", "text/xml")).build();
IAMApi apiWhenExist = requestSendsResponse(
get, getResponse);
assertEquals(apiWhenExist.getRoleApi().get("name").toString(), new GetRoleResponseTest().expected().toString());
}
public void testGetWhenResponseIs404() throws Exception {
HttpResponse getResponse = HttpResponse.builder().statusCode(404).build();
IAMApi apiWhenDontExist = requestSendsResponse(
get, getResponse);
assertNull(apiWhenDontExist.getRoleApi().get("name"));
}
HttpRequest delete = HttpRequest.builder()
.method("POST")
.endpoint("https://iam.amazonaws.com/")
.addHeader("Host", "iam.amazonaws.com")
.addFormParam("Action", "DeleteRole")
.addFormParam("RoleName", "name")
.addFormParam("Signature", "yhONyyLjFFtLgearEBrBNpSGTafh35LvRaaK8VagOVA%3D")
.addFormParam("SignatureMethod", "HmacSHA256")
.addFormParam("SignatureVersion", "2")
.addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z")
.addFormParam("Version", "2010-05-08")
.addFormParam("AWSAccessKeyId", "identity").build();
public void testDeleteWhenResponseIs2xx() throws Exception {
HttpResponse deleteResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/delete_role.xml", "text/xml")).build();
IAMApi apiWhenExist = requestSendsResponse(delete, deleteResponse);
apiWhenExist.getRoleApi().delete("name");
}
public void testDeleteWhenResponseIs404() throws Exception {
HttpResponse deleteResponse = HttpResponse.builder().statusCode(404).build();
IAMApi apiWhenDontExist = requestSendsResponse(delete, deleteResponse);
apiWhenDontExist.getRoleApi().delete("name");
}
HttpRequest list = HttpRequest.builder()
.method("POST")
.endpoint("https://iam.amazonaws.com/")
.addHeader("Host", "iam.amazonaws.com")
.addFormParam("Action", "ListRoles")
.addFormParam("Signature", "aUfKE6CqT%2BAiRMmcRWmGrw/6wNpzrKCwd35UufAVEbs%3D")
.addFormParam("SignatureMethod", "HmacSHA256")
.addFormParam("SignatureVersion", "2")
.addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z")
.addFormParam("Version", "2010-05-08")
.addFormParam("AWSAccessKeyId", "identity").build();
public void testListWhenResponseIs2xx() throws Exception {
HttpResponse listResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/list_roles.xml", "text/xml")).build();
IAMApi apiWhenExist = requestSendsResponse(
list, listResponse);
assertEquals(apiWhenExist.getRoleApi().list().get(0).toString(), new ListRolesResponseTest().expected().toString());
}
public void testList2PagesWhenResponseIs2xx() throws Exception {
HttpResponse listResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/list_roles_marker.xml", "text/xml")).build();
HttpRequest list2 = HttpRequest.builder()
.method("POST")
.endpoint("https://iam.amazonaws.com/")
.addHeader("Host", "iam.amazonaws.com")
.addFormParam("Action", "ListRoles")
.addFormParam("Marker", "MARKER")
.addFormParam("Signature", "gOfxvq54UyrEck9AmMy4tm5zcNlRWwWtLBzGpKASskk%3D")
.addFormParam("SignatureMethod", "HmacSHA256")
.addFormParam("SignatureVersion", "2")
.addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z")
.addFormParam("Version", "2010-05-08")
.addFormParam("AWSAccessKeyId", "identity").build();
HttpResponse list2Response = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/list_roles.xml", "text/xml")).build();
IAMApi apiWhenExist = requestsSendResponses(list, listResponse, list2, list2Response);
assertEquals(apiWhenExist.getRoleApi().list().concat().toList(),
ImmutableList.copyOf(Iterables.concat(new ListRolesResponseTest().expected(), new ListRolesResponseTest().expected())));
}
HttpRequest listPathPrefix = HttpRequest.builder()
.method("POST")
.endpoint("https://iam.amazonaws.com/")
.addHeader("Host", "iam.amazonaws.com")
.addFormParam("Action", "ListRoles")
.addFormParam("PathPrefix", "/subdivision")
.addFormParam("Signature", "ELuhOLquxfQw5pv9381CBuUfqiXv5FHl836m31HA2BI%3D")
.addFormParam("SignatureMethod", "HmacSHA256")
.addFormParam("SignatureVersion", "2")
.addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z")
.addFormParam("Version", "2010-05-08")
.addFormParam("AWSAccessKeyId", "identity").build();
public void testListPathPrefixWhenResponseIs2xx() throws Exception {
HttpResponse listResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/list_roles.xml", "text/xml")).build();
IAMApi apiWhenExist = requestSendsResponse(
listPathPrefix, listResponse);
assertEquals(apiWhenExist.getRoleApi().listPathPrefix("/subdivision").get(0).toString(), new ListRolesResponseTest().expected().toString());
}
public void testListPathPrefix2PagesWhenResponseIs2xx() throws Exception {
HttpResponse listResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/list_roles_marker.xml", "text/xml")).build();
HttpRequest listPathPrefix2 = HttpRequest.builder()
.method("POST")
.endpoint("https://iam.amazonaws.com/")
.addHeader("Host", "iam.amazonaws.com")
.addFormParam("Action", "ListRoles")
.addFormParam("Marker", "MARKER")
.addFormParam("PathPrefix", "/subdivision")
.addFormParam("Signature", "Y05M4vbhJpd35erXuhECszxjtx56cdIULGHnRaVr13s%3D")
.addFormParam("SignatureMethod", "HmacSHA256")
.addFormParam("SignatureVersion", "2")
.addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z")
.addFormParam("Version", "2010-05-08")
.addFormParam("AWSAccessKeyId", "identity").build();
HttpResponse list2Response = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/list_roles.xml", "text/xml")).build();
IAMApi apiWhenExist = requestsSendResponses(listPathPrefix, listResponse, listPathPrefix2, list2Response);
assertEquals(apiWhenExist.getRoleApi().listPathPrefix("/subdivision").concat().toList(),
ImmutableList.copyOf(Iterables.concat(new ListRolesResponseTest().expected(), new ListRolesResponseTest().expected())));
}
// TODO: this should really be an empty set
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testListWhenResponseIs404() throws Exception {
HttpResponse listResponse = HttpResponse.builder().statusCode(404).build();
IAMApi apiWhenDontExist = requestSendsResponse(
list, listResponse);
apiWhenDontExist.getRoleApi().list().get(0);
}
public void testListPathPrefixAtWhenResponseIs2xx() throws Exception {
HttpRequest listWithOptions =
HttpRequest.builder()
.method("POST")
.endpoint("https://iam.amazonaws.com/")
.addHeader("Host", "iam.amazonaws.com")
.addFormParam("Action", "ListRoles")
.addFormParam("Marker", "MARKER")
.addFormParam("PathPrefix", "/foo")
.addFormParam("Signature", "HUXPIey7u7ajfog4wFgJn59fcFWpMSjd5yjomenL7jc%3D")
.addFormParam("SignatureMethod", "HmacSHA256")
.addFormParam("SignatureVersion", "2")
.addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z")
.addFormParam("Version", "2010-05-08")
.addFormParam("AWSAccessKeyId", "identity").build();
HttpResponse listWithOptionsResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/list_roles.xml", "text/xml")).build();
IAMApi apiWhenWithOptionsExist = requestSendsResponse(listWithOptions,
listWithOptionsResponse);
assertEquals(apiWhenWithOptionsExist.getRoleApi().listPathPrefixAt("/foo", "MARKER").toString(),
new ListRolesResponseTest().expected().toString());
}
}

View File

@ -0,0 +1,91 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.iam.features;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.logging.Logger.getAnonymousLogger;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import org.jclouds.iam.domain.Role;
import org.jclouds.iam.internal.BaseIAMApiLiveTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
/**
* @author Adrian Cole
*/
@Test(groups = "live", testName = "RoleApiLiveTest")
public class RoleApiLiveTest extends BaseIAMApiLiveTest {
private void checkRole(Role role) {
checkNotNull(role.getArn(), "Arn cannot be null for Role %s", role);
checkNotNull(role.getId(), "Id cannot be null for Role %s", role);
checkNotNull(role.getName(), "Name cannot be null for Role %s", role);
checkNotNull(role.getPath(), "Path cannot be null for Role %s", role);
checkNotNull(role.getAssumeRolePolicy(), "AssumeRolePolicy cannot be null for Role %s", role);
checkNotNull(role.getCreateDate(), "CreateDate cannot be null for a Role Role %s", role);
}
@Test
protected void testListRoles() {
ImmutableList<Role> roles = api().list().concat().toList();
getAnonymousLogger().info("roles: " + roles.size());
for (Role role : roles) {
checkRole(role);
assertEquals(api().get(role.getName()), role);
ImmutableSet<Role> rolesAtPath = api().listPathPrefix(role.getPath()).concat().toSet();
assertTrue(rolesAtPath.contains(role), role + " not in " + rolesAtPath);
}
}
@Test
public void testGetRoleWhenNotFound() {
assertNull(api().get("AAAAAAAAAAAAAAAA"));
}
@Test
public void testDeleteRoleWhenNotFound() {
api().delete("AAAAAAAAAAAAAAAA");
}
String policy = "{\"Version\":\"2008-10-17\",\"Statement\":[{\"Sid\":\"\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"ec2.amazonaws.com\"},\"Action\":\"sts:AssumeRole\"}]}";
@Test
public void testCreateAndDeleteRole() {
String name = System.getProperty("user.name").replace('.', '-') + ".role.iamtest.jclouds.org.";
Role newRole;
try {
newRole = api().createWithPolicy(name, policy);
getAnonymousLogger().info("created role: " + newRole);
checkRole(newRole);
} finally {
api().delete(name);
assertNull(api().get(name));
}
}
protected RoleApi api() {
return context.getApi().getRoleApi();
}
}

View File

@ -21,8 +21,6 @@ package org.jclouds.iam.features;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import java.util.TimeZone;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.iam.IAMApi;
@ -41,10 +39,6 @@ import com.google.common.collect.Iterables;
@Test(groups = "unit", testName = "UserApiExpectTest")
public class UserApiExpectTest extends BaseIAMApiExpectTest {
public UserApiExpectTest() {
TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
}
public void testGetCurrentWhenResponseIs2xx() throws Exception {
HttpRequest get = HttpRequest.builder()
.method("POST")

View File

@ -21,6 +21,7 @@ package org.jclouds.iam.features;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.logging.Logger.getAnonymousLogger;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import org.jclouds.iam.domain.User;
import org.jclouds.iam.internal.BaseIAMApiLiveTest;
@ -57,8 +58,10 @@ public class UserApiLiveTest extends BaseIAMApiLiveTest {
for (User user : users) {
checkUser(user);
assertEquals(api().get(user.getId()), user);
if (user.getPath().isPresent())
assertEquals(api().listPathPrefix(user.getPath().get()).toSet(), ImmutableSet.of(user));
if (user.getPath().isPresent()) {
ImmutableSet<User> usersAtPath = api().listPathPrefix(user.getPath().get()).concat().toSet();
assertTrue(usersAtPath.contains(user), user + " not in " + usersAtPath);
}
}
}

View File

@ -18,6 +18,8 @@
*/
package org.jclouds.iam.internal;
import java.util.TimeZone;
import org.jclouds.date.DateService;
import org.jclouds.iam.config.IAMRestClientModule;
import org.jclouds.rest.ConfiguresRestClient;
@ -33,6 +35,7 @@ public class BaseIAMExpectTest<T> extends BaseRestApiExpectTest<T> {
public BaseIAMExpectTest() {
provider = "iam";
TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
}
@ConfiguresRestClient

View File

@ -0,0 +1,63 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.iam.parse;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.iam.domain.Role;
import org.jclouds.iam.xml.RoleHandler;
import org.testng.annotations.Test;
/**
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "GetRoleResponseTest")
public class GetRoleResponseTest extends BaseHandlerTest {
public void test() {
InputStream is = getClass().getResourceAsStream("/get_role.xml");
Role expected = expected();
RoleHandler handler = injector.getInstance(RoleHandler.class);
Role result = factory.create(handler).parse(is);
assertEquals(result, expected);
assertEquals(result.getPath(), expected.getPath());
assertEquals(result.getName(), expected.getName());
assertEquals(result.getCreateDate(), expected.getCreateDate());
assertEquals(result.getAssumeRolePolicy(), expected.getAssumeRolePolicy());
}
public Role expected() {
return Role.builder()
.arn("arn:aws:iam::993194456877:role/foobie")
.id("AROAIBFDQ5TQHEMPBEUE4")
.name("foobie")
.path("/")
.assumeRolePolicy("{\"Version\":\"2008-10-17\",\"Statement\":[{\"Sid\":\"\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"ec2.amazonaws.com\"},\"Action\":\"sts:AssumeRole\"}]}")
.createDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2013-02-25T01:51:35Z")).build();
}
}

View File

@ -0,0 +1,72 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.iam.parse;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.IterableWithMarkers;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.iam.domain.Role;
import org.jclouds.iam.xml.ListRolesResultHandler;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
/**
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "ListRolesResponseTest")
public class ListRolesResponseTest extends BaseHandlerTest {
public void test() {
InputStream is = getClass().getResourceAsStream("/list_roles.xml");
IterableWithMarker<Role> expected = expected();
ListRolesResultHandler handler = injector.getInstance(ListRolesResultHandler.class);
IterableWithMarker<Role> result = factory.create(handler).parse(is);
assertEquals(result.toString(), expected.toString());
}
public IterableWithMarker<Role> expected() {
return IterableWithMarkers.from(ImmutableSet.of(
Role.builder()
.arn("arn:aws:iam::993194456877:role/foobie")
.id("AROAIBFDQ5TQHEMPBEUE4")
.name("foobie")
.path("/")
.assumeRolePolicy("{\"Version\":\"2008-10-17\",\"Statement\":[{\"Sid\":\"\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"ec2.amazonaws.com\"},\"Action\":\"sts:AssumeRole\"}]}")
.createDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2013-02-25T01:51:35Z")).build(),
Role.builder()
.arn("arn:aws:iam::993194456877:role/s3-read-only")
.id("AROAJZ7NAM67BRSDAJ6PA")
.name("s3-read-only")
.path("/")
.assumeRolePolicy("{\"Version\":\"2008-10-17\",\"Statement\":[{\"Sid\":\"\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"ec2.amazonaws.com\"},\"Action\":\"sts:AssumeRole\"}]}")
.createDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2013-02-25T01:48:59Z")).build()));
}
}

View File

@ -0,0 +1,15 @@
<CreateRoleResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
<CreateRoleResult>
<Role>
<Path>/</Path>
<Arn>arn:aws:iam::993194456877:role/adriancole.role.iamtest.jclouds.org.</Arn>
<RoleName>adriancole.role.iamtest.jclouds.org.</RoleName>
<AssumeRolePolicyDocument>%7B%22Version%22%3A%222008-10-17%22%2C%22Statement%22%3A%5B%7B%22Sid%22%3A%22%22%2C%22Effect%22%3A%22Allow%22%2C%22Principal%22%3A%7B%22Service%22%3A%22ec2.amazonaws.com%22%7D%2C%22Action%22%3A%22sts%3AAssumeRole%22%7D%5D%7D</AssumeRolePolicyDocument>
<CreateDate>2013-02-25T02:40:42.201Z</CreateDate>
<RoleId>AROAICHA6NH3SOP6PEC72</RoleId>
</Role>
</CreateRoleResult>
<ResponseMetadata>
<RequestId>bf56e8fb-7ef4-11e2-87c7-6b7f31e39cd7</RequestId>
</ResponseMetadata>
</CreateRoleResponse>

View File

@ -0,0 +1,5 @@
<DeleteRoleResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
<ResponseMetadata>
<RequestId>913e3f37-99ed-11e1-a4c3-270EXAMPLE04</RequestId>
</ResponseMetadata>
</DeleteRoleResponse>

View File

@ -0,0 +1,15 @@
<GetRoleResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
<GetRoleResult>
<Role>
<Path>/</Path>
<Arn>arn:aws:iam::993194456877:role/foobie</Arn>
<RoleName>foobie</RoleName>
<AssumeRolePolicyDocument>%7B%22Version%22%3A%222008-10-17%22%2C%22Statement%22%3A%5B%7B%22Sid%22%3A%22%22%2C%22Effect%22%3A%22Allow%22%2C%22Principal%22%3A%7B%22Service%22%3A%22ec2.amazonaws.com%22%7D%2C%22Action%22%3A%22sts%3AAssumeRole%22%7D%5D%7D</AssumeRolePolicyDocument>
<CreateDate>2013-02-25T01:51:35Z</CreateDate>
<RoleId>AROAIBFDQ5TQHEMPBEUE4</RoleId>
</Role>
</GetRoleResult>
<ResponseMetadata>
<RequestId>22fda32f-7eee-11e2-87c7-6b7f31e39cd7</RequestId>
</ResponseMetadata>
</GetRoleResponse>

View File

@ -0,0 +1,28 @@
<ListRolesResponse>
<ListRolesResult>
<Roles>
<member>
<Path>/</Path>
<Arn>arn:aws:iam::993194456877:role/foobie</Arn>
<RoleName>foobie</RoleName>
<AssumeRolePolicyDocument>%7B%22Version%22%3A%222008-10-17%22%2C%22Statement%22%3A%5B%7B%22Sid%22%3A%22%22%2C%22Effect%22%3A%22Allow%22%2C%22Principal%22%3A%7B%22Service%22%3A%22ec2.amazonaws.com%22%7D%2C%22Action%22%3A%22sts%3AAssumeRole%22%7D%5D%7D
</AssumeRolePolicyDocument>
<CreateDate>2013-02-25T01:51:35Z</CreateDate>
<RoleId>AROAIBFDQ5TQHEMPBEUE4</RoleId>
</member>
<member>
<Path>/</Path>
<Arn>arn:aws:iam::993194456877:role/s3-read-only</Arn>
<RoleName>s3-read-only</RoleName>
<AssumeRolePolicyDocument>%7B%22Version%22%3A%222008-10-17%22%2C%22Statement%22%3A%5B%7B%22Sid%22%3A%22%22%2C%22Effect%22%3A%22Allow%22%2C%22Principal%22%3A%7B%22Service%22%3A%22ec2.amazonaws.com%22%7D%2C%22Action%22%3A%22sts%3AAssumeRole%22%7D%5D%7D
</AssumeRolePolicyDocument>
<CreateDate>2013-02-25T01:48:59Z</CreateDate>
<RoleId>AROAJZ7NAM67BRSDAJ6PA</RoleId>
</member>
</Roles>
<IsTruncated>false</IsTruncated>
</ListRolesResult>
<ResponseMetadata>
<RequestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</RequestId>
</ResponseMetadata>
</ListRolesResponse>

View File

@ -0,0 +1,29 @@
<ListRolesResponse>
<ListRolesResult>
<Roles>
<member>
<Path>/</Path>
<Arn>arn:aws:iam::993194456877:role/foobie</Arn>
<RoleName>foobie</RoleName>
<AssumeRolePolicyDocument>%7B%22Version%22%3A%222008-10-17%22%2C%22Statement%22%3A%5B%7B%22Sid%22%3A%22%22%2C%22Effect%22%3A%22Allow%22%2C%22Principal%22%3A%7B%22Service%22%3A%22ec2.amazonaws.com%22%7D%2C%22Action%22%3A%22sts%3AAssumeRole%22%7D%5D%7D
</AssumeRolePolicyDocument>
<CreateDate>2013-02-25T01:51:35Z</CreateDate>
<RoleId>AROAIBFDQ5TQHEMPBEUE4</RoleId>
</member>
<member>
<Path>/</Path>
<Arn>arn:aws:iam::993194456877:role/s3-read-only</Arn>
<RoleName>s3-read-only</RoleName>
<AssumeRolePolicyDocument>%7B%22Version%22%3A%222008-10-17%22%2C%22Statement%22%3A%5B%7B%22Sid%22%3A%22%22%2C%22Effect%22%3A%22Allow%22%2C%22Principal%22%3A%7B%22Service%22%3A%22ec2.amazonaws.com%22%7D%2C%22Action%22%3A%22sts%3AAssumeRole%22%7D%5D%7D
</AssumeRolePolicyDocument>
<CreateDate>2013-02-25T01:48:59Z</CreateDate>
<RoleId>AROAJZ7NAM67BRSDAJ6PA</RoleId>
</member>
</Roles>
<Marker>MARKER</Marker>
<IsTruncated>false</IsTruncated>
</ListRolesResult>
<ResponseMetadata>
<RequestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</RequestId>
</ResponseMetadata>
</ListRolesResponse>