mirror of https://github.com/apache/jclouds.git
openstack-nova: Adding CREATESERVEREXT extension (renamed ServerWithSecurityGroupsClient to be clear about what's on offer)
This commit is contained in:
parent
42df3d339c
commit
06d3ef02ba
|
@ -27,6 +27,7 @@ import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.HostAdministrationAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.HostAdministrationAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupAsyncClient;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.extensions.ServerWithSecurityGroupsAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.SimpleTenantUsageAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.SimpleTenantUsageAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.VirtualInterfaceAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.VirtualInterfaceAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.VolumeAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.VolumeAsyncClient;
|
||||||
|
@ -135,4 +136,13 @@ public interface NovaAsyncClient {
|
||||||
@Delegate
|
@Delegate
|
||||||
Optional<VirtualInterfaceAsyncClient> getVirtualInterfaceExtensionForZone(
|
Optional<VirtualInterfaceAsyncClient> getVirtualInterfaceExtensionForZone(
|
||||||
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
|
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides asynchronous access to Server Extra Data features.
|
||||||
|
*/
|
||||||
|
@Delegate
|
||||||
|
Optional<ServerWithSecurityGroupsAsyncClient> getServerExtraDataExtensionForZone(
|
||||||
|
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.HostAdministrationClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.HostAdministrationClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupClient;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.extensions.ServerWithSecurityGroupsClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.SimpleTenantUsageClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.SimpleTenantUsageClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.VirtualInterfaceClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.VirtualInterfaceClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.VolumeClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.VolumeClient;
|
||||||
|
@ -139,4 +140,12 @@ public interface NovaClient {
|
||||||
Optional<VirtualInterfaceClient> getVirtualInterfaceExtensionForZone(
|
Optional<VirtualInterfaceClient> getVirtualInterfaceExtensionForZone(
|
||||||
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
|
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides synchronous access to Server Extra Data features.
|
||||||
|
*/
|
||||||
|
@Delegate
|
||||||
|
Optional<ServerWithSecurityGroupsClient> getServerExtraDataExtensionForZone(
|
||||||
|
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,14 +20,19 @@ package org.jclouds.openstack.nova.v1_1.config;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.json.config.GsonModule;
|
import org.jclouds.json.config.GsonModule;
|
||||||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.HostResourceUsage;
|
import org.jclouds.openstack.nova.v1_1.domain.HostResourceUsage;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.ServerWithSecurityGroups;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonDeserializationContext;
|
import com.google.gson.JsonDeserializationContext;
|
||||||
import com.google.gson.JsonDeserializer;
|
import com.google.gson.JsonDeserializer;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
|
@ -39,13 +44,17 @@ import com.google.inject.Provides;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
* @author Adam Lowe
|
||||||
*/
|
*/
|
||||||
public class NovaParserModule extends AbstractModule {
|
public class NovaParserModule extends AbstractModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
public Map<Type, Object> provideCustomAdapterBindings() {
|
public Map<Type, Object> provideCustomAdapterBindings() {
|
||||||
return ImmutableMap.<Type, Object> of(HostResourceUsage.class, new HostResourceUsageAdapter());
|
return ImmutableMap.<Type, Object> of(
|
||||||
|
HostResourceUsage.class, new HostResourceUsageAdapter(),
|
||||||
|
ServerWithSecurityGroups.class, new ServerWithSecurityGroupsAdapter()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -79,4 +88,22 @@ public class NovaParserModule extends AbstractModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class ServerWithSecurityGroupsAdapter implements JsonDeserializer<ServerWithSecurityGroups> {
|
||||||
|
@Override
|
||||||
|
public ServerWithSecurityGroups deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
Server server = context.deserialize(jsonElement, Server.class);
|
||||||
|
ServerWithSecurityGroups.Builder result = ServerWithSecurityGroups.builder().fromServer(server);
|
||||||
|
Set<String> names = Sets.newLinkedHashSet();
|
||||||
|
if (jsonElement.getAsJsonObject().get("security_groups") != null) {
|
||||||
|
JsonArray x = jsonElement.getAsJsonObject().get("security_groups").getAsJsonArray();
|
||||||
|
for(JsonElement y : x) {
|
||||||
|
names.add(y.getAsJsonObject().get("name").getAsString());
|
||||||
|
}
|
||||||
|
result.securityGroupNames(names);
|
||||||
|
}
|
||||||
|
return result.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,7 @@ public class NovaRestClientModule extends RestClientModule<NovaClient, NovaAsync
|
||||||
.put(SimpleTenantUsageClient.class, SimpleTenantUsageAsyncClient.class)
|
.put(SimpleTenantUsageClient.class, SimpleTenantUsageAsyncClient.class)
|
||||||
.put(VolumeClient.class, VolumeAsyncClient.class)
|
.put(VolumeClient.class, VolumeAsyncClient.class)
|
||||||
.put(VirtualInterfaceClient.class, VirtualInterfaceAsyncClient.class)
|
.put(VirtualInterfaceClient.class, VirtualInterfaceAsyncClient.class)
|
||||||
|
.put(ServerWithSecurityGroupsClient.class, ServerWithSecurityGroupsAsyncClient.class)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public NovaRestClientModule() {
|
public NovaRestClientModule() {
|
||||||
|
|
|
@ -101,23 +101,23 @@ public class Server extends Resource {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder extends Resource.Builder {
|
public static class Builder extends Resource.Builder {
|
||||||
private String uuid;
|
protected String uuid;
|
||||||
private String tenantId;
|
protected String tenantId;
|
||||||
private String userId;
|
protected String userId;
|
||||||
private Date updated;
|
protected Date updated;
|
||||||
private Date created;
|
protected Date created;
|
||||||
private String hostId;
|
protected String hostId;
|
||||||
private String accessIPv4;
|
protected String accessIPv4;
|
||||||
private String accessIPv6;
|
protected String accessIPv6;
|
||||||
private Status status;
|
protected Status status;
|
||||||
private String configDrive;
|
protected String configDrive;
|
||||||
private Resource image;
|
protected Resource image;
|
||||||
private Resource flavor;
|
protected Resource flavor;
|
||||||
private Map<String, String> metadata = Maps.newHashMap();
|
protected Map<String, String> metadata = Maps.newHashMap();
|
||||||
// TODO: get gson multimap ad
|
// TODO: get gson multimap ad
|
||||||
private Multimap<String, Address> addresses = LinkedHashMultimap.create();
|
protected Multimap<String, Address> addresses = LinkedHashMultimap.create();
|
||||||
private String adminPass;
|
protected String adminPass;
|
||||||
private String keyName;
|
protected String keyName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Server#getUuid()
|
* @see Server#getUuid()
|
||||||
|
@ -375,8 +375,7 @@ public class Server extends Resource {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return host identifier, or null if in {@link Status#BUILD}
|
||||||
* @return host identifier, or null if in {@link ServerState#BUILD}
|
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getHostId() {
|
public String getHostId() {
|
||||||
|
|
|
@ -0,0 +1,271 @@
|
||||||
|
/**
|
||||||
|
* 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.nova.v1_1.domain;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
import org.jclouds.openstack.domain.Link;
|
||||||
|
import org.jclouds.openstack.domain.Resource;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extended server returned by ServerWithSecurityGroupsClient
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
* @see org.jclouds.openstack.nova.v1_1.extensions.ServerWithSecurityGroupsClient
|
||||||
|
* @see <a href=
|
||||||
|
* "http://docs.openstack.org/api/openstack-compute/1.1/content/Get_Server_Details-d1e2623.html"
|
||||||
|
* />
|
||||||
|
*/
|
||||||
|
public class ServerWithSecurityGroups extends Server {
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return new Builder().fromServerWithSecurityGroups(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder extends Server.Builder {
|
||||||
|
private Set<String> securityGroupNames = Sets.newLinkedHashSet();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ServerWithSecurityGroups#getSecurityGroupNames()
|
||||||
|
*/
|
||||||
|
public Builder securityGroupNames(Set<String> securityGroupNames) {
|
||||||
|
this.securityGroupNames = securityGroupNames;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder fromServerWithSecurityGroups(ServerWithSecurityGroups in) {
|
||||||
|
return fromServer(in).securityGroupNames(in.getSecurityGroupNames());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerWithSecurityGroups build() {
|
||||||
|
return new ServerWithSecurityGroups(id, name, links, uuid, tenantId, userId, updated, created, hostId, accessIPv4, accessIPv6,
|
||||||
|
status, configDrive, image, flavor, adminPass, keyName, addresses, metadata, securityGroupNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder fromResource(Resource in) {
|
||||||
|
return Builder.class.cast(super.fromResource(in));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder fromServer(Server in) {
|
||||||
|
return Builder.class.cast(super.fromServer(in));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder id(String id) {
|
||||||
|
return Builder.class.cast(super.id(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder name(String name) {
|
||||||
|
return Builder.class.cast(super.name(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder links(Set<Link> links) {
|
||||||
|
return Builder.class.cast(super.links(links));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder links(Link... links) {
|
||||||
|
return Builder.class.cast(super.links(links));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder uuid(String uuid) {
|
||||||
|
return Builder.class.cast(super.uuid(uuid));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder tenantId(String tenantId) {
|
||||||
|
return Builder.class.cast(super.tenantId(tenantId));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder userId(String userId) {
|
||||||
|
return Builder.class.cast(super.userId(userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder updated(Date updated) {
|
||||||
|
return Builder.class.cast(super.updated(updated));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder created(Date created) {
|
||||||
|
return Builder.class.cast(super.created(created));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder hostId(String hostId) {
|
||||||
|
return Builder.class.cast(super.hostId(hostId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder accessIPv4(String accessIPv4) {
|
||||||
|
return Builder.class.cast(super.accessIPv4(accessIPv4));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder accessIPv6(String accessIPv6) {
|
||||||
|
return Builder.class.cast(super.accessIPv6(accessIPv6));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder status(Status status) {
|
||||||
|
return Builder.class.cast(super.status(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder configDrive(String configDrive) {
|
||||||
|
return Builder.class.cast(super.configDrive(configDrive));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder image(Resource image) {
|
||||||
|
return Builder.class.cast(super.image(image));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder flavor(Resource flavor) {
|
||||||
|
return Builder.class.cast(super.flavor(flavor));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder adminPass(String adminPass) {
|
||||||
|
return Builder.class.cast(super.adminPass(adminPass));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder keyName(String keyName) {
|
||||||
|
return Builder.class.cast(super.keyName(keyName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder addresses(Multimap<String, Address> addresses) {
|
||||||
|
return Builder.class.cast(super.addresses(addresses));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder metadata(Map<String, String> metadata) {
|
||||||
|
return Builder.class.cast(super.metadata(metadata));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SerializedName("security_groups")
|
||||||
|
private final Set<String> securityGroupNames;
|
||||||
|
|
||||||
|
public ServerWithSecurityGroups(String id, String name, Set<Link> links, @Nullable String uuid, String tenantId,
|
||||||
|
String userId, Date updated, Date created, @Nullable String hostId,
|
||||||
|
@Nullable String accessIPv4, @Nullable String accessIPv6, Status status,
|
||||||
|
@Nullable String configDrive, Resource image, Resource flavor, String adminPass,
|
||||||
|
@Nullable String keyName, Multimap<String, Address> addresses,
|
||||||
|
Map<String, String> metadata, Set<String> securityGroupNames) {
|
||||||
|
super(id, name, links, uuid, tenantId, userId, updated, created, hostId, accessIPv4, accessIPv6, status, configDrive, image, flavor, adminPass, keyName, addresses, metadata);
|
||||||
|
this.securityGroupNames = ImmutableSet.copyOf(securityGroupNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getSecurityGroupNames() {
|
||||||
|
return Collections.unmodifiableSet(securityGroupNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ToStringHelper string() {
|
||||||
|
return super.string().add("securityGroupNames", securityGroupNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/**
|
||||||
|
* 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.nova.v1_1.extensions;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.ServerWithSecurityGroups;
|
||||||
|
import org.jclouds.openstack.services.Extension;
|
||||||
|
import org.jclouds.openstack.services.ServiceType;
|
||||||
|
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.ReturnNullOnNotFoundOr404;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides synchronous access to Servers with Security Groups.
|
||||||
|
*
|
||||||
|
* @see org.jclouds.openstack.nova.v1_1.features.ServerAsyncClient
|
||||||
|
* @see ServerWithSecurityGroupsClient
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.CREATESERVEREXT)
|
||||||
|
@SkipEncoding({'/', '='})
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
public interface ServerWithSecurityGroupsAsyncClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ServerWithSecurityGroupsClient#getServer(String)
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@SelectJson("server")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/os-create-server-ext/{id}")
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<ServerWithSecurityGroups> getServer(@PathParam("id") String id);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
* 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.nova.v1_1.extensions;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.ServerWithSecurityGroups;
|
||||||
|
import org.jclouds.openstack.services.Extension;
|
||||||
|
import org.jclouds.openstack.services.ServiceType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides synchronous access to Server details including security groups.
|
||||||
|
* <p/>
|
||||||
|
* NOTE: the equivalent to listServersInDetail() doesn't work, so not extending ServerClient at this time.
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
* @see org.jclouds.openstack.nova.v1_1.features.ServerClient
|
||||||
|
* @see ServerWithSecurityGroupsAsyncClient
|
||||||
|
*/
|
||||||
|
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.CREATESERVEREXT)
|
||||||
|
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||||
|
public interface ServerWithSecurityGroupsClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve details of the specified server, including security groups
|
||||||
|
*
|
||||||
|
* @param id id of the server
|
||||||
|
* @return server or null if not found
|
||||||
|
*/
|
||||||
|
ServerWithSecurityGroups getServer(String id);
|
||||||
|
|
||||||
|
}
|
|
@ -69,7 +69,9 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
|
||||||
.put(URI.create(ExtensionNamespaces.VOLUMES),
|
.put(URI.create(ExtensionNamespaces.VOLUMES),
|
||||||
URI.create("http://docs.openstack.org/compute/ext/volumes/api/v1.1"))
|
URI.create("http://docs.openstack.org/compute/ext/volumes/api/v1.1"))
|
||||||
.put(URI.create(ExtensionNamespaces.VIRTUAL_INTERFACES),
|
.put(URI.create(ExtensionNamespaces.VIRTUAL_INTERFACES),
|
||||||
URI.create("http://docs.openstack.org/compute/ext/virtual_interfaces/api/v1.1"))
|
URI.create("http://docs.openstack.org/compute/ext/virtual_interfaces/api/v1.1"))
|
||||||
|
.put(URI.create(ExtensionNamespaces.CREATESERVEREXT),
|
||||||
|
URI.create("http://docs.openstack.org/compute/ext/createserverext/api/v1.1"))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
* 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.nova.v1_1.extensions;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.ServerWithSecurityGroups;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientExpectTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests parsing and guice wiring of ServerExtraDataClient
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "ServerWithSecurityGroupsClientExpectTest")
|
||||||
|
public class ServerWithSecurityGroupsClientExpectTest extends BaseNovaClientExpectTest {
|
||||||
|
|
||||||
|
public void testGetServerWithSecurityGroups() {
|
||||||
|
URI endpoint = URI.create("https://compute.north.host/v1.1/3456/os-create-server-ext/8d0a6ca5-8849-4b3d-b86e-f24c92490ebb");
|
||||||
|
ServerWithSecurityGroupsClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint).build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResource("/server_with_security_groups.json")).build()
|
||||||
|
).getServerExtraDataExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
|
||||||
|
ServerWithSecurityGroups server = client.getServer("8d0a6ca5-8849-4b3d-b86e-f24c92490ebb");
|
||||||
|
assertEquals(server.getId(), "8d0a6ca5-8849-4b3d-b86e-f24c92490ebb");
|
||||||
|
assertEquals(server.getSecurityGroupNames(), ImmutableSet.of("default", "group1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetServerWithSecurityGroupsFailNotFound() {
|
||||||
|
URI endpoint = URI.create("https://compute.north.host/v1.1/3456/os-create-server-ext/8d0a6ca5-8849-4b3d-b86e-f24c92490ebb");
|
||||||
|
ServerWithSecurityGroupsClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
|
||||||
|
standardRequestBuilder(endpoint).build(),
|
||||||
|
standardResponseBuilder(404).build()
|
||||||
|
).getServerExtraDataExtensionForZone("az-1.region-a.geo-1").get();
|
||||||
|
assertNull(client.getServer("8d0a6ca5-8849-4b3d-b86e-f24c92490ebb"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
/**
|
||||||
|
* 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.nova.v1_1.extensions;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.domain.Resource;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.ServerWithSecurityGroups;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.features.ServerClient;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientLiveTest;
|
||||||
|
import org.testng.annotations.BeforeGroups;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of ServerWithSecurityGroupsClient
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", testName = "ServerWithSecurityGroupsClientLiveTest", singleThreaded = true)
|
||||||
|
public class ServerWithSecurityGroupsClientLiveTest extends BaseNovaClientLiveTest {
|
||||||
|
private ServerClient serverClient;
|
||||||
|
private Optional<ServerWithSecurityGroupsClient> clientOption;
|
||||||
|
private String zone;
|
||||||
|
|
||||||
|
@BeforeGroups(groups = {"integration", "live"})
|
||||||
|
@Override
|
||||||
|
public void setupContext() {
|
||||||
|
super.setupContext();
|
||||||
|
zone = Iterables.getLast(novaContext.getApi().getConfiguredZones(), "nova");
|
||||||
|
serverClient = novaContext.getApi().getServerClientForZone(zone);
|
||||||
|
clientOption = novaContext.getApi().getServerExtraDataExtensionForZone(zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetServer() {
|
||||||
|
if (clientOption.isPresent()) {
|
||||||
|
|
||||||
|
for (Resource server : serverClient.listServers()) {
|
||||||
|
ServerWithSecurityGroups serverWithGroups = clientOption.get().getServer(server.getId());
|
||||||
|
assertEquals(serverWithGroups.getId(), server.getId());
|
||||||
|
assertEquals(serverWithGroups.getName(), server.getName());
|
||||||
|
assertNotNull(serverWithGroups.getSecurityGroupNames());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new server to verify the groups work as expected
|
||||||
|
Server testServer = null;
|
||||||
|
try {
|
||||||
|
testServer = createServerInZone(zone);
|
||||||
|
|
||||||
|
ServerWithSecurityGroups results = clientOption.get().getServer(testServer.getId());
|
||||||
|
assertEquals(results.getId(), testServer.getId());
|
||||||
|
assertEquals(results.getSecurityGroupNames(), ImmutableSet.of("default"));
|
||||||
|
} finally {
|
||||||
|
if (testServer != null) {
|
||||||
|
serverClient.deleteServer(testServer.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
{"server": {"status": "ACTIVE", "updated": "2012-05-04T12:15:01Z", "hostId": "02c7c81e36024d2bfdb473cb762900138bc07777922479d3d4f8f690", "user_id": "1e8a56719e0d4ab4b7edb85c77f7290f", "name": "test", "links": [{"href": "http://172.16.89.148:8774/v2/4287930c796741aa898425f40832cb3c/servers/8d0a6ca5-8849-4b3d-b86e-f24c92490ebb", "rel": "self"}, {"href": "http://172.16.89.148:8774/4287930c796741aa898425f40832cb3c/servers/8d0a6ca5-8849-4b3d-b86e-f24c92490ebb", "rel": "bookmark"}], "created": "2012-05-04T12:14:57Z", "tenant_id": "4287930c796741aa898425f40832cb3c", "image": {"id": "ea17cc36-f7c9-40cd-b6bf-a952b74870f2", "links": [{"href": "http://172.16.89.148:8774/4287930c796741aa898425f40832cb3c/images/ea17cc36-f7c9-40cd-b6bf-a952b74870f2", "rel": "bookmark"}]}, "addresses": {"private": [{"version": 4, "addr": "10.0.0.8"}]}, "accessIPv4": "", "accessIPv6": "", "key_name": "", "progress": 0, "flavor": {"id": "1", "links": [{"href": "http://172.16.89.148:8774/4287930c796741aa898425f40832cb3c/flavors/1", "rel": "bookmark"}]}, "config_drive": "", "id": "8d0a6ca5-8849-4b3d-b86e-f24c92490ebb", "security_groups": [{"name": "default"},{"name": "group1"}], "metadata": {}}}
|
Loading…
Reference in New Issue