mirror of https://github.com/apache/jclouds.git
Adding openstack-keystone to expose additional methods available on keystone api
This commit is contained in:
parent
d6ac7be31d
commit
b6502b13c1
|
@ -0,0 +1,134 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. jclouds licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.jclouds</groupId>
|
||||||
|
<artifactId>jclouds-project</artifactId>
|
||||||
|
<version>1.5.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../../project/pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<groupId>org.jclouds.labs</groupId>
|
||||||
|
<artifactId>openstack-keystone</artifactId>
|
||||||
|
<name>jcloud openstack-keystone api</name>
|
||||||
|
<description>jclouds components to access an implementation of OpenStack Keystone</description>
|
||||||
|
<packaging>bundle</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<!-- keystone endpoint -->
|
||||||
|
<test.openstack-keystone.endpoint>http://localhost:5000</test.openstack-keystone.endpoint>
|
||||||
|
<!-- keystone version -->
|
||||||
|
<test.openstack-keystone.api-version>2.0</test.openstack-keystone.api-version>
|
||||||
|
<test.openstack-keystone.build-version></test.openstack-keystone.build-version>
|
||||||
|
<test.openstack-keystone.identity>FIXME_IDENTITY</test.openstack-keystone.identity>
|
||||||
|
<test.openstack-keystone.credential>FIXME_CREDENTIALS</test.openstack-keystone.credential>
|
||||||
|
<test.jclouds.keystone.credential-type>passwordCredentials</test.jclouds.keystone.credential-type>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jclouds.common</groupId>
|
||||||
|
<artifactId>openstack-common</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jclouds</groupId>
|
||||||
|
<artifactId>jclouds-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>test-jar</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jclouds.common</groupId>
|
||||||
|
<artifactId>openstack-common</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>test-jar</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jclouds.driver</groupId>
|
||||||
|
<artifactId>jclouds-slf4j</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>1.0.0</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.openstack-keystone.endpoint>${test.openstack-keystone.endpoint}</test.openstack-keystone.endpoint>
|
||||||
|
<test.openstack-keystone.api-version>${test.openstack-keystone.api-version}</test.openstack-keystone.api-version>
|
||||||
|
<test.openstack-keystone.build-version>${test.openstack-keystone.build-version}</test.openstack-keystone.build-version>
|
||||||
|
<test.openstack-keystone.identity>${test.openstack-keystone.identity}</test.openstack-keystone.identity>
|
||||||
|
<test.openstack-keystone.credential>${test.openstack-keystone.credential}</test.openstack-keystone.credential>
|
||||||
|
<test.jclouds.keystone.credential-type>${test.jclouds.keystone.credential-type}</test.jclouds.keystone.credential-type>
|
||||||
|
</systemPropertyVariables>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<instructions>
|
||||||
|
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||||
|
<Export-Package>org.jclouds.openstack.keystone.v2_0*;version="${project.version}"</Export-Package>
|
||||||
|
<Import-Package>
|
||||||
|
org.jclouds.rest.internal;version="${project.version}",
|
||||||
|
org.jclouds*;version="${project.version}",
|
||||||
|
*
|
||||||
|
</Import-Package>
|
||||||
|
</instructions>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,176 @@
|
||||||
|
/**
|
||||||
|
* 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.openstack.keystone.v2_0;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.HEAD;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Access;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Role;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Token;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.User;
|
||||||
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
|
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||||
|
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
|
||||||
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides asynchronous access to Admin via their REST API.
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @see AdminClient
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
@SkipEncoding({ '/', '=' })
|
||||||
|
public interface AdminAsyncClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see UserClient#getApiMetadata()
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@SelectJson("version")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/")
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<ApiMetadata> getApiMetadata();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see UserClient#listTenants()
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@SelectJson("tenants")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/tenants")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Set<Tenant>> listTenants();
|
||||||
|
|
||||||
|
/** @see AdminClient#getToken(String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("token")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/tokens/{token}")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Token> getToken(@PathParam("token") String token);
|
||||||
|
|
||||||
|
/** @see AdminClient#getUserOfToken(String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("user")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/tokens/{token}")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<User> getUserOfToken(@PathParam("token") String token);
|
||||||
|
|
||||||
|
/** @see AdminClient#checkTokenIsValid(String) */
|
||||||
|
@HEAD
|
||||||
|
@Path("/tokens/{token}")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Boolean> checkTokenIsValid(@PathParam("token") String token);
|
||||||
|
|
||||||
|
/** @see AdminClient#getEndpointsForToken(String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("endpoints")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/tokens/{token}/endpoints")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Set<Endpoint>> getEndpointsForToken(@PathParam("token") String token);
|
||||||
|
|
||||||
|
/** @see AdminClient#getTenant(String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("tenant")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/tenants/{tenantId}")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Tenant> getTenant(@PathParam("tenantId") String tenantId);
|
||||||
|
|
||||||
|
/** @see AdminClient#getTenantByName(String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("tenant")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/tenants")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Tenant> getTenantByName(@QueryParam("name") String tenantName);
|
||||||
|
|
||||||
|
/** @see AdminClient#listUsers() */
|
||||||
|
@GET
|
||||||
|
@SelectJson("users")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/users")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Set<User>> listUsers();
|
||||||
|
|
||||||
|
/** @see AdminClient#getUser(String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("user")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/users/{userId}")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<User> getUser(@PathParam("userId") String userId);
|
||||||
|
|
||||||
|
/** @see AdminClient#getUserByName(String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("user")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/users")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<User> getUserByName(@QueryParam("name") String userName);
|
||||||
|
|
||||||
|
/** @see AdminClient#listRolesOfUser(String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("roles")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/users/{userId}/roles")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Set<Role>> listRolesOfUser(@PathParam("userId") String userId);
|
||||||
|
|
||||||
|
/** @see AdminClient#listRolesOfUserOnTenant(String, String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("roles")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/tenants/{tenantId}/users/{userId}/roles")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Set<Role>> listRolesOfUserOnTenant(@PathParam("userId") String userId, @PathParam("tenantId") String tenantId);
|
||||||
|
}
|
|
@ -0,0 +1,146 @@
|
||||||
|
/**
|
||||||
|
* 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.openstack.keystone.v2_0;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Access;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Role;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Token;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides synchronous access to the KeyStone Admin API.
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
* @see UserAsyncClient
|
||||||
|
* @see <a href=
|
||||||
|
* "http://docs.openstack.org/api/openstack-identity-service/2.0/content/Service_API_Client_Operations.html"
|
||||||
|
* />
|
||||||
|
*/
|
||||||
|
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
|
||||||
|
public interface AdminClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discover API version information, links to documentation (PDF, HTML, WADL), and supported media types
|
||||||
|
*
|
||||||
|
* @return the requested information
|
||||||
|
*/
|
||||||
|
ApiMetadata getApiMetadata();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The operation returns a list of tenants which the current token provides access to.
|
||||||
|
*/
|
||||||
|
Set<Tenant> listTenants();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve information about a tenant, by tenant ID
|
||||||
|
*
|
||||||
|
* @return the information about the tenant
|
||||||
|
*/
|
||||||
|
Tenant getTenant(String tenantId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve information about a tenant, by tenant name
|
||||||
|
* <p/>
|
||||||
|
* NOTE: currently not working in openstack ( https://bugs.launchpad.net/keystone/+bug/956687 )
|
||||||
|
*
|
||||||
|
* @return the information about the tenant
|
||||||
|
*/
|
||||||
|
Tenant getTenantByName(String tenantName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a token and, if it is valid, return access information regarding the tenant (though not the service catalog)/
|
||||||
|
*
|
||||||
|
* @return the requested information
|
||||||
|
*/
|
||||||
|
Token getToken(String token);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a token and, if it is valid, return access information regarding the tenant (though not the service catalog)/
|
||||||
|
*
|
||||||
|
* @return the requested information
|
||||||
|
*/
|
||||||
|
User getUserOfToken(String token);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a token. This is a high-performance variant of the #getToken() call that does not return any further
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* @return true if the token is valid
|
||||||
|
*/
|
||||||
|
Boolean checkTokenIsValid(String token);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all endpoints for a token
|
||||||
|
* <p/>
|
||||||
|
* NOTE: currently not working in openstack ( https://bugs.launchpad.net/keystone/+bug/988672 )
|
||||||
|
*
|
||||||
|
* @return the set of endpoints
|
||||||
|
*/
|
||||||
|
Set<Endpoint> getEndpointsForToken(String token);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the list of users
|
||||||
|
* <p/>
|
||||||
|
* NOTE: this method is not in API documentation for keystone, but does work
|
||||||
|
*
|
||||||
|
* @return the list of users
|
||||||
|
*/
|
||||||
|
Set<User> listUsers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve information about a user, by user ID
|
||||||
|
*
|
||||||
|
* @return the information about the user
|
||||||
|
*/
|
||||||
|
User getUser(String userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve information about a user, by user name
|
||||||
|
* <p/>
|
||||||
|
* NOTE: currently not working in openstack ( https://bugs.launchpad.net/keystone/+bug/956687 )
|
||||||
|
*
|
||||||
|
* @return the information about the user
|
||||||
|
*/
|
||||||
|
User getUserByName(String userName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of global roles associated with a specific user (excludes tenant roles).
|
||||||
|
* <p/>
|
||||||
|
* NOTE: Broken in openstack ( https://bugs.launchpad.net/keystone/+bug/933565 )
|
||||||
|
*
|
||||||
|
* @return the set of Roles granted to the user
|
||||||
|
*/
|
||||||
|
Set<Role> listRolesOfUser(String userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List the roles a user has been granted on a specific tenant
|
||||||
|
*
|
||||||
|
* @return the set of roles
|
||||||
|
*/
|
||||||
|
Set<Role> listRolesOfUserOnTenant(String userId, String tenantId);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
/**
|
||||||
|
* 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.openstack.keystone.v2_0;
|
||||||
|
|
||||||
|
import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.apis.ApiMetadata;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.KeystoneRestClientModule;
|
||||||
|
import org.jclouds.openstack.services.ServiceType;
|
||||||
|
import org.jclouds.rest.RestContext;
|
||||||
|
import org.jclouds.rest.internal.BaseRestApiMetadata;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.reflect.TypeToken;
|
||||||
|
import com.google.inject.Module;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of {@link org.jclouds.apis.ApiMetadata} for Keystone 2.0 API
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class KeystoneApiMetadata extends BaseRestApiMetadata {
|
||||||
|
|
||||||
|
/** The serialVersionUID */
|
||||||
|
private static final long serialVersionUID = 6725672099385580694L;
|
||||||
|
|
||||||
|
public static final TypeToken<RestContext<KeystoneClient, KeystoneAsyncClient>> CONTEXT_TOKEN = new TypeToken<RestContext<KeystoneClient, KeystoneAsyncClient>>() {
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return new Builder().fromApiMetadata(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeystoneApiMetadata() {
|
||||||
|
this(new Builder());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected KeystoneApiMetadata(Builder builder) {
|
||||||
|
super(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Properties defaultProperties() {
|
||||||
|
Properties properties = BaseRestApiMetadata.defaultProperties();
|
||||||
|
// auth fail can happen while cloud-init applies keypair updates
|
||||||
|
properties.setProperty("jclouds.ssh.max-retries", "7");
|
||||||
|
properties.setProperty("jclouds.ssh.retry-auth", "true");
|
||||||
|
// TODO: this doesn't actually do anything yet.
|
||||||
|
properties.setProperty(KeystoneProperties.VERSION, "2.0");
|
||||||
|
properties.put(SERVICE_TYPE, ServiceType.IDENTITY);
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder extends BaseRestApiMetadata.Builder {
|
||||||
|
|
||||||
|
protected Builder() {
|
||||||
|
super(KeystoneClient.class, KeystoneAsyncClient.class);
|
||||||
|
id("openstack-keystone")
|
||||||
|
.name("OpenStack Keystone Essex+ API")
|
||||||
|
.identityName("tenantId:user")
|
||||||
|
.credentialName("password")
|
||||||
|
.documentation(URI.create("http://api.openstack.org/"))
|
||||||
|
.version("2.0")
|
||||||
|
.defaultEndpoint("http://localhost:5000")
|
||||||
|
.defaultProperties(KeystoneApiMetadata.defaultProperties())
|
||||||
|
.defaultModules(ImmutableSet.<Class<? extends Module>>of(KeystoneRestClientModule.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeystoneApiMetadata build() {
|
||||||
|
return new KeystoneApiMetadata(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Builder fromApiMetadata(ApiMetadata in) {
|
||||||
|
super.fromApiMetadata(in);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/**
|
||||||
|
* 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.openstack.keystone.v2_0;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
|
||||||
|
import org.jclouds.Constants;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
import org.jclouds.location.Region;
|
||||||
|
import org.jclouds.location.functions.RegionToEndpoint;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.functions.RegionToAdminEndpointURI;
|
||||||
|
import org.jclouds.rest.annotations.Delegate;
|
||||||
|
import org.jclouds.rest.annotations.EndpointParam;
|
||||||
|
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides access to Openstack keystone resources via their REST API.
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
* @see <a href="http://keystone.openstack.org/" />
|
||||||
|
* @see KeystoneClient
|
||||||
|
*/
|
||||||
|
@Path("/v{" + Constants.PROPERTY_API_VERSION + "}")
|
||||||
|
public interface KeystoneAsyncClient {
|
||||||
|
/**
|
||||||
|
* @return the Region codes configured
|
||||||
|
*/
|
||||||
|
@Provides
|
||||||
|
@Region
|
||||||
|
Set<String> getConfiguredRegions();
|
||||||
|
|
||||||
|
/** Provides asynchronous access to Identity user-accessible features */
|
||||||
|
@Delegate
|
||||||
|
UserAsyncClient getUserClientForRegion(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
|
||||||
|
|
||||||
|
/** Provides asynchronous access to the KeyStone Admin API */
|
||||||
|
@Delegate
|
||||||
|
AdminAsyncClient getAdminClientForRegion(@EndpointParam(parser = RegionToAdminEndpointURI.class) @Nullable String region);
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/**
|
||||||
|
* 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.openstack.keystone.v2_0;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
import org.jclouds.location.Region;
|
||||||
|
import org.jclouds.location.functions.RegionToEndpoint;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.functions.RegionToAdminEndpointURI;
|
||||||
|
import org.jclouds.rest.annotations.Delegate;
|
||||||
|
import org.jclouds.rest.annotations.EndpointParam;
|
||||||
|
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides access to Openstack keystone resources via their REST API.
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
* @see <a href="http://keystone.openstack.org/" />
|
||||||
|
*/
|
||||||
|
@Timeout(duration = 10, timeUnit = TimeUnit.SECONDS)
|
||||||
|
public interface KeystoneClient {
|
||||||
|
/**
|
||||||
|
* @return the Region codes configured
|
||||||
|
*/
|
||||||
|
@Provides
|
||||||
|
@Region
|
||||||
|
Set<String> getConfiguredRegions();
|
||||||
|
|
||||||
|
/** Provides synchronous access to Identity user-accessible features */
|
||||||
|
@Delegate
|
||||||
|
UserClient getUserClientForRegion(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
|
||||||
|
|
||||||
|
/** Provides synchronous access to the KeyStone Admin API */
|
||||||
|
@Delegate
|
||||||
|
AdminClient getAdminClientForRegion(@EndpointParam(parser = RegionToAdminEndpointURI.class) @Nullable String region);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
/**
|
||||||
|
* 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.openstack.keystone.v2_0;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.binders.BindAuthToJsonPayload;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Access;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.ApiAccessKeyCredentials;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.PasswordCredentials;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||||
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
|
import org.jclouds.rest.annotations.MapBinder;
|
||||||
|
import org.jclouds.rest.annotations.PayloadParam;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
|
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||||
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides asynchronous access to Service via their REST API.
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @see UserClient
|
||||||
|
* @see <a href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/Service_API_Client_Operations.html"
|
||||||
|
* />
|
||||||
|
* @author Adrian Cole, Adam Lowe
|
||||||
|
*/
|
||||||
|
@SkipEncoding({ '/', '=' })
|
||||||
|
public interface UserAsyncClient {
|
||||||
|
/**
|
||||||
|
* @see UserClient#getApiMetadata()
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@SelectJson("version")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/")
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<ApiMetadata> getApiMetadata();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see UserClient#listTenants()
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@SelectJson("tenants")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/tenants")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Set<Tenant>> listTenants();
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/**
|
||||||
|
* 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.openstack.keystone.v2_0;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Access;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.ApiAccessKeyCredentials;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.PasswordCredentials;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides synchronous access to the KeyStone Service API.
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @author Adrian Cole, Adam Lowe
|
||||||
|
* @see UserAsyncClient
|
||||||
|
* @see <a href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/Service_API_Client_Operations.html"
|
||||||
|
* />
|
||||||
|
*/
|
||||||
|
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
|
||||||
|
public interface UserClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discover API version information, links to documentation (PDF, HTML, WADL), and supported media types
|
||||||
|
*
|
||||||
|
* @return the requested information
|
||||||
|
*/
|
||||||
|
ApiMetadata getApiMetadata();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The operation returns a list of tenants which the current token provides access to.
|
||||||
|
*/
|
||||||
|
Set<Tenant> listTenants();
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/**
|
||||||
|
* 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.openstack.keystone.v2_0.config;
|
||||||
|
|
||||||
|
import org.jclouds.json.config.GsonModule;
|
||||||
|
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||||
|
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
public class KeystoneParserModule extends AbstractModule {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bind(DateAdapter.class).to(GsonModule.Iso8601DateAdapter.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
/**
|
||||||
|
* 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.openstack.keystone.v2_0.config;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpErrorHandler;
|
||||||
|
import org.jclouds.http.annotation.ClientError;
|
||||||
|
import org.jclouds.http.annotation.Redirection;
|
||||||
|
import org.jclouds.http.annotation.ServerError;
|
||||||
|
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
|
||||||
|
import org.jclouds.location.suppliers.implicit.OnlyLocationOrFirstZone;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.AdminAsyncClient;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.AdminClient;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.KeystoneAsyncClient;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.KeystoneClient;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.UserAsyncClient;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.UserClient;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.handlers.KeystoneErrorHandler;
|
||||||
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
|
import org.jclouds.rest.config.RestClientModule;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.inject.Scopes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the Keystone connection.
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
@ConfiguresRestClient
|
||||||
|
public class KeystoneRestClientModule extends RestClientModule<KeystoneClient, KeystoneAsyncClient> {
|
||||||
|
|
||||||
|
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
|
||||||
|
.put(UserClient.class, UserAsyncClient.class).put(AdminClient.class, AdminAsyncClient.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
public KeystoneRestClientModule() {
|
||||||
|
super(DELEGATE_MAP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
install(new KeystoneParserModule());
|
||||||
|
super.configure();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void installLocations() {
|
||||||
|
// TODO: select this from KeystoneProperties.VERSION; note you select from
|
||||||
|
// a guice provided property, so it will have to come from somewhere else, maybe we move
|
||||||
|
// this to the the ContextBuilder
|
||||||
|
install(KeystoneAuthenticationModule.forRegions());
|
||||||
|
super.installLocations();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void bindErrorHandlers() {
|
||||||
|
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(KeystoneErrorHandler.class);
|
||||||
|
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(KeystoneErrorHandler.class);
|
||||||
|
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(KeystoneErrorHandler.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/**
|
||||||
|
* 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.openstack.keystone.v2_0.handlers;
|
||||||
|
|
||||||
|
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpCommand;
|
||||||
|
import org.jclouds.http.HttpErrorHandler;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
import org.jclouds.rest.AuthorizationException;
|
||||||
|
import org.jclouds.rest.ResourceNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will parse and set an appropriate exception on the command object.
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
// TODO: is there error spec someplace? let's type errors, etc.
|
||||||
|
@Singleton
|
||||||
|
public class KeystoneErrorHandler implements HttpErrorHandler {
|
||||||
|
public void handleError(HttpCommand command, HttpResponse response) {
|
||||||
|
// it is important to always read fully and close streams
|
||||||
|
byte[] data = closeClientButKeepContentStream(response);
|
||||||
|
String message = data != null ? new String(data) : null;
|
||||||
|
|
||||||
|
Exception exception = message != null ? new HttpResponseException(command, response, message)
|
||||||
|
: new HttpResponseException(command, response);
|
||||||
|
message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest().getRequestLine(),
|
||||||
|
response.getStatusLine());
|
||||||
|
switch (response.getStatusCode()) {
|
||||||
|
case 400:
|
||||||
|
break;
|
||||||
|
case 401:
|
||||||
|
case 403:
|
||||||
|
exception = new AuthorizationException(message, exception);
|
||||||
|
break;
|
||||||
|
case 404:
|
||||||
|
if (!command.getCurrentRequest().getMethod().equals("DELETE")) {
|
||||||
|
exception = new ResourceNotFoundException(message, exception);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
command.setException(exception);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
org.jclouds.openstack.keystone.v2_0.KeystoneApiMetadata
|
|
@ -0,0 +1,379 @@
|
||||||
|
/**
|
||||||
|
* 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 1.1 (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-1.1
|
||||||
|
*
|
||||||
|
* 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.openstack.keystone.v2_0;
|
||||||
|
|
||||||
|
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||||
|
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.net.URI;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.date.DateService;
|
||||||
|
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
import org.jclouds.openstack.domain.Link;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.MediaType;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Role;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Token;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.User;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneRestClientExpectTest;
|
||||||
|
import org.jclouds.rest.AuthorizationException;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests parsing and Guice wiring of UserClient
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
public class AdminClientExpectTest extends BaseKeystoneRestClientExpectTest<KeystoneClient> {
|
||||||
|
private DateService dateService = new SimpleDateFormatDateService();
|
||||||
|
|
||||||
|
public AdminClientExpectTest() {
|
||||||
|
endpoint = "https://csnode.jclouds.org:35357";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetApiMetaData() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/").
|
||||||
|
headers(ImmutableMultimap.of("Accept", APPLICATION_JSON)).build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/api_metadata.json", APPLICATION_JSON)).build())
|
||||||
|
.getAdminClientForRegion("region-a.geo-1");
|
||||||
|
ApiMetadata metadata = client.getApiMetadata();
|
||||||
|
assertNotNull(metadata);
|
||||||
|
assertEquals(metadata.getId(), "v2.0");
|
||||||
|
|
||||||
|
ApiMetadata expected = ApiMetadata.builder().id("v2.0")
|
||||||
|
.links(ImmutableSet.of(Link.builder().relation(Link.Relation.SELF).href(URI.create("http://172.16.89.140:5000/v2.0/")).build(),
|
||||||
|
Link.builder().relation(Link.Relation.DESCRIBEDBY).type("text/html").href(URI.create("http://docs.openstack.org/api/openstack-identity-service/2.0/content/")).build(),
|
||||||
|
Link.builder().relation(Link.Relation.DESCRIBEDBY).type("application/pdf").href(URI.create("http://docs.openstack.org/api/openstack-identity-service/2.0/identity-dev-guide-2.0.pdf")).build()
|
||||||
|
))
|
||||||
|
.status("beta")
|
||||||
|
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-11-19T00:00:00Z"))
|
||||||
|
.mediaTypes(ImmutableSet.of(
|
||||||
|
MediaType.builder().base("application/json").type("application/vnd.openstack.identity-v2.0+json").build(),
|
||||||
|
MediaType.builder().base("application/xml").type("application/vnd.openstack.identity-v2.0+xml").build()
|
||||||
|
))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertEquals(metadata, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetApiMetaDataFailNotFound() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/").headers(ImmutableMultimap.of("Accept", APPLICATION_JSON)).build(),
|
||||||
|
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
||||||
|
assertNull(client.getApiMetadata());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListTenants() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tenants").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/tenant_list.json", APPLICATION_JSON)).build())
|
||||||
|
.getAdminClientForRegion("region-a.geo-1");
|
||||||
|
Set<Tenant> tenants = client.listTenants();
|
||||||
|
assertNotNull(tenants);
|
||||||
|
assertFalse(tenants.isEmpty());
|
||||||
|
|
||||||
|
Set<Tenant> expected = ImmutableSet.of(
|
||||||
|
Tenant.builder().name("demo").id("05d1dc7af71646deba64cfc17b81bec0").build(),
|
||||||
|
Tenant.builder().name("admin").id("7aa2e17ec29f44d193c48feaba0852cc").build()
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(tenants, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListTenantsFailNotFound() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tenants").build(),
|
||||||
|
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
||||||
|
assertTrue(client.listTenants().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetTenant() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tenants/013ba41150a14830bec85ffe93353bcc").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/tenant_details.json", APPLICATION_JSON)).build())
|
||||||
|
.getAdminClientForRegion("region-a.geo-1");
|
||||||
|
Tenant tenant = client.getTenant("013ba41150a14830bec85ffe93353bcc");
|
||||||
|
assertNotNull(tenant);
|
||||||
|
assertEquals(tenant, Tenant.builder().id("013ba41150a14830bec85ffe93353bcc").name("admin").build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = AuthorizationException.class)
|
||||||
|
public void testListTenantsFailNotAuthorized() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tenants/013ba41150a14830bec85ffe93353bcc").build(),
|
||||||
|
standardResponseBuilder(401).build()).getAdminClientForRegion("region-a.geo-1");
|
||||||
|
client.getTenant("013ba41150a14830bec85ffe93353bcc");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetTenantByName() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tenants?name=admin").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/tenant_details.json", APPLICATION_JSON)).build())
|
||||||
|
.getAdminClientForRegion("region-a.geo-1");
|
||||||
|
Tenant tenant = client.getTenantByName("admin");
|
||||||
|
assertNotNull(tenant);
|
||||||
|
assertEquals(tenant, Tenant.builder().id("013ba41150a14830bec85ffe93353bcc").name("admin").build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetTenantByNameFailNotFound() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tenants?name=admin").build(),
|
||||||
|
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
||||||
|
assertNull(client.getTenantByName("admin"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetToken() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/token_details.json", APPLICATION_JSON)).build())
|
||||||
|
.getAdminClientForRegion("region-a.geo-1");
|
||||||
|
Token token = client.getToken("sometokenorother");
|
||||||
|
assertNotNull(token);
|
||||||
|
assertEquals(token,
|
||||||
|
Token.builder().id("167eccdc790946969ced473732e8109b").expires(dateService.iso8601SecondsDateParse("2012-04-28T12:42:50Z"))
|
||||||
|
.tenant(Tenant.builder().id("4cea93f5464b4f1c921fb3e0461d72b5").name("demo").build()).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetTokenFailNotFound() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").build(),
|
||||||
|
standardResponseBuilder(404).build())
|
||||||
|
.getAdminClientForRegion("region-a.geo-1");
|
||||||
|
assertNull(client.getToken("sometokenorother"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = HttpResponseException.class)
|
||||||
|
public void testGetTokenFail500() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").build(),
|
||||||
|
standardResponseBuilder(500).build()).getAdminClientForRegion("region-a.geo-1");
|
||||||
|
client.getToken("sometokenorother");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetUserOfToken() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/token_details.json", APPLICATION_JSON)).build())
|
||||||
|
.getAdminClientForRegion("region-a.geo-1");
|
||||||
|
User user = client.getUserOfToken("sometokenorother");
|
||||||
|
assertNotNull(user);
|
||||||
|
assertEquals(user, User.builder().id("2b9b606181634ae9ac86fd95a8bc2cde").name("admin")
|
||||||
|
.roles(ImmutableSet.of(Role.builder().id("79cada5c02814b57a52e0eed4dd388cb").name("admin").build()))
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetUserOfTokenFailNotFound() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").build(),
|
||||||
|
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
||||||
|
assertNull(client.getUserOfToken("sometokenorother"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCheckTokenIsValid() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").method("HEAD")
|
||||||
|
.headers(ImmutableMultimap.of("X-Auth-Token", authToken)).build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/token_details.json", APPLICATION_JSON)).build())
|
||||||
|
.getAdminClientForRegion("region-a.geo-1");
|
||||||
|
assertTrue(client.checkTokenIsValid("sometokenorother"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCheckTokenIsValidFailNotValid() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").method("HEAD")
|
||||||
|
.headers(ImmutableMultimap.of("X-Auth-Token", authToken)).build(),
|
||||||
|
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
||||||
|
assertFalse(client.checkTokenIsValid("sometokenorother"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEndpointsForToken() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/XXXXXX/endpoints").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_endpoints.json", APPLICATION_JSON)).build())
|
||||||
|
.getAdminClientForRegion("region-a.geo-1");
|
||||||
|
Set<Endpoint> endpoints = client.getEndpointsForToken("XXXXXX");
|
||||||
|
|
||||||
|
assertEquals(endpoints, ImmutableSet.of(
|
||||||
|
Endpoint.builder().publicURL(URI.create("https://csnode.jclouds.org/v2.0/"))
|
||||||
|
.adminURL(URI.create("https://csnode.jclouds.org:35357/v2.0/"))
|
||||||
|
.region("region-a.geo-1").versionId("2.0").build()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEndpointsForTokenFailNotFound() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/XXXXXX/endpoints").build(),
|
||||||
|
standardResponseBuilder(404).build())
|
||||||
|
.getAdminClientForRegion("region-a.geo-1");
|
||||||
|
assertTrue(client.getEndpointsForToken("XXXXXX").isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListUsers() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_list.json", APPLICATION_JSON)).build())
|
||||||
|
.getAdminClientForRegion("region-a.geo-1");
|
||||||
|
Set<User> users = client.listUsers();
|
||||||
|
assertNotNull(users);
|
||||||
|
assertFalse(users.isEmpty());
|
||||||
|
|
||||||
|
Set<User> expected = ImmutableSet.of(
|
||||||
|
User.builder().name("nova").id("e021dfd758eb44a89f1c57c8ef3be8e2").build(),
|
||||||
|
User.builder().name("glance").id("3f6c1c9ba993495ead7d2eb2192e284f").build(),
|
||||||
|
User.builder().name("demo").id("667b2e1420604df8b67cd8ea57d4ee64").build(),
|
||||||
|
User.builder().name("admin").id("2b9b606181634ae9ac86fd95a8bc2cde").build()
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(users, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = AuthorizationException.class)
|
||||||
|
public void testListUsersFailNotAuth() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users").build(),
|
||||||
|
standardResponseBuilder(401).build()).getAdminClientForRegion("region-a.geo-1");
|
||||||
|
client.listUsers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetUser() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users/e021dfd758eb44a89f1c57c8ef3be8e2").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_details.json", APPLICATION_JSON)).build())
|
||||||
|
.getAdminClientForRegion("region-a.geo-1");
|
||||||
|
User user = client.getUser("e021dfd758eb44a89f1c57c8ef3be8e2");
|
||||||
|
assertNotNull(user);
|
||||||
|
assertEquals(user, User.builder().name("nova").id("e021dfd758eb44a89f1c57c8ef3be8e2").build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetUserFailNotFound() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users/f021dfd758eb44a89f1c57c8ef3be8e2").build(),
|
||||||
|
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
||||||
|
assertNull(client.getUser("f021dfd758eb44a89f1c57c8ef3be8e2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetUserByName() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users?name=nova").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_details.json", APPLICATION_JSON)).build())
|
||||||
|
.getAdminClientForRegion("region-a.geo-1");
|
||||||
|
User user = client.getUserByName("nova");
|
||||||
|
assertNotNull(user);
|
||||||
|
assertEquals(user, User.builder().name("nova").id("e021dfd758eb44a89f1c57c8ef3be8e2").build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetUserByNameFailNotFound() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users?name=fred").build(),
|
||||||
|
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
||||||
|
assertNull(client.getUserByName("fred"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListRolesOfUser() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users/3f6c1c9ba993495ead7d2eb2192e284f/roles").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_role_list.json", APPLICATION_JSON)).build())
|
||||||
|
.getAdminClientForRegion("region-a.geo-1");
|
||||||
|
Set<Role> roles = client.listRolesOfUser("3f6c1c9ba993495ead7d2eb2192e284f");
|
||||||
|
assertNotNull(roles);
|
||||||
|
assertFalse(roles.isEmpty());
|
||||||
|
assertEquals(roles, ImmutableSet.of(
|
||||||
|
Role.builder().id("79cada5c02814b57a52e0eed4dd388cb").name("admin").build()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListRolesOfUserFailNotFound() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users/4f6c1c9ba993495ead7d2eb2192e284f/roles").build(),
|
||||||
|
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
||||||
|
assertTrue(client.listRolesOfUser("4f6c1c9ba993495ead7d2eb2192e284f").isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = HttpResponseException.class)
|
||||||
|
public void testListRolesOfUserFailNotImplemented() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users/5f6c1c9ba993495ead7d2eb2192e284f/roles").build(),
|
||||||
|
standardResponseBuilder(501).build()).getAdminClientForRegion("region-a.geo-1");
|
||||||
|
assertTrue(client.listRolesOfUser("5f6c1c9ba993495ead7d2eb2192e284f").isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListRolesOfUserInTenant() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users/3f6c1c9ba993495ead7d2eb2192e284f/roles").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_tenant_role_list.json", APPLICATION_JSON)).build())
|
||||||
|
.getAdminClientForRegion("region-a.geo-1");
|
||||||
|
Set<Role> roles = client.listRolesOfUser("3f6c1c9ba993495ead7d2eb2192e284f");
|
||||||
|
assertNotNull(roles);
|
||||||
|
assertFalse(roles.isEmpty());
|
||||||
|
assertEquals(roles, ImmutableSet.of(
|
||||||
|
Role.builder().id("31c451195aac49b386039341e2c92a16").name("KeystoneServiceAdmin").build(),
|
||||||
|
Role.builder().id("79cada5c02814b57a52e0eed4dd388cb").name("admin").build(),
|
||||||
|
Role.builder().id("6ea17ddd37a6447794cb0e164d4db894").name("KeystoneAdmin").build()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListRolesOfUserInTenantFailNotFound() {
|
||||||
|
AdminClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users/3f6c1c9ba993495ead7d2eb2192e284f/roles").build(),
|
||||||
|
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
||||||
|
assertTrue(client.listRolesOfUser("3f6c1c9ba993495ead7d2eb2192e284f").isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,194 @@
|
||||||
|
/**
|
||||||
|
* 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 1.1 (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-1.1
|
||||||
|
*
|
||||||
|
* 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.openstack.keystone.v2_0;
|
||||||
|
|
||||||
|
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.AssertJUnit.assertTrue;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Access;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Role;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Token;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.User;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneClientLiveTest;
|
||||||
|
import org.jclouds.openstack.reference.AuthHeaders;
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests AdminClient
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", testName = "AdminClientLiveTest", singleThreaded = true)
|
||||||
|
public class AdminClientLiveTest extends BaseKeystoneClientLiveTest {
|
||||||
|
|
||||||
|
protected String token;
|
||||||
|
|
||||||
|
// Get the token currently in use (there's currently no listTokens())
|
||||||
|
@BeforeMethod
|
||||||
|
public void grabToken() {
|
||||||
|
AuthenticateRequest ar = keystoneContext.getUtils().getInjector().getInstance(AuthenticateRequest.class);
|
||||||
|
HttpRequest test = ar.filter(HttpRequest.builder().method("GET").endpoint(URI.create(endpoint)).build());
|
||||||
|
token = Iterables.getOnlyElement(test.getHeaders().get(AuthHeaders.AUTH_TOKEN));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetApiMetaData() {
|
||||||
|
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
||||||
|
ApiMetadata result = keystoneContext.getApi().getAdminClientForRegion(regionId).getApiMetadata();
|
||||||
|
assertNotNull(result);
|
||||||
|
assertNotNull(result.getId());
|
||||||
|
assertNotNull(result.getStatus());
|
||||||
|
assertNotNull(result.getUpdated());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testTenants() {
|
||||||
|
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
||||||
|
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
||||||
|
Set<Tenant> result = client.listTenants();
|
||||||
|
assertNotNull(result);
|
||||||
|
assertFalse(result.isEmpty());
|
||||||
|
|
||||||
|
for (Tenant tenant : result) {
|
||||||
|
assertNotNull(tenant.getId());
|
||||||
|
|
||||||
|
Tenant aTenant = client.getTenant(tenant.getId());
|
||||||
|
assertEquals(aTenant, tenant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testToken() {
|
||||||
|
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
||||||
|
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
||||||
|
assertTrue(client.checkTokenIsValid(token));
|
||||||
|
Token result = client.getToken(token);
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(result.getId(), token);
|
||||||
|
assertNotNull(result.getTenant());
|
||||||
|
|
||||||
|
User user = client.getUserOfToken(token);
|
||||||
|
assertNotNull(user);
|
||||||
|
assertNotNull(user.getId());
|
||||||
|
assertNotNull(user.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testInvalidToken() {
|
||||||
|
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
||||||
|
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
||||||
|
assertFalse(client.checkTokenIsValid("thisisnotarealtoken!"));
|
||||||
|
assertNull(client.getToken("thisisnotarealtoken!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO this threw 501 not implemented
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testTokenEndpoints() {
|
||||||
|
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
||||||
|
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
||||||
|
Set<Endpoint> endpoints = client.getEndpointsForToken(token);
|
||||||
|
assertNotNull(endpoints);
|
||||||
|
assertFalse(endpoints.isEmpty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO this threw 501 not implemented
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testInvalidTokenEndpoints() {
|
||||||
|
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
||||||
|
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
||||||
|
assertTrue(client.getEndpointsForToken("thisisnotarealtoken!").isEmpty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testUsers() {
|
||||||
|
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
||||||
|
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
||||||
|
Set<User> users = client.listUsers();
|
||||||
|
assertNotNull(users);
|
||||||
|
assertFalse(users.isEmpty());
|
||||||
|
for (User user : users) {
|
||||||
|
User aUser = client.getUser(user.getId());
|
||||||
|
assertEquals(aUser, user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = {"testUsers", "testTenants"})
|
||||||
|
public void testUserRolesOnTenant() {
|
||||||
|
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
||||||
|
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
||||||
|
Set<User> users = client.listUsers();
|
||||||
|
Set<Tenant> tenants = client.listTenants();
|
||||||
|
|
||||||
|
for (User user : users) {
|
||||||
|
for (Tenant tenant : tenants) {
|
||||||
|
Set<Role> roles = client.listRolesOfUserOnTenant(user.getId(), tenant.getId());
|
||||||
|
for (Role role : roles) {
|
||||||
|
assertNotNull(role.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO this functionality is currently broken in openstack
|
||||||
|
@Test(enabled = false, dependsOnMethods = "testUsers")
|
||||||
|
public void testListRolesOfUser() {
|
||||||
|
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
||||||
|
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
||||||
|
for (User user : client.listUsers()) {
|
||||||
|
Set<Role> roles = client.listRolesOfUser(user.getId());
|
||||||
|
for (Role role : roles) {
|
||||||
|
assertNotNull(role.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO this functionality is currently broken in openstack (possibly deprecated?)
|
||||||
|
@Test(enabled=false, dependsOnMethods = {"testUsers", "testTenants"})
|
||||||
|
public void testUsersAndTenantsByName() {
|
||||||
|
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
||||||
|
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
||||||
|
for (User user : client.listUsers()) {
|
||||||
|
User aUser = client.getUserByName(user.getName());
|
||||||
|
assertEquals(aUser, user);
|
||||||
|
}
|
||||||
|
for (Tenant tenant : client.listTenants()) {
|
||||||
|
Tenant aTenant = client.getTenantByName(tenant.getName());
|
||||||
|
assertEquals(aTenant, tenant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
/**
|
||||||
|
* 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 1.1 (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-1.1
|
||||||
|
*
|
||||||
|
* 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.openstack.keystone.v2_0;
|
||||||
|
|
||||||
|
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||||
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
import static junit.framework.Assert.assertFalse;
|
||||||
|
import static junit.framework.Assert.assertNotNull;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.openstack.domain.Link;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.MediaType;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneRestClientExpectTest;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests parsing and Guice wiring of UserClient
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
public class UserClientExpectTest extends BaseKeystoneRestClientExpectTest<KeystoneClient> {
|
||||||
|
|
||||||
|
public void testGetApiMetaData() {
|
||||||
|
UserClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
HttpRequest.builder().method("GET").endpoint(URI.create(endpoint + "/v2.0/")).
|
||||||
|
headers(ImmutableMultimap.of("Accept", APPLICATION_JSON)).build(),
|
||||||
|
HttpResponse.builder().statusCode(200).
|
||||||
|
payload(payloadFromResourceWithContentType("/api_metadata.json", APPLICATION_JSON)).build())
|
||||||
|
.getUserClientForRegion("region-a.geo-1");
|
||||||
|
ApiMetadata metadata = client.getApiMetadata();
|
||||||
|
assertNotNull(metadata);
|
||||||
|
assertEquals(metadata.getId(), "v2.0");
|
||||||
|
|
||||||
|
ApiMetadata expected = ApiMetadata.builder().id("v2.0")
|
||||||
|
.links(ImmutableSet.of(Link.builder().relation(Link.Relation.SELF).href(URI.create("http://172.16.89.140:5000/v2.0/")).build(),
|
||||||
|
Link.builder().relation(Link.Relation.DESCRIBEDBY).type("text/html").href(URI.create("http://docs.openstack.org/api/openstack-identity-service/2.0/content/")).build(),
|
||||||
|
Link.builder().relation(Link.Relation.DESCRIBEDBY).type("application/pdf").href(URI.create("http://docs.openstack.org/api/openstack-identity-service/2.0/identity-dev-guide-2.0.pdf")).build()
|
||||||
|
))
|
||||||
|
.status("beta")
|
||||||
|
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-11-19T00:00:00Z"))
|
||||||
|
.mediaTypes(ImmutableSet.of(
|
||||||
|
MediaType.builder().base("application/json").type("application/vnd.openstack.identity-v2.0+json").build(),
|
||||||
|
MediaType.builder().base("application/xml").type("application/vnd.openstack.identity-v2.0+xml").build()
|
||||||
|
))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertEquals(metadata, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListTenants() {
|
||||||
|
UserClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
HttpRequest.builder().method("GET").endpoint(URI.create(endpoint + "/v2.0/tenants")).
|
||||||
|
headers(ImmutableMultimap.of("Accept", APPLICATION_JSON, "X-Auth-Token", authToken)).build(),
|
||||||
|
HttpResponse.builder().statusCode(200).
|
||||||
|
payload(payloadFromResourceWithContentType("/tenant_list.json", APPLICATION_JSON)).build())
|
||||||
|
.getUserClientForRegion("region-a.geo-1");
|
||||||
|
Set<Tenant> tenants = client.listTenants();
|
||||||
|
assertNotNull(tenants);
|
||||||
|
assertFalse(tenants.isEmpty());
|
||||||
|
|
||||||
|
Set<Tenant> expected = ImmutableSet.of(
|
||||||
|
Tenant.builder().name("demo").id("05d1dc7af71646deba64cfc17b81bec0").build(),
|
||||||
|
Tenant.builder().name("admin").id("7aa2e17ec29f44d193c48feaba0852cc").build()
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(tenants, expected);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
/**
|
||||||
|
* 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 1.1 (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-1.1
|
||||||
|
*
|
||||||
|
* 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.openstack.keystone.v2_0;
|
||||||
|
|
||||||
|
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||||
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
import static junit.framework.Assert.assertFalse;
|
||||||
|
import static junit.framework.Assert.assertNotNull;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.openstack.domain.Link;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.MediaType;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneClientLiveTest;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneRestClientExpectTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests UserClient
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", testName = "UserClientLiveTest")
|
||||||
|
public class UserClientLiveTest extends BaseKeystoneClientLiveTest {
|
||||||
|
|
||||||
|
public void testGetApiMetaData() {
|
||||||
|
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
||||||
|
ApiMetadata result = keystoneContext.getApi().getUserClientForRegion(regionId).getApiMetadata();
|
||||||
|
assertNotNull(result);
|
||||||
|
assertNotNull(result.getId());
|
||||||
|
assertNotNull(result.getStatus());
|
||||||
|
assertNotNull(result.getUpdated());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListTenants() {
|
||||||
|
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
||||||
|
Set<Tenant> result = keystoneContext.getApi().getUserClientForRegion(regionId).listTenants();
|
||||||
|
assertNotNull(result);
|
||||||
|
assertFalse(result.isEmpty());
|
||||||
|
|
||||||
|
for (Tenant tenant : result) {
|
||||||
|
assertNotNull(tenant.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/**
|
||||||
|
* 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.openstack.keystone.v2_0.internal;
|
||||||
|
|
||||||
|
import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.apis.BaseContextLiveTest;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.KeystoneApiMetadata;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.KeystoneAsyncClient;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.KeystoneClient;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
|
||||||
|
import org.jclouds.openstack.services.ServiceType;
|
||||||
|
import org.jclouds.rest.RestContext;
|
||||||
|
import org.testng.annotations.AfterGroups;
|
||||||
|
import org.testng.annotations.BeforeGroups;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.reflect.TypeToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code KeystoneClient}
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
@Test(groups = "live")
|
||||||
|
public class BaseKeystoneClientLiveTest extends BaseContextLiveTest<RestContext<KeystoneClient, KeystoneAsyncClient>> {
|
||||||
|
|
||||||
|
public BaseKeystoneClientLiveTest() {
|
||||||
|
provider = "openstack-keystone";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RestContext<KeystoneClient, KeystoneAsyncClient> keystoneContext;
|
||||||
|
|
||||||
|
@BeforeGroups(groups = { "integration", "live" })
|
||||||
|
@Override
|
||||||
|
public void setupContext() {
|
||||||
|
super.setupContext();
|
||||||
|
keystoneContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Properties setupProperties() {
|
||||||
|
Properties props = super.setupProperties();
|
||||||
|
setIfTestSystemPropertyPresent(props, KeystoneProperties.CREDENTIAL_TYPE);
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterGroups(groups = "live")
|
||||||
|
protected void tearDown() {
|
||||||
|
if (keystoneContext != null)
|
||||||
|
keystoneContext.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TypeToken<RestContext<KeystoneClient, KeystoneAsyncClient>> contextType() {
|
||||||
|
return KeystoneApiMetadata.CONTEXT_TOKEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
/**
|
||||||
|
* 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 1.1 (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-1.1
|
||||||
|
*
|
||||||
|
* 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.openstack.keystone.v2_0.internal;
|
||||||
|
|
||||||
|
import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.Constants;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.openstack.keystone.v1_1.config.AuthenticationServiceModule;
|
||||||
|
import org.jclouds.openstack.services.ServiceType;
|
||||||
|
import org.jclouds.rest.internal.BaseRestClientExpectTest;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.net.HttpHeaders;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for writing KeyStone 2.0 Rest Client Expect tests
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
public class BaseKeystoneRestClientExpectTest<S> extends BaseRestClientExpectTest<S> {
|
||||||
|
protected HttpRequest keystoneAuthWithUsernameAndPassword;
|
||||||
|
protected HttpRequest keystoneAuthWithAccessKeyAndSecretKey;
|
||||||
|
protected String authToken;
|
||||||
|
protected HttpResponse responseWithKeystoneAccess;
|
||||||
|
protected String endpoint = "https://csnode.jclouds.org";
|
||||||
|
|
||||||
|
public BaseKeystoneRestClientExpectTest() {
|
||||||
|
provider = "openstack-keystone";
|
||||||
|
keystoneAuthWithUsernameAndPassword = KeystoneFixture.INSTANCE.initialAuthWithUsernameAndPassword(identity,
|
||||||
|
credential);
|
||||||
|
keystoneAuthWithAccessKeyAndSecretKey = KeystoneFixture.INSTANCE.initialAuthWithAccessKeyAndSecretKey(identity,
|
||||||
|
credential);
|
||||||
|
|
||||||
|
authToken = KeystoneFixture.INSTANCE.getAuthToken();
|
||||||
|
responseWithKeystoneAccess = KeystoneFixture.INSTANCE.responseWithAccess();
|
||||||
|
// now, createContext arg will need tenant prefix
|
||||||
|
identity = KeystoneFixture.INSTANCE.getTenantName() + ":" + identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected HttpRequest.Builder standardRequestBuilder(String endpoint) {
|
||||||
|
return HttpRequest.builder().method("GET")
|
||||||
|
.headers(ImmutableMultimap.of("Accept", MediaType.APPLICATION_JSON, "X-Auth-Token", authToken))
|
||||||
|
.endpoint(URI.create(endpoint));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected HttpResponse.Builder standardResponseBuilder(int status) {
|
||||||
|
return HttpResponse.builder().statusCode(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Properties setupProperties() {
|
||||||
|
Properties props = super.setupProperties();
|
||||||
|
props.put(SERVICE_TYPE, ServiceType.IDENTITY);
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected HttpRequestComparisonType compareHttpRequestAsType(HttpRequest input) {
|
||||||
|
return Objects.equal("HEAD", input.getMethod()) ? HttpRequestComparisonType.DEFAULT : HttpRequestComparisonType.JSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
{"version": {"status": "beta", "updated": "2011-11-19T00:00:00Z", "media-types": [{"base": "application/json", "type": "application/vnd.openstack.identity-v2.0+json"}, {"base": "application/xml", "type": "application/vnd.openstack.identity-v2.0+xml"}], "id": "v2.0", "links": [{"href": "http://172.16.89.140:5000/v2.0/", "rel": "self"}, {"href": "http://docs.openstack.org/api/openstack-identity-service/2.0/content/", "type": "text/html", "rel": "describedby"}, {"href": "http://docs.openstack.org/api/openstack-identity-service/2.0/identity-dev-guide-2.0.pdf", "type": "application/pdf", "rel": "describedby"}]}}
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<configuration scan="false">
|
||||||
|
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
|
||||||
|
<file>target/test-data/jclouds.log</file>
|
||||||
|
|
||||||
|
<encoder>
|
||||||
|
<Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="WIREFILE" class="ch.qos.logback.core.FileAppender">
|
||||||
|
<file>target/test-data/jclouds-wire.log</file>
|
||||||
|
|
||||||
|
<encoder>
|
||||||
|
<Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="BLOBSTOREFILE" class="ch.qos.logback.core.FileAppender">
|
||||||
|
<file>target/test-data/jclouds-blobstore.log</file>
|
||||||
|
|
||||||
|
<encoder>
|
||||||
|
<Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root>
|
||||||
|
<level value="warn" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
<logger name="org.jclouds">
|
||||||
|
<level value="DEBUG" />
|
||||||
|
<appender-ref ref="FILE" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<logger name="jclouds.wire">
|
||||||
|
<level value="DEBUG" />
|
||||||
|
<appender-ref ref="WIREFILE" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<logger name="jclouds.headers">
|
||||||
|
<level value="DEBUG" />
|
||||||
|
<appender-ref ref="WIREFILE" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<logger name="jclouds.blobstore">
|
||||||
|
<level value="DEBUG" />
|
||||||
|
<appender-ref ref="BLOBSTOREFILE" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
</configuration>
|
|
@ -0,0 +1 @@
|
||||||
|
{"tenant": {"enabled": true, "description": null, "name": "admin", "id": "013ba41150a14830bec85ffe93353bcc"}}
|
|
@ -0,0 +1 @@
|
||||||
|
{"tenants_links": [], "tenants": [{"enabled": true, "description": null, "name": "demo", "id": "05d1dc7af71646deba64cfc17b81bec0"}, {"enabled": true, "description": null, "name": "admin", "id": "7aa2e17ec29f44d193c48feaba0852cc"}]}
|
|
@ -0,0 +1 @@
|
||||||
|
{"access": {"token": {"expires": "2012-04-28T12:42:50Z", "id": "167eccdc790946969ced473732e8109b", "tenant": {"id": "4cea93f5464b4f1c921fb3e0461d72b5", "enabled": true, "description": null, "name": "demo"}}, "user": {"username": "admin", "roles_links": [], "id": "2b9b606181634ae9ac86fd95a8bc2cde", "roles": [{"id": "79cada5c02814b57a52e0eed4dd388cb", "name": "admin"}], "name": "admin"}}}
|
|
@ -0,0 +1 @@
|
||||||
|
{"user": {"name": "nova", "enabled": true, "email": "nova@example.com", "id": "e021dfd758eb44a89f1c57c8ef3be8e2", "tenantId": "ab1da202f5774cceb5da2aeff1f0aa87"}}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{"endpoints": [
|
||||||
|
{
|
||||||
|
"adminURL": "https://csnode.jclouds.org:35357/v2.0/",
|
||||||
|
"publicURL": "https://csnode.jclouds.org/v2.0/",
|
||||||
|
"region": "region-a.geo-1",
|
||||||
|
"id": "2.0",
|
||||||
|
"versionId":"2.0",
|
||||||
|
"list": "https://csnode.jclouds.org/extension"
|
||||||
|
}
|
||||||
|
]}
|
|
@ -0,0 +1 @@
|
||||||
|
{"users": [{"name": "admin", "enabled": true, "email": "admin@example.com", "id": "2b9b606181634ae9ac86fd95a8bc2cde", "tenantId": null}, {"name": "demo", "enabled": true, "email": "demo@example.com", "id": "667b2e1420604df8b67cd8ea57d4ee64", "tenantId": null}, {"name": "nova", "enabled": true, "email": "nova@example.com", "id": "e021dfd758eb44a89f1c57c8ef3be8e2", "tenantId": "ab1da202f5774cceb5da2aeff1f0aa87"}, {"name": "glance", "enabled": true, "email": "glance@example.com", "id": "3f6c1c9ba993495ead7d2eb2192e284f", "tenantId": "ab1da202f5774cceb5da2aeff1f0aa87"}]}
|
|
@ -0,0 +1 @@
|
||||||
|
{"roles": [{"id": "79cada5c02814b57a52e0eed4dd388cb", "name": "admin"}]}
|
|
@ -0,0 +1 @@
|
||||||
|
{"roles": [{"id": "31c451195aac49b386039341e2c92a16", "name": "KeystoneServiceAdmin"}, {"id": "79cada5c02814b57a52e0eed4dd388cb", "name": "admin"}, {"id": "6ea17ddd37a6447794cb0e164d4db894", "name": "KeystoneAdmin"}]}
|
Loading…
Reference in New Issue