updated cloudstack to work with both security group and advanced networking

This commit is contained in:
Adrian Cole 2011-03-14 01:41:08 -07:00
parent f5fa2d983b
commit 94ac74d711
59 changed files with 2300 additions and 425 deletions

View File

@ -21,8 +21,10 @@ package org.jclouds.cloudstack;
import org.jclouds.cloudstack.features.AddressAsyncClient;
import org.jclouds.cloudstack.features.AsyncJobAsyncClient;
import org.jclouds.cloudstack.features.ConfigurationAsyncClient;
import org.jclouds.cloudstack.features.FirewallAsyncClient;
import org.jclouds.cloudstack.features.GuestOSAsyncClient;
import org.jclouds.cloudstack.features.HypervisorAsyncClient;
import org.jclouds.cloudstack.features.LoadBalancerAsyncClient;
import org.jclouds.cloudstack.features.NATAsyncClient;
import org.jclouds.cloudstack.features.NetworkAsyncClient;
@ -114,4 +116,16 @@ public interface CloudStackAsyncClient {
*/
@Delegate
GuestOSAsyncClient getGuestOSClient();
/**
* Provides asynchronous access to Hypervisor features.
*/
@Delegate
HypervisorAsyncClient getHypervisorClient();
/**
* Provides asynchronous access to Configuration features.
*/
@Delegate
ConfigurationAsyncClient getConfigurationClient();
}

View File

@ -23,8 +23,10 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.cloudstack.features.AddressClient;
import org.jclouds.cloudstack.features.AsyncJobClient;
import org.jclouds.cloudstack.features.ConfigurationClient;
import org.jclouds.cloudstack.features.FirewallClient;
import org.jclouds.cloudstack.features.GuestOSClient;
import org.jclouds.cloudstack.features.HypervisorClient;
import org.jclouds.cloudstack.features.LoadBalancerClient;
import org.jclouds.cloudstack.features.NATClient;
import org.jclouds.cloudstack.features.NetworkClient;
@ -117,4 +119,16 @@ public interface CloudStackClient {
*/
@Delegate
GuestOSClient getGuestOSClient();
/**
* Provides synchronous access to Hypervisor features.
*/
@Delegate
HypervisorClient getHypervisorClient();
/**
* Provides synchronous access to Configuration features.
*/
@Delegate
ConfigurationClient getConfigurationClient();
}

View File

@ -0,0 +1,70 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map.Entry;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.ws.rs.core.UriBuilder;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.utils.ModifyRequest;
import org.jclouds.rest.Binder;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.ImmutableMultimap.Builder;
/**
*
* @author Adrian Cole
*/
@Singleton
public class BindAccountSecurityGroupPairsToIndexedQueryParams implements Binder {
private final Provider<UriBuilder> uriBuilderProvider;
@Inject
public BindAccountSecurityGroupPairsToIndexedQueryParams(Provider<UriBuilder> uriBuilderProvider) {
this.uriBuilderProvider = checkNotNull(uriBuilderProvider, "uriBuilderProvider");
}
@SuppressWarnings("unchecked")
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
checkArgument(input instanceof Multimap<?, ?>, "this binder is only valid for Multimaps!");
Multimap<String, String> pairs = (Multimap<String, String>) checkNotNull(input, "account group pairs");
checkArgument(pairs.size() > 0, "you must specify at least one account, group pair");
UriBuilder builder = uriBuilderProvider.get();
builder.uri(request.getEndpoint());
Builder<String, String> map = ImmutableMultimap.<String, String> builder().putAll(
ModifyRequest.parseQueryToMap(request.getEndpoint().getQuery()));
int i = 0;
for (Entry<String, String> entry : pairs.entries())
map.put(String.format("usersecuritygrouplist[%d].account", i), entry.getKey()).put(
String.format("usersecuritygrouplist[%d].group", i++), entry.getValue());
builder.replaceQuery(ModifyRequest.makeQueryLine(map.build(), null));
return (R) request.toBuilder().endpoint(builder.build()).build();
}
}

View File

@ -0,0 +1,58 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.ws.rs.core.UriBuilder;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.utils.ModifyRequest;
import org.jclouds.rest.Binder;
import com.google.common.base.Joiner;
import com.google.common.collect.Iterables;
/**
*
* @author Adrian Cole
*/
@Singleton
public class BindCIDRsToCommaDelimitedQueryParam implements Binder {
private final Provider<UriBuilder> uriBuilderProvider;
@Inject
public BindCIDRsToCommaDelimitedQueryParam(Provider<UriBuilder> uriBuilderProvider) {
this.uriBuilderProvider = checkNotNull(uriBuilderProvider, "uriBuilderProvider");
}
@SuppressWarnings("unchecked")
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
checkArgument(input instanceof Iterable<?>, "this binder is only valid for Iterables!");
Iterable<String> cidrs = (Iterable<String>) checkNotNull(input, "cidr list");
checkArgument(Iterables.size(cidrs) > 0, "you must specify at least one cidr range");
return ModifyRequest.addQueryParam(request, "cidrlist", Joiner.on(',').join(cidrs), uriBuilderProvider.get());
}
}

View File

@ -27,10 +27,14 @@ import org.jclouds.cloudstack.features.AddressAsyncClient;
import org.jclouds.cloudstack.features.AddressClient;
import org.jclouds.cloudstack.features.AsyncJobAsyncClient;
import org.jclouds.cloudstack.features.AsyncJobClient;
import org.jclouds.cloudstack.features.ConfigurationAsyncClient;
import org.jclouds.cloudstack.features.ConfigurationClient;
import org.jclouds.cloudstack.features.FirewallAsyncClient;
import org.jclouds.cloudstack.features.FirewallClient;
import org.jclouds.cloudstack.features.GuestOSAsyncClient;
import org.jclouds.cloudstack.features.GuestOSClient;
import org.jclouds.cloudstack.features.HypervisorAsyncClient;
import org.jclouds.cloudstack.features.HypervisorClient;
import org.jclouds.cloudstack.features.LoadBalancerAsyncClient;
import org.jclouds.cloudstack.features.LoadBalancerClient;
import org.jclouds.cloudstack.features.NATAsyncClient;
@ -84,6 +88,8 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
.put(FirewallClient.class, FirewallAsyncClient.class)//
.put(LoadBalancerClient.class, LoadBalancerAsyncClient.class)//
.put(GuestOSClient.class, GuestOSAsyncClient.class)//
.put(HypervisorClient.class, HypervisorAsyncClient.class)//
.put(ConfigurationClient.class, ConfigurationAsyncClient.class)//
.build();
public CloudStackRestClientModule() {

View File

@ -0,0 +1,140 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.domain;
import com.google.gson.annotations.SerializedName;
/**
*
* @author Adrian Cole
*/
public class Capabilities {
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String cloudStackVersion;
private boolean securityGroupsEnabled;
private boolean canShareTemplates;
public Builder cloudStackVersion(String cloudStackVersion) {
this.cloudStackVersion = cloudStackVersion;
return this;
}
public Builder securityGroupsEnabled(boolean securityGroupsEnabled) {
this.securityGroupsEnabled = securityGroupsEnabled;
return this;
}
public Builder sharedTemplatesEnabled(boolean canShareTemplates) {
this.canShareTemplates = canShareTemplates;
return this;
}
public Capabilities build() {
return new Capabilities(cloudStackVersion, securityGroupsEnabled, canShareTemplates);
}
}
@SerializedName("cloudstackversion")
private String cloudStackVersion;
@SerializedName("securitygroupsenabled")
private boolean securityGroupsEnabled;
@SerializedName("userpublictemplateenabled")
private boolean canShareTemplates;
/**
* present only for serializer
*
*/
Capabilities() {
}
public Capabilities(String cloudStackVersion, boolean securityGroupsEnabled, boolean canShareTemplates) {
this.cloudStackVersion = cloudStackVersion;
this.securityGroupsEnabled = securityGroupsEnabled;
this.canShareTemplates = canShareTemplates;
}
/**
*
* @return version of the cloud stack
*/
public String getCloudStackVersion() {
return cloudStackVersion;
}
/**
*
* @return true if security groups support is enabled, false otherwise
*/
public boolean isSecurityGroupsEnabled() {
return securityGroupsEnabled;
}
/**
*
* @return true if user and domain admins can set templates to be shared, false otherwise
*/
public boolean isSharedTemplatesEnabled() {
return canShareTemplates;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (canShareTemplates ? 1231 : 1237);
result = prime * result + ((cloudStackVersion == null) ? 0 : cloudStackVersion.hashCode());
result = prime * result + (securityGroupsEnabled ? 1231 : 1237);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Capabilities other = (Capabilities) obj;
if (canShareTemplates != other.canShareTemplates)
return false;
if (cloudStackVersion == null) {
if (other.cloudStackVersion != null)
return false;
} else if (!cloudStackVersion.equals(other.cloudStackVersion))
return false;
if (securityGroupsEnabled != other.securityGroupsEnabled)
return false;
return true;
}
@Override
public String toString() {
return "[cloudStackVersion=" + cloudStackVersion + ", canShareTemplates=" + canShareTemplates
+ ", securityGroupsEnabled=" + securityGroupsEnabled + "]";
}
}

View File

@ -19,6 +19,8 @@
package org.jclouds.cloudstack.domain;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.gson.annotations.SerializedName;
/**
@ -33,13 +35,13 @@ public class IngressRule implements Comparable<IngressRule> {
public static class Builder {
private String account;
private String CIDR;
private int endPort;
private int ICMPCode;
private int ICMPType;
private int endPort = -1;
private int ICMPCode = -1;
private int ICMPType = -1;
private String protocol;
private long id;
private long id = -1;
private String securityGroupName;
private int startPort;
private int startPort = -1;
public Builder account(String account) {
this.account = account;
@ -95,28 +97,34 @@ public class IngressRule implements Comparable<IngressRule> {
@SerializedName("cidr")
private String CIDR;
@SerializedName("endport")
private int endPort;
private int endPort = -1;
@SerializedName("icmpcode")
private int ICMPCode;
private int ICMPCode = -1;
@SerializedName("icmptype")
private int ICMPType;
private int ICMPType = -1;
private String protocol;
@SerializedName("ruleid")
private long id;
private long id = -1;
@SerializedName("securitygroupname")
private String securityGroupName;
@SerializedName("startport")
private int startPort;
private int startPort = -1;
// for serialization
IngressRule() {
}
public IngressRule(String account, String cIDR, int endPort, int iCMPCode, int iCMPType, String protocol, long id,
public IngressRule(String account, String CIDR, int endPort, int iCMPCode, int iCMPType, String protocol, long id,
String securityGroupName, int startPort) {
if (account == null)
checkArgument(securityGroupName == null && CIDR != null,
"if you do not specify an account and security group, you must specify a CIDR range");
if (CIDR == null)
checkArgument(account != null && securityGroupName != null,
"if you do not specify an account and security group, you must specify a CIDR range");
this.account = account;
this.CIDR = cIDR;
this.CIDR = CIDR;
this.endPort = endPort;
this.ICMPCode = iCMPCode;
this.ICMPType = iCMPType;

View File

@ -287,7 +287,7 @@ public class Zone implements Comparable<Zone> {
/**
*
* @return true if this is an advanced network with security groups enabled, or a basic network.
* @return true if this zone has security groups enabled
*/
public boolean isSecurityGroupsEnabled() {
return securityGroupsEnabled;

View File

@ -0,0 +1,55 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.features;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.Capabilities;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.Unwrap;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to cloudstack via their REST API.
* <p/>
*
* @see ConfigurationClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api/TOC_User.html" />
* @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@QueryParams(keys = "response", values = "json")
public interface ConfigurationAsyncClient {
/**
* @see ConfigurationClient#listCapabilities
*/
@GET
@QueryParams(keys = "command", values = "listCapabilities")
@Unwrap(depth = 2)
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Capabilities> listCapabilities();
}

View File

@ -0,0 +1,45 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.features;
import java.util.concurrent.TimeUnit;
import org.jclouds.cloudstack.domain.Capabilities;
import org.jclouds.concurrent.Timeout;
/**
* Provides synchronous access to CloudStack Configuration features.
* <p/>
*
* @see ConfigurationAsyncClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api/TOC_User.html" />
* @author Adrian Cole
*/
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface ConfigurationClient {
/**
* Lists capabilities
*
* @return current capabilities of this cloud
*
*/
Capabilities listCapabilities();
}

View File

@ -19,6 +19,7 @@
package org.jclouds.cloudstack.features;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.Consumes;
@ -28,10 +29,13 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.OSType;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.functions.ParseIdToNameEntryFromHttpResponse;
import org.jclouds.cloudstack.functions.ParseIdToNameFromHttpResponse;
import org.jclouds.cloudstack.options.ListOSTypesOptions;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.Unwrap;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
@ -69,4 +73,23 @@ public interface GuestOSAsyncClient {
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<OSType> getOSType(@QueryParam("id") long id);
/**
* @see GuestOSClient#listOSCategories
*/
@GET
@QueryParams(keys = "command", values = "listOsCategories")
@ResponseParser(ParseIdToNameFromHttpResponse.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Map<Long, String>> listOSCategories();
/**
* @see GuestOSClient#getOSCategory
*/
@GET
@QueryParams(keys = "command", values = "listOsCategories")
@ResponseParser(ParseIdToNameEntryFromHttpResponse.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Map.Entry<Long, String>> getOSCategory(@QueryParam("id") long id);
}

View File

@ -19,6 +19,7 @@
package org.jclouds.cloudstack.features;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -53,4 +54,20 @@ public interface GuestOSClient {
* @return os type or null if not found
*/
OSType getOSType(long id);
/**
* Lists all supported OS categories for this cloud.
*
* @return os categories matching query, or empty set, if no categories are found
*/
Map<Long, String> listOSCategories();
/**
* get a specific os category by id
*
* @param id
* os category to get
* @return os category or null if not found
*/
Map.Entry<Long, String> getOSCategory(long id);
}

View File

@ -0,0 +1,66 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.features;
import java.util.Set;
import javax.ws.rs.GET;
import javax.ws.rs.QueryParam;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.functions.ParseNamesFromHttpResponse;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to cloudstack via their REST API.
* <p/>
*
* @see AsyncJobClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api/TOC_User.html" />
* @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@QueryParams(keys = "response", values = "json")
public interface HypervisorAsyncClient {
/**
* @see HypervisorClient#listHypervisors
*/
@GET
@QueryParams(keys = "command", values = "listHypervisors")
@ResponseParser(ParseNamesFromHttpResponse.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listHypervisors();
/**
* @see HypervisorClient#listHypervisorsInZone
*/
@GET
@QueryParams(keys = "command", values = "listHypervisors")
@ResponseParser(ParseNamesFromHttpResponse.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listHypervisorsInZone(@QueryParam("zoneid") long zoneId);
}

View File

@ -0,0 +1,53 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.features;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
/**
* Provides synchronous access to CloudStack Operating System features.
* <p/>
*
* @see GuestOSAsyncClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api/TOC_User.html" />
* @author Adrian Cole
*/
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface HypervisorClient {
/**
* Lists all supported hypervisors for this cloud.
*
* @return hypervisors, or empty set, if no hypervisors are found
*/
Set<String> listHypervisors();
/**
* Lists all supported hypervisors for this zone.
*
* @param zoneId
* the zone id for listing hypervisors.
* @return hypervisors in the zone, or empty set, if no hypervisors are found
*/
Set<String> listHypervisorsInZone(long zoneId);
}

View File

@ -26,9 +26,13 @@ import javax.ws.rs.GET;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.binders.BindAccountSecurityGroupPairsToIndexedQueryParams;
import org.jclouds.cloudstack.binders.BindCIDRsToCommaDelimitedQueryParam;
import org.jclouds.cloudstack.domain.SecurityGroup;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.options.AccountInDomainOptions;
import org.jclouds.cloudstack.options.ListSecurityGroupsOptions;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
@ -37,6 +41,7 @@ import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import com.google.common.collect.Multimap;
import com.google.common.util.concurrent.ListenableFuture;
/**
@ -80,6 +85,70 @@ public interface SecurityGroupAsyncClient {
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<SecurityGroup> createSecurityGroup(@QueryParam("name") String name);
/**
* @see SecurityGroupClient#authorizeIngressPortsToCIDRs
*/
@GET
@QueryParams(keys = "command", values = "authorizeSecurityGroupIngress")
@Unwrap(depth = 2)
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Long> authorizeIngressPortsToCIDRs(@QueryParam("securitygroupid") long securityGroupId,
@QueryParam("protocol") String protocol, @QueryParam("startport") int startPort,
@QueryParam("endport") int endPort,
@BinderParam(BindCIDRsToCommaDelimitedQueryParam.class) Iterable<String> cidrList,
AccountInDomainOptions... options);
/**
* @see SecurityGroupClient#authorizeIngressPortsToSecurityGroups
*/
@GET
@QueryParams(keys = "command", values = "authorizeSecurityGroupIngress")
@Unwrap(depth = 2)
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Long> authorizeIngressPortsToSecurityGroups(
@QueryParam("securitygroupid") long securityGroupId,
@QueryParam("protocol") String protocol,
@QueryParam("startport") int startPort,
@QueryParam("endport") int endPort,
@BinderParam(BindAccountSecurityGroupPairsToIndexedQueryParams.class) Multimap<String, String> accountToGroup,
AccountInDomainOptions... options);
/**
* @see SecurityGroupClient#authorizeIngressICMPToCIDRs
*/
@GET
@QueryParams(keys = { "command", "protocol" }, values = { "authorizeSecurityGroupIngress", "ICMP" })
@Unwrap(depth = 2)
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Long> authorizeIngressICMPToCIDRs(@QueryParam("securitygroupid") long securityGroupId,
@QueryParam("icmpcode") int ICMPCode, @QueryParam("icmptype") int ICMPType,
@BinderParam(BindCIDRsToCommaDelimitedQueryParam.class) Iterable<String> cidrList,
AccountInDomainOptions... options);
/**
* @see SecurityGroupClient#authorizeIngressICMPToSecurityGroups
*/
@GET
@QueryParams(keys = { "command", "protocol" }, values = { "authorizeSecurityGroupIngress", "ICMP" })
@Unwrap(depth = 2)
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Long> authorizeIngressICMPToSecurityGroups(
@QueryParam("securitygroupid") long securityGroupId,
@QueryParam("icmpcode") int ICMPCode,
@QueryParam("icmptype") int ICMPType,
@BinderParam(BindAccountSecurityGroupPairsToIndexedQueryParams.class) Multimap<String, String> accountToGroup,
AccountInDomainOptions... options);
/**
* @see SecurityGroupClient#revokeIngressRule
*/
@GET
@QueryParams(keys = "command", values = "revokeSecurityGroupIngress")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
@Unwrap(depth = 2)
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Long> revokeIngressRule(@QueryParam("id") long id, AccountInDomainOptions... options);
/**
* @see SecurityGroupClient#deleteSecurityGroup
*/

View File

@ -23,9 +23,12 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jclouds.cloudstack.domain.SecurityGroup;
import org.jclouds.cloudstack.options.AccountInDomainOptions;
import org.jclouds.cloudstack.options.ListSecurityGroupsOptions;
import org.jclouds.concurrent.Timeout;
import com.google.common.collect.Multimap;
/**
* Provides synchronous access to CloudStack security group features.
* <p/>
@ -45,6 +48,82 @@ public interface SecurityGroupClient {
*/
Set<SecurityGroup> listSecurityGroups(ListSecurityGroupsOptions... options);
/**
* Authorizes a particular TCP or UDP ingress rule for this security group
*
* @param securityGroupId
* The ID of the security group
* @param protocol
* tcp or udp
* @param startPort
* start port for this ingress rule
* @param endPort
* end port for this ingress rule
* @param cidrList
* the cidr list associated
* @return response relating to the creation of this ingress rule
*/
long authorizeIngressPortsToCIDRs(long securityGroupId, String protocol, int startPort, int endPort,
Iterable<String> cidrList, AccountInDomainOptions... options);
/**
* Authorizes a particular TCP or UDP ingress rule for this security group
*
* @param securityGroupId
* The ID of the security group
* @param protocol
* tcp or udp
* @param startPort
* start port for this ingress rule
* @param endPort
* end port for this ingress rule
* @param accountToGroup
* mapping of account names to security groups you wish to authorize
* @return response relating to the creation of this ingress rule
*/
long authorizeIngressPortsToSecurityGroups(long securityGroupId, String protocol, int startPort,
int endPort, Multimap<String, String> accountToGroup, AccountInDomainOptions... options);
/**
* Authorizes a particular ICMP ingress rule for this security group
*
* @param securityGroupId
* The ID of the security group
* @param ICMPCode
* type of the icmp message being sent
* @param ICMPType
* error code for this icmp message
* @param cidrList
* the cidr list associated
* @return response relating to the creation of this ingress rule
*/
long authorizeIngressICMPToCIDRs(long securityGroupId, int ICMPCode, int ICMPType,
Iterable<String> cidrList, AccountInDomainOptions... options);
/**
* Authorizes a particular ICMP ingress rule for this security group
*
* @param securityGroupId
* The ID of the security group
* @param ICMPCode
* type of the icmp message being sent
* @param ICMPType
* error code for this icmp message
* @param accountToGroup
* mapping of account names to security groups you wish to authorize
* @return response relating to the creation of this ingress rule
*/
long authorizeIngressICMPToSecurityGroups(long securityGroupId, int ICMPCode, int ICMPType,
Multimap<String, String> accountToGroup, AccountInDomainOptions... options);
/**
* Deletes a particular ingress rule from this security group
*
* @param id The ID of the ingress rule
* @param options scope of the rule.
*/
long revokeIngressRule(long id, AccountInDomainOptions... options);;
/**
* get a specific security group by id
*

View File

@ -78,6 +78,6 @@ public interface TemplateAsyncClient {
@Unwrap(depth = 3, edgeCollection = Set.class)
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Template> getTemplate(@QueryParam("id") long id);
ListenableFuture<Template> getTemplateInZone(@QueryParam("zoneid") long zoneId, @QueryParam("id") long id);
}

View File

@ -57,9 +57,11 @@ public interface TemplateClient {
/**
* get a specific template by id
*
* @param zoneId
* zone template is defined in
* @param id
* template to get
* @return template or null if not found
*/
Template getTemplate(long id);
Template getTemplateInZone(long zoneId, long id);
}

View File

@ -21,6 +21,10 @@ package org.jclouds.cloudstack.filters;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Comparator;
import java.util.Map;
import java.util.Map.Entry;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
@ -43,12 +47,10 @@ import org.jclouds.rest.RequestSigner;
import org.jclouds.util.Strings2;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
import com.google.common.collect.ImmutableMultimap.Builder;
/**
*
@ -118,14 +120,15 @@ public class QuerySigner implements HttpRequestFilter, RequestSigner {
@VisibleForTesting
public String createStringToSign(HttpRequest request, Multimap<String, String> decodedParams) {
utils.logRequest(signatureLog, request, ">>");
Builder<String, String> builder = ImmutableMultimap.<String, String> builder();
for (String key : ImmutableSortedSet.copyOf(decodedParams.keySet()))
builder.put(key.toLowerCase(), Iterables.getOnlyElement(decodedParams.get(key)).toLowerCase());
ImmutableSortedSet.Builder<String> builder = ImmutableSortedSet.<String> naturalOrder();
for (Entry<String, String> entry : decodedParams.entries())
builder.add(entry.getKey().toLowerCase() + "=" + Strings2.urlEncode(entry.getValue().toLowerCase()));
String stringToSign = ModifyRequest.makeQueryLine(builder.build(), null);
String stringToSign = Joiner.on('&').join(builder.build());
if (signatureWire.enabled())
signatureWire.output(stringToSign);
return stringToSign;
}

View File

@ -0,0 +1,53 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import javax.inject.Singleton;
import org.jclouds.http.HttpResponse;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.inject.Inject;
/**
*
* @author Adrian Cole
*/
@Singleton
public class ParseIdToNameEntryFromHttpResponse implements Function<HttpResponse, Map.Entry<Long, String>> {
private final ParseIdToNameFromHttpResponse parser;
@Inject
public ParseIdToNameEntryFromHttpResponse(ParseIdToNameFromHttpResponse parser) {
this.parser = checkNotNull(parser, "parser");
}
public Map.Entry<Long, String> apply(HttpResponse response) {
checkNotNull(response, "response");
Map<Long, String> toParse = parser.apply(response);
checkNotNull(toParse, "parsed result from %s", response);
return Iterables.getFirst(toParse.entrySet(), null);
}
}

View File

@ -0,0 +1,93 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import java.util.Set;
import javax.inject.Singleton;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.inject.Inject;
/**
*
* @author Adrian Cole
*/
@Singleton
public class ParseIdToNameFromHttpResponse implements Function<HttpResponse, Map<Long, String>> {
private final UnwrapOnlyNestedJsonValue<Set<IdName>> parser;
private static class IdName {
private long id;
private String name;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
IdName other = (IdName) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
@Inject
public ParseIdToNameFromHttpResponse(UnwrapOnlyNestedJsonValue<Set<IdName>> parser) {
this.parser = checkNotNull(parser, "parser");
}
public Map<Long, String> apply(HttpResponse response) {
checkNotNull(response, "response");
Set<IdName> toParse = parser.apply(response);
checkNotNull(toParse, "parsed result from %s", response);
Builder<Long, String> builder = ImmutableMap.<Long, String> builder();
for (IdName entry : toParse)
builder.put(entry.id, entry.name);
return builder.build();
}
}

View File

@ -0,0 +1,88 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set;
import javax.inject.Singleton;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.inject.Inject;
/**
*
* @author Adrian Cole
*/
@Singleton
public class ParseNamesFromHttpResponse implements Function<HttpResponse, Set<String>> {
private final UnwrapOnlyNestedJsonValue<Set<Name>> parser;
private static class Name {
private String name;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Name other = (Name) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
@Inject
public ParseNamesFromHttpResponse(UnwrapOnlyNestedJsonValue<Set<Name>> parser) {
this.parser = checkNotNull(parser, "parser");
}
public Set<String> apply(HttpResponse response) {
checkNotNull(response, "response");
Set<Name> toParse = parser.apply(response);
checkNotNull(toParse, "parsed result from %s", response);
Builder<String> builder = ImmutableSet.<String> builder();
for (Name entry : toParse)
builder.add(entry.name);
return builder.build();
}
}

View File

@ -0,0 +1,76 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.options;
import org.jclouds.http.options.BaseHttpRequestOptions;
import com.google.common.collect.ImmutableSet;
/**
* Options for services that apply to accounts in domains
*
* @see <a href="http://download.cloud.com/releases/2.2.0/api/TOC_User.html" />
* @author Adrian Cole
*/
public class AccountInDomainOptions extends BaseHttpRequestOptions {
public static final AccountInDomainOptions NONE = new AccountInDomainOptions();
/**
*
* @param account
* an optional account for the resource
* @param domain
* domain id
*/
public AccountInDomainOptions accountInDomain(String account, long domain) {
this.queryParameters.replaceValues("account", ImmutableSet.of(account));
this.queryParameters.replaceValues("domainid", ImmutableSet.of(domain + ""));
return this;
}
/**
* @param domainId
* The domain for the resource
*/
public AccountInDomainOptions domainId(long domainId) {
this.queryParameters.replaceValues("domainid", ImmutableSet.of(domainId + ""));
return this;
}
public static class Builder {
/**
* @see AccountInDomainOptions#accountInDomain
*/
public static AccountInDomainOptions accountInDomain(String account, long domain) {
AccountInDomainOptions options = new AccountInDomainOptions();
return options.accountInDomain(account, domain);
}
/**
* @see AccountInDomainOptions#domainId
*/
public static AccountInDomainOptions domainId(long domainId) {
AccountInDomainOptions options = new AccountInDomainOptions();
return options.domainId(domainId);
}
}
}

View File

@ -19,8 +19,6 @@
package org.jclouds.cloudstack.options;
import org.jclouds.http.options.BaseHttpRequestOptions;
import com.google.common.collect.ImmutableSet;
/**
@ -29,23 +27,10 @@ import com.google.common.collect.ImmutableSet;
* @see <a href="http://download.cloud.com/releases/2.2.0/api/user/associateIpAddress.html" />
* @author Adrian Cole
*/
public class AssociateIPAddressOptions extends BaseHttpRequestOptions {
public class AssociateIPAddressOptions extends AccountInDomainOptions {
public static final AssociateIPAddressOptions NONE = new AssociateIPAddressOptions();
/**
*
* @param account
* an optional account for the ip address
* @param domain
* domain id
*/
public AssociateIPAddressOptions accountInDomain(String account, long domain) {
this.queryParameters.replaceValues("account", ImmutableSet.of(account));
this.queryParameters.replaceValues("domainid", ImmutableSet.of(domain + ""));
return this;
}
/**
* @param networkId
* The network this ip address should be associated to.
@ -57,6 +42,15 @@ public class AssociateIPAddressOptions extends BaseHttpRequestOptions {
}
public static class Builder {
/**
* @see AssociateIPAddressOptions#networkId
*/
public static AssociateIPAddressOptions networkId(long networkId) {
AssociateIPAddressOptions options = new AssociateIPAddressOptions();
return options.networkId(networkId);
}
/**
* @see AssociateIPAddressOptions#accountInDomain
*/
@ -66,11 +60,27 @@ public class AssociateIPAddressOptions extends BaseHttpRequestOptions {
}
/**
* @see AssociateIPAddressOptions#networkId
* @see AssociateIPAddressOptions#domainId
*/
public static AssociateIPAddressOptions networkId(long networkId) {
public static AssociateIPAddressOptions domainId(long domainId) {
AssociateIPAddressOptions options = new AssociateIPAddressOptions();
return options.networkId(networkId);
return options.domainId(domainId);
}
}
/**
* {@inheritDoc}
*/
@Override
public AssociateIPAddressOptions accountInDomain(String account, long domain) {
return AssociateIPAddressOptions.class.cast(super.accountInDomain(account, domain));
}
/**
* {@inheritDoc}
*/
@Override
public AssociateIPAddressOptions domainId(long domainId) {
return AssociateIPAddressOptions.class.cast(super.domainId(domainId));
}
}

View File

@ -23,7 +23,6 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.encryption.internal.Base64;
import org.jclouds.http.options.BaseHttpRequestOptions;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSet;
@ -34,23 +33,10 @@ import com.google.common.collect.ImmutableSet;
* @see <a href="http://download.cloud.com/releases/2.2.0/api/user/deployVirtualMachine.html" />
* @author Adrian Cole
*/
public class DeployVirtualMachineOptions extends BaseHttpRequestOptions {
public class DeployVirtualMachineOptions extends AccountInDomainOptions {
public static final DeployVirtualMachineOptions NONE = new DeployVirtualMachineOptions();
/**
*
* @param account
* an optional account for the virtual machine
* @param domain
* domain id
*/
public DeployVirtualMachineOptions accountInDomain(String account, long domain) {
this.queryParameters.replaceValues("account", ImmutableSet.of(account));
this.queryParameters.replaceValues("domainid", ImmutableSet.of(domain + ""));
return this;
}
/**
* the ID of the disk offering for the virtual machine. If the template is of ISO format, the
* diskOfferingId is for the root disk volume. Otherwise this parameter is used to dinidcate the
@ -176,13 +162,6 @@ public class DeployVirtualMachineOptions extends BaseHttpRequestOptions {
}
public static class Builder {
/**
* @see DeployVirtualMachineOptions#accountInDomain
*/
public static DeployVirtualMachineOptions accountInDomain(String account, long domain) {
DeployVirtualMachineOptions options = new DeployVirtualMachineOptions();
return options.accountInDomain(account, domain);
}
/**
* @see DeployVirtualMachineOptions#diskOfferingId
@ -279,5 +258,37 @@ public class DeployVirtualMachineOptions extends BaseHttpRequestOptions {
DeployVirtualMachineOptions options = new DeployVirtualMachineOptions();
return options.userData(unencodedData);
}
/**
* @see DeployVirtualMachineOptions#accountInDomain
*/
public static DeployVirtualMachineOptions accountInDomain(String account, long domain) {
DeployVirtualMachineOptions options = new DeployVirtualMachineOptions();
return options.accountInDomain(account, domain);
}
/**
* @see DeployVirtualMachineOptions#domainId
*/
public static DeployVirtualMachineOptions domainId(long domainId) {
DeployVirtualMachineOptions options = new DeployVirtualMachineOptions();
return options.domainId(domainId);
}
}
/**
* {@inheritDoc}
*/
@Override
public DeployVirtualMachineOptions accountInDomain(String account, long domain) {
return DeployVirtualMachineOptions.class.cast(super.accountInDomain(account, domain));
}
/**
* {@inheritDoc}
*/
@Override
public DeployVirtualMachineOptions domainId(long domainId) {
return DeployVirtualMachineOptions.class.cast(super.domainId(domainId));
}
}

View File

@ -25,7 +25,6 @@ import java.util.Date;
import org.jclouds.date.DateService;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.options.BaseHttpRequestOptions;
import com.google.common.collect.ImmutableSet;
@ -35,40 +34,18 @@ import com.google.common.collect.ImmutableSet;
* @see <a href="http://download.cloud.com/releases/2.2.0/api/user/listAsyncJobs.html" />
* @author Adrian Cole
*/
public class ListAsyncJobsOptions extends BaseHttpRequestOptions {
public class ListAsyncJobsOptions extends AccountInDomainOptions {
private final static DateService dateService = new SimpleDateFormatDateService();
public static final ListAsyncJobsOptions NONE = new ListAsyncJobsOptions();
/**
*
* @param account
* an optional account for the virtual machine
* @param domain
* domain id
*/
public ListAsyncJobsOptions accountInDomain(String account, long domain) {
this.queryParameters.replaceValues("account", ImmutableSet.of(account + ""));
return domainId(domain);
}
/**
* @param domainId
* the ID of the domain associated with the asyncJob
*/
public ListAsyncJobsOptions domainId(long domainId) {
this.queryParameters.replaceValues("domainid", ImmutableSet.of(domainId + ""));
return this;
}
/**
* @param startDate
* the start date of the async job
*/
public ListAsyncJobsOptions startDate(Date startDate) {
this.queryParameters.replaceValues("startdate",
ImmutableSet.of(dateService.iso8601SecondsDateFormat(checkNotNull(startDate, "startDate"))));
this.queryParameters.replaceValues("startdate", ImmutableSet.of(dateService
.iso8601SecondsDateFormat(checkNotNull(startDate, "startDate"))));
return this;
}
@ -99,4 +76,20 @@ public class ListAsyncJobsOptions extends BaseHttpRequestOptions {
}
}
/**
* {@inheritDoc}
*/
@Override
public ListAsyncJobsOptions accountInDomain(String account, long domain) {
return ListAsyncJobsOptions.class.cast(super.accountInDomain(account, domain));
}
/**
* {@inheritDoc}
*/
@Override
public ListAsyncJobsOptions domainId(long domainId) {
return ListAsyncJobsOptions.class.cast(super.domainId(domainId));
}
}

View File

@ -19,8 +19,6 @@
package org.jclouds.cloudstack.options;
import org.jclouds.http.options.BaseHttpRequestOptions;
import com.google.common.collect.ImmutableSet;
/**
@ -29,7 +27,7 @@ import com.google.common.collect.ImmutableSet;
* @see <a href="http://download.cloud.com/releases/2.2.0/api/user/listIpForwardingRules.html" />
* @author Adrian Cole
*/
public class ListIPForwardingRulesOptions extends BaseHttpRequestOptions {
public class ListIPForwardingRulesOptions extends AccountInDomainOptions {
public static final ListIPForwardingRulesOptions NONE = new ListIPForwardingRulesOptions();
@ -42,31 +40,6 @@ public class ListIPForwardingRulesOptions extends BaseHttpRequestOptions {
return this;
}
/**
* @param domainId
* Lists all rules for this id. If used with the account parameter, returns all rules
* for an account in the specified domain ID.
*/
public ListIPForwardingRulesOptions domainId(long domainId) {
this.queryParameters.replaceValues("domainid", ImmutableSet.of(domainId + ""));
return this;
}
/**
* @param account
* the account associated with the ip forwarding rule. Must be used with the domainId
* parameter.
*
* @param domain
* domain id
*/
public ListIPForwardingRulesOptions accountInDomain(String account, long domain) {
this.queryParameters.replaceValues("account", ImmutableSet.of(account));
this.queryParameters.replaceValues("domainid", ImmutableSet.of(domain + ""));
return this;
}
/**
* @param IPAddressId
* list the rule belonging to this public ip address
@ -129,4 +102,20 @@ public class ListIPForwardingRulesOptions extends BaseHttpRequestOptions {
return options.virtualMachineId(virtualMachineId);
}
}
/**
* {@inheritDoc}
*/
@Override
public ListIPForwardingRulesOptions accountInDomain(String account, long domain) {
return ListIPForwardingRulesOptions.class.cast(super.accountInDomain(account, domain));
}
/**
* {@inheritDoc}
*/
@Override
public ListIPForwardingRulesOptions domainId(long domainId) {
return ListIPForwardingRulesOptions.class.cast(super.domainId(domainId));
}
}

View File

@ -19,8 +19,6 @@
package org.jclouds.cloudstack.options;
import org.jclouds.http.options.BaseHttpRequestOptions;
import com.google.common.collect.ImmutableSet;
/**
@ -29,7 +27,7 @@ import com.google.common.collect.ImmutableSet;
* @see <a href="http://download.cloud.com/releases/2.2.0/api/user/listLoadBalancerRules.html" />
* @author Adrian Cole
*/
public class ListLoadBalancerRulesOptions extends BaseHttpRequestOptions {
public class ListLoadBalancerRulesOptions extends AccountInDomainOptions {
public static final ListLoadBalancerRulesOptions NONE = new ListLoadBalancerRulesOptions();
@ -42,31 +40,6 @@ public class ListLoadBalancerRulesOptions extends BaseHttpRequestOptions {
return this;
}
/**
* @param domainId
* Lists all rules for this id. If used with the account parameter, returns all rules
* for an account in the specified domain ID.
*/
public ListLoadBalancerRulesOptions domainId(long domainId) {
this.queryParameters.replaceValues("domainid", ImmutableSet.of(domainId + ""));
return this;
}
/**
* @param account
* the account associated with the load balancing rule. Must be used with the domainId
* parameter.
*
* @param domain
* domain id
*/
public ListLoadBalancerRulesOptions accountInDomain(String account, long domain) {
this.queryParameters.replaceValues("account", ImmutableSet.of(account));
this.queryParameters.replaceValues("domainid", ImmutableSet.of(domain + ""));
return this;
}
/**
* @param name
* the name of the load balancer rule
@ -145,4 +118,20 @@ public class ListLoadBalancerRulesOptions extends BaseHttpRequestOptions {
return options.virtualMachineId(virtualMachineId);
}
}
/**
* {@inheritDoc}
*/
@Override
public ListLoadBalancerRulesOptions accountInDomain(String account, long domain) {
return ListLoadBalancerRulesOptions.class.cast(super.accountInDomain(account, domain));
}
/**
* {@inheritDoc}
*/
@Override
public ListLoadBalancerRulesOptions domainId(long domainId) {
return ListLoadBalancerRulesOptions.class.cast(super.domainId(domainId));
}
}

View File

@ -19,8 +19,6 @@
package org.jclouds.cloudstack.options;
import org.jclouds.http.options.BaseHttpRequestOptions;
import com.google.common.collect.ImmutableSet;
/**
@ -29,35 +27,10 @@ import com.google.common.collect.ImmutableSet;
* @see <a href="http://download.cloud.com/releases/2.2.0/api/user/listIpForwardingRules.html" />
* @author Adrian Cole
*/
public class ListPortForwardingRulesOptions extends BaseHttpRequestOptions {
public class ListPortForwardingRulesOptions extends AccountInDomainOptions {
public static final ListPortForwardingRulesOptions NONE = new ListPortForwardingRulesOptions();
/**
* @param domainId
* Lists all rules for this id. If used with the account parameter, returns all rules
* for an account in the specified domain ID.
*/
public ListPortForwardingRulesOptions domainId(long domainId) {
this.queryParameters.replaceValues("domainid", ImmutableSet.of(domainId + ""));
return this;
}
/**
* @param account
* the account associated with the port forwarding rule. Must be used with the domainId
* parameter.
*
* @param domain
* domain id
*/
public ListPortForwardingRulesOptions accountInDomain(String account, long domain) {
this.queryParameters.replaceValues("account", ImmutableSet.of(account));
this.queryParameters.replaceValues("domainid", ImmutableSet.of(domain + ""));
return this;
}
/**
* @param IPAddressId
* list the rule belonging to this public ip address
@ -94,4 +67,20 @@ public class ListPortForwardingRulesOptions extends BaseHttpRequestOptions {
}
}
/**
* {@inheritDoc}
*/
@Override
public ListPortForwardingRulesOptions accountInDomain(String account, long domain) {
return ListPortForwardingRulesOptions.class.cast(super.accountInDomain(account, domain));
}
/**
* {@inheritDoc}
*/
@Override
public ListPortForwardingRulesOptions domainId(long domainId) {
return ListPortForwardingRulesOptions.class.cast(super.domainId(domainId));
}
}

View File

@ -19,8 +19,6 @@
package org.jclouds.cloudstack.options;
import org.jclouds.http.options.BaseHttpRequestOptions;
import com.google.common.collect.ImmutableSet;
/**
@ -29,7 +27,7 @@ import com.google.common.collect.ImmutableSet;
* @see <a href="http://download.cloud.com/releases/2.2.0/api/user/listIPAddresses.html" />
* @author Adrian Cole
*/
public class ListPublicIPAddressesOptions extends BaseHttpRequestOptions {
public class ListPublicIPAddressesOptions extends AccountInDomainOptions {
public static final ListPublicIPAddressesOptions NONE = new ListPublicIPAddressesOptions();
@ -42,29 +40,6 @@ public class ListPublicIPAddressesOptions extends BaseHttpRequestOptions {
return this;
}
/**
* @param domainId
* lists all public IP addresses by domain ID. If used with the account parameter,
* lists all public IP addresses by account for specified domain.
*/
public ListPublicIPAddressesOptions domainId(long domainId) {
this.queryParameters.replaceValues("domainid", ImmutableSet.of(domainId + ""));
return this;
}
/**
*
* @param account
* account id
* @param domain
* domain id
*/
public ListPublicIPAddressesOptions accountInDomain(String account, long domain) {
this.queryParameters.replaceValues("account", ImmutableSet.of(account));
return domainId(domain);
}
/**
* @param allocatedOnly
* limits search results to allocated public IP addresses
@ -197,4 +172,20 @@ public class ListPublicIPAddressesOptions extends BaseHttpRequestOptions {
return options.usesVirtualNetwork(usesVirtualNetwork);
}
}
/**
* {@inheritDoc}
*/
@Override
public ListPublicIPAddressesOptions accountInDomain(String account, long domain) {
return ListPublicIPAddressesOptions.class.cast(super.accountInDomain(account, domain));
}
/**
* {@inheritDoc}
*/
@Override
public ListPublicIPAddressesOptions domainId(long domainId) {
return ListPublicIPAddressesOptions.class.cast(super.domainId(domainId));
}
}

View File

@ -19,8 +19,6 @@
package org.jclouds.cloudstack.options;
import org.jclouds.http.options.BaseHttpRequestOptions;
import com.google.common.collect.ImmutableSet;
/**
@ -29,7 +27,7 @@ import com.google.common.collect.ImmutableSet;
* @see <a href="http://download.cloud.com/releases/2.2.0/api/user/listSecurityGroups.html" />
* @author Adrian Cole
*/
public class ListSecurityGroupsOptions extends BaseHttpRequestOptions {
public class ListSecurityGroupsOptions extends AssociateIPAddressOptions {
public static final ListSecurityGroupsOptions NONE = new ListSecurityGroupsOptions();
@ -42,25 +40,6 @@ public class ListSecurityGroupsOptions extends BaseHttpRequestOptions {
return this;
}
/**
* @param domainId
* the ID of the domain associated with the security group
*/
public ListSecurityGroupsOptions domainId(long domainId) {
this.queryParameters.replaceValues("domainid", ImmutableSet.of(domainId + ""));
return this;
}
/**
* @param account
* the security group account
*/
public ListSecurityGroupsOptions account(String account) {
this.queryParameters.replaceValues("account", ImmutableSet.of(account));
return this;
}
/**
* @param securityGroupName
* lists security groups by name
@ -83,14 +62,6 @@ public class ListSecurityGroupsOptions extends BaseHttpRequestOptions {
public static class Builder {
/**
* @see ListSecurityGroupsOptions#account
*/
public static ListSecurityGroupsOptions account(String account) {
ListSecurityGroupsOptions options = new ListSecurityGroupsOptions();
return options.account(account);
}
/**
* @see ListSecurityGroupsOptions#named
*/
@ -99,14 +70,6 @@ public class ListSecurityGroupsOptions extends BaseHttpRequestOptions {
return options.named(securityGroupName);
}
/**
* @see ListSecurityGroupsOptions#domainId
*/
public static ListSecurityGroupsOptions domainId(long id) {
ListSecurityGroupsOptions options = new ListSecurityGroupsOptions();
return options.domainId(id);
}
/**
* @see ListSecurityGroupsOptions#id
*/
@ -122,5 +85,37 @@ public class ListSecurityGroupsOptions extends BaseHttpRequestOptions {
ListSecurityGroupsOptions options = new ListSecurityGroupsOptions();
return options.virtualMachineId(virtualMachineId);
}
/**
* @see DeployVirtualMachineOptions#accountInDomain
*/
public static ListSecurityGroupsOptions accountInDomain(String account, long domain) {
ListSecurityGroupsOptions options = new ListSecurityGroupsOptions();
return options.accountInDomain(account, domain);
}
/**
* @see DeployVirtualMachineOptions#domainId
*/
public static ListSecurityGroupsOptions domainId(long domainId) {
ListSecurityGroupsOptions options = new ListSecurityGroupsOptions();
return options.domainId(domainId);
}
}
/**
* {@inheritDoc}
*/
@Override
public ListSecurityGroupsOptions accountInDomain(String account, long domain) {
return ListSecurityGroupsOptions.class.cast(super.accountInDomain(account, domain));
}
/**
* {@inheritDoc}
*/
@Override
public ListSecurityGroupsOptions domainId(long domainId) {
return ListSecurityGroupsOptions.class.cast(super.domainId(domainId));
}
}

View File

@ -20,7 +20,6 @@
package org.jclouds.cloudstack.options;
import org.jclouds.cloudstack.domain.TemplateFilter;
import org.jclouds.http.options.BaseHttpRequestOptions;
import com.google.common.collect.ImmutableSet;
@ -30,7 +29,7 @@ import com.google.common.collect.ImmutableSet;
* @see <a href="http://download.cloud.com/releases/2.2.0/api/user/listTemplates.html" />
* @author Adrian Cole
*/
public class ListTemplatesOptions extends BaseHttpRequestOptions {
public class ListTemplatesOptions extends AccountInDomainOptions {
public ListTemplatesOptions() {
filter(TemplateFilter.EXECUTABLE);
}
@ -55,18 +54,6 @@ public class ListTemplatesOptions extends BaseHttpRequestOptions {
return this;
}
/**
*
* @param account
* account id
* @param domain
* domain id
*/
public ListTemplatesOptions accountInDomain(String account, long domain) {
this.queryParameters.replaceValues("account", ImmutableSet.of(account + ""));
return domainId(domain);
}
/**
* @param name
* the template name
@ -76,17 +63,6 @@ public class ListTemplatesOptions extends BaseHttpRequestOptions {
return this;
}
/**
* @param domainId
* list all templates in specified domain. If used with the account parameter, lists
* all templates for an account in the specified domain.
*/
public ListTemplatesOptions domainId(long domainId) {
this.queryParameters.replaceValues("domainid", ImmutableSet.of(domainId + ""));
return this;
}
/**
* @param zoneId
* list templates by zoneId.
@ -165,4 +141,19 @@ public class ListTemplatesOptions extends BaseHttpRequestOptions {
}
}
/**
* {@inheritDoc}
*/
@Override
public ListTemplatesOptions accountInDomain(String account, long domain) {
return ListTemplatesOptions.class.cast(super.accountInDomain(account, domain));
}
/**
* {@inheritDoc}
*/
@Override
public ListTemplatesOptions domainId(long domainId) {
return ListTemplatesOptions.class.cast(super.domainId(domainId));
}
}

View File

@ -19,8 +19,6 @@
package org.jclouds.cloudstack.options;
import org.jclouds.http.options.BaseHttpRequestOptions;
import com.google.common.collect.ImmutableSet;
/**
@ -29,7 +27,7 @@ import com.google.common.collect.ImmutableSet;
* @see <a href="http://download.cloud.com/releases/2.2.0/api/user/listVirtualMachines.html" />
* @author Adrian Cole
*/
public class ListVirtualMachinesOptions extends BaseHttpRequestOptions {
public class ListVirtualMachinesOptions extends AccountInDomainOptions {
public static final ListVirtualMachinesOptions NONE = new ListVirtualMachinesOptions();
@ -60,28 +58,6 @@ public class ListVirtualMachinesOptions extends BaseHttpRequestOptions {
return this;
}
/**
* @param domainId
* the ID of the domain associated with the virtual machine
*/
public ListVirtualMachinesOptions domainId(long domainId) {
this.queryParameters.replaceValues("domainid", ImmutableSet.of(domainId + ""));
return this;
}
/**
*
* @param account
* account id
* @param domain
* domain id
*/
public ListVirtualMachinesOptions accountInDomain(String account, long domain) {
this.queryParameters.replaceValues("account", ImmutableSet.of(account));
return domainId(domain);
}
/**
* @param groupId
* list virtual machines by groupId.
@ -232,4 +208,20 @@ public class ListVirtualMachinesOptions extends BaseHttpRequestOptions {
return options.usesVirtualNetwork(usesVirtualNetwork);
}
}
/**
* {@inheritDoc}
*/
@Override
public ListVirtualMachinesOptions accountInDomain(String account, long domain) {
return ListVirtualMachinesOptions.class.cast(super.accountInDomain(account, domain));
}
/**
* {@inheritDoc}
*/
@Override
public ListVirtualMachinesOptions domainId(long domainId) {
return ListVirtualMachinesOptions.class.cast(super.domainId(domainId));
}
}

View File

@ -0,0 +1,99 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.predicates;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.domain.Template;
import org.jclouds.cloudstack.domain.Zone;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
/**
* Templates can be present in a zone, and available, but not valid for launch as their hypervisor
* isn't installed.
*
* @author Adrian Cole
*/
@Singleton
public class CorrectHypervisorForZone implements Function<Long, Predicate<Template>> {
private final Supplier<Map<Long, Set<String>>> hypervisorsSupplier;
@Inject
public CorrectHypervisorForZone(CloudStackClient client) {
this(Suppliers.ofInstance(new CloudStackClientToZoneToHypervisors().apply(checkNotNull(client, "client"))));
}
public CorrectHypervisorForZone(Supplier<Map<Long, Set<String>>> hypervisorsSupplier) {
this.hypervisorsSupplier = checkNotNull(hypervisorsSupplier, "hypervisorsSupplier");
}
private static class CloudStackClientToZoneToHypervisors implements
Function<CloudStackClient, Map<Long, Set<String>>> {
@Override
public Map<Long, Set<String>> apply(CloudStackClient client) {
checkNotNull(client, "client");
Builder<Long, Set<String>> builder = ImmutableMap.<Long, Set<String>> builder();
for (Zone zone : client.getZoneClient().listZones()) {
builder.put(zone.getId(), client.getHypervisorClient().listHypervisorsInZone(zone.getId()));
}
return builder.build();
}
}
@Override
public Predicate<Template> apply(final Long zoneId) {
final Set<String> acceptableHypervisorsInZone;
try {
acceptableHypervisorsInZone = this.hypervisorsSupplier.get().get(zoneId);
} catch (NullPointerException e) {
throw new IllegalArgumentException("unknown zone: " + zoneId);
}
if (acceptableHypervisorsInZone.size() == 0)
return Predicates.alwaysFalse();
return new Predicate<Template>() {
@Override
public boolean apply(Template input) {
return Predicates.in(acceptableHypervisorsInZone).apply(input.getHypervisor());
}
@Override
public String toString() {
return "hypervisorsInZone(" + zoneId + ", " + acceptableHypervisorsInZone + ")";
}
};
}
}

View File

@ -0,0 +1,94 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.predicates;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.domain.OSType;
import org.jclouds.cloudstack.domain.Template;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.Maps;
/**
*
*
* @author Adrian Cole
*/
@Singleton
public class OSCategoryIn implements Function<Set<String>, Predicate<Template>> {
private final Supplier<Map<Long, String>> categoriesSupplier;
private final Supplier<Set<OSType>> osTypesSupplier;
@Inject
public OSCategoryIn(CloudStackClient client) {
this(Suppliers.ofInstance(checkNotNull(client, "client").getGuestOSClient().listOSCategories()), Suppliers.ofInstance(client
.getGuestOSClient().listOSTypes()));
}
public OSCategoryIn(Supplier<Map<Long, String>> categoriesSupplier, Supplier<Set<OSType>> osTypesSupplier) {
this.categoriesSupplier = checkNotNull(categoriesSupplier, "categoriesSupplier");
this.osTypesSupplier = checkNotNull(osTypesSupplier, "osTypesSupplier");
}
@Override
public Predicate<Template> apply(final Set<String> acceptableCategories) {
final Map<Long, String> categories = categoriesSupplier.get();
final Set<Long> acceptableOSTypeIds = Maps.filterValues(
Maps.transformValues(Maps.uniqueIndex(osTypesSupplier.get(), new Function<OSType, Long>() {
@Override
public Long apply(OSType input) {
return input.getId();
}
}), new Function<OSType, String>() {
@Override
public String apply(OSType input) {
return categories.get(input.getOSCategoryId());
}
}), Predicates.in(acceptableCategories)).keySet();
return new Predicate<Template>() {
@Override
public boolean apply(Template input) {
return Predicates.in(acceptableOSTypeIds).apply(input.getOSTypeId());
}
@Override
public String toString() {
return "OSCategoryIn(" + acceptableCategories + ")";
}
};
}
}

View File

@ -0,0 +1,70 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.predicates;
import javax.inject.Singleton;
import org.jclouds.cloudstack.domain.Template;
import com.google.common.base.Predicate;
/**
*
*
* @author Adrian Cole
*/
@Singleton
public class TemplatePredicates {
public static Predicate<Template> isReady() {
return Ready.INSTANCE;
}
public enum Ready implements Predicate<Template> {
INSTANCE;
@Override
public boolean apply(Template arg0) {
return arg0.isReady();
}
@Override
public String toString() {
return "isReady()";
}
}
public static enum PasswordEnabled implements Predicate<Template> {
INSTANCE;
@Override
public boolean apply(Template arg0) {
return arg0.isPasswordEnabled();
}
@Override
public String toString() {
return "isPasswordEnabled()";
}
}
public static Predicate<Template> isPasswordEnabled() {
return PasswordEnabled.INSTANCE;
}
}

View File

@ -23,7 +23,13 @@ import java.io.IOException;
import java.util.concurrent.ExecutionException;
import org.jclouds.cloudstack.features.BaseCloudStackAsyncClientTest;
import org.jclouds.cloudstack.features.FirewallClient;
import org.jclouds.cloudstack.features.GuestOSClient;
import org.jclouds.cloudstack.features.HypervisorClient;
import org.jclouds.cloudstack.features.LoadBalancerClient;
import org.jclouds.cloudstack.features.NATClient;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@ -51,6 +57,11 @@ public class CloudStackAsyncClientTest extends BaseCloudStackAsyncClientTest<Clo
assert syncClient.getSecurityGroupClient() != null;
assert syncClient.getAsyncJobClient() != null;
assert syncClient.getAddressClient() != null;
assert syncClient.getNATClient() != null;
assert syncClient.getFirewallClient() != null;
assert syncClient.getLoadBalancerClient() != null;
assert syncClient.getGuestOSClient() != null;
assert syncClient.getHypervisorClient() != null;
}
public void testAsync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException {
@ -62,6 +73,11 @@ public class CloudStackAsyncClientTest extends BaseCloudStackAsyncClientTest<Clo
assert asyncClient.getSecurityGroupClient() != null;
assert asyncClient.getAsyncJobClient() != null;
assert asyncClient.getAddressClient() != null;
assert asyncClient.getNATClient() != null;
assert asyncClient.getFirewallClient() != null;
assert asyncClient.getLoadBalancerClient() != null;
assert asyncClient.getGuestOSClient() != null;
assert asyncClient.getHypervisorClient() != null;
}
@Override

View File

@ -30,6 +30,8 @@ import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.PublicIPAddress;
import org.jclouds.cloudstack.options.ListPublicIPAddressesOptions;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.common.collect.Iterables;
@ -41,9 +43,18 @@ import com.google.common.collect.Iterables;
*/
@Test(groups = "live", sequential = true, testName = "PublicIPAddressClientLiveTest")
public class AddressClientLiveTest extends BaseCloudStackClientLiveTest {
private boolean networksEnabled;
@BeforeGroups(groups = "live")
void networksEnabled() {
networksEnabled = client.getNetworkClient().listNetworks().size() > 0;
}
private PublicIPAddress ip = null;
public void testAssociateDisassociatePublicIPAddress() throws Exception {
if (!networksEnabled)
return;
AsyncCreateResponse job = client.getAddressClient().associateIPAddress(
Iterables.get(client.getNetworkClient().listNetworks(), 0).getZoneId());
checkState(jobComplete.apply(job.getJobId()), "job %d failed to complete", job.getJobId());
@ -60,6 +71,8 @@ public class AddressClientLiveTest extends BaseCloudStackClientLiveTest {
}
public void testListPublicIPAddresss() throws Exception {
if (!networksEnabled)
return;
Set<PublicIPAddress> response = client.getAddressClient().listPublicIPAddresses();
assert null != response;
assertTrue(response.size() >= 0);

View File

@ -125,7 +125,7 @@ public class BaseCloudStackClientLiveTest {
sshFactory = injector.getInstance(SshClient.Factory.class);
socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 180, 1, 1, TimeUnit.SECONDS);
injector.injectMembers(socketTester);
jobComplete = new RetryablePredicate<Long>(new JobComplete(client), 600, 5, 5, TimeUnit.SECONDS);
jobComplete = new RetryablePredicate<Long>(new JobComplete(client), 1200, 1, 5, TimeUnit.SECONDS);
injector.injectMembers(jobComplete);
virtualMachineRunning = new RetryablePredicate<VirtualMachine>(new VirtualMachineRunning(client), 600, 5, 5,
TimeUnit.SECONDS);

View File

@ -0,0 +1,64 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.features;
import java.io.IOException;
import java.lang.reflect.Method;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue;
import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code ConfigurationAsyncClient}
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "ConfigurationAsyncClientTest")
public class ConfigurationAsyncClientTest extends BaseCloudStackAsyncClientTest<ConfigurationAsyncClient> {
public void testListCapabilities() throws SecurityException, NoSuchMethodException, IOException {
Method method = ConfigurationAsyncClient.class.getMethod("listCapabilities");
HttpRequest httpRequest = processor.createRequest(method);
assertRequestLineEquals(httpRequest,
"GET http://localhost:8080/client/api?response=json&command=listCapabilities HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, UnwrapOnlyNestedJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
checkFilters(httpRequest);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<ConfigurationAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<ConfigurationAsyncClient>>() {
};
}
}

View File

@ -0,0 +1,39 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.features;
import org.jclouds.cloudstack.domain.Capabilities;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code ConfigurationClientLiveTest}
*
* @author Adrian Cole
*/
@Test(groups = "live", sequential = true, testName = "ConfigurationClientLiveTest")
public class ConfigurationClientLiveTest extends BaseCloudStackClientLiveTest {
public void testListCapabilities() throws Exception {
Capabilities response = client.getConfigurationClient().listCapabilities();
assert null != response;
assert null != response.getCloudStackVersion();
}
}

View File

@ -23,6 +23,7 @@ import static com.google.common.collect.Iterables.find;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.NoSuchElementException;
import java.util.Set;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
@ -49,20 +50,26 @@ public class FirewallClientLiveTest extends BaseCloudStackClientLiveTest {
private VirtualMachine vm;
private PortForwardingRule rule;
private Network network;
private boolean networksDisabled;
@BeforeGroups(groups = "live")
public void setupClient() {
super.setupClient();
prefix += "rule";
try {
network = find(client.getNetworkClient().listNetworks(), NetworkPredicates.supportsPortForwarding());
vm = VirtualMachineClientLiveTest.createVirtualMachineInNetwork(network, client, jobComplete,
virtualMachineRunning);
if (vm.getPassword() != null)
password = vm.getPassword();
} catch (NoSuchElementException e) {
networksDisabled = true;
}
}
public void testCreatePortForwardingRule() throws Exception {
if (networksDisabled)
return;
while (rule == null) {
ip = reuseOrAssociate.apply(network);
try {

View File

@ -22,6 +22,8 @@ package org.jclouds.cloudstack.features;
import java.io.IOException;
import java.lang.reflect.Method;
import org.jclouds.cloudstack.functions.ParseIdToNameEntryFromHttpResponse;
import org.jclouds.cloudstack.functions.ParseIdToNameFromHttpResponse;
import org.jclouds.cloudstack.options.ListOSTypesOptions;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue;
@ -42,6 +44,40 @@ import com.google.inject.TypeLiteral;
@Test(groups = "unit", testName = "GuestOSAsyncClientTest")
public class GuestOSAsyncClientTest extends BaseCloudStackAsyncClientTest<GuestOSAsyncClient> {
public void testGetOSCategory() throws SecurityException, NoSuchMethodException, IOException {
Method method = GuestOSAsyncClient.class.getMethod("getOSCategory", long.class);
HttpRequest httpRequest = processor.createRequest(method, 11l);
assertRequestLineEquals(httpRequest,
"GET http://localhost:8080/client/api?response=json&command=listOsCategories&id=11 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ParseIdToNameEntryFromHttpResponse.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testListOSCategories() throws SecurityException, NoSuchMethodException, IOException {
Method method = GuestOSAsyncClient.class.getMethod("listOSCategories");
HttpRequest httpRequest = processor.createRequest(method);
assertRequestLineEquals(httpRequest,
"GET http://localhost:8080/client/api?response=json&command=listOsCategories HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ParseIdToNameFromHttpResponse.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testGetOSType() throws SecurityException, NoSuchMethodException, IOException {
Method method = GuestOSAsyncClient.class.getMethod("getOSType", long.class);
HttpRequest httpRequest = processor.createRequest(method, 11l);

View File

@ -23,7 +23,9 @@ import static com.google.common.collect.Iterables.getOnlyElement;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import org.jclouds.cloudstack.domain.OSType;
import org.jclouds.cloudstack.options.ListOSTypesOptions;
@ -45,11 +47,26 @@ public class GuestOSClientLiveTest extends BaseCloudStackClientLiveTest {
OSType newDetails = getOnlyElement(client.getGuestOSClient().listOSTypes(
ListOSTypesOptions.Builder.id(type.getId())));
assertEquals(type.getId(), newDetails.getId());
checkIP(type);
checkOSType(type);
}
}
protected void checkIP(OSType type) {
public void testListOSCategories() throws Exception {
Map<Long, String> response = client.getGuestOSClient().listOSCategories();
assert null != response;
assertTrue(response.size() >= 0);
for (Entry<Long, String> category : response.entrySet()) {
checkOSCategory(category);
}
}
protected void checkOSCategory(Entry<Long, String> category) {
assertEquals(category, client.getGuestOSClient().getOSCategory(category.getKey()));
assert category.getKey() > 0 : category;
assert category.getValue() != null : category;
}
protected void checkOSType(OSType type) {
assertEquals(type.getId(), client.getGuestOSClient().getOSType(type.getId()).getId());
assert type.getId() > 0 : type;
assert type.getOSCategoryId() > 0 : type;

View File

@ -0,0 +1,81 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.features;
import java.io.IOException;
import java.lang.reflect.Method;
import org.jclouds.cloudstack.functions.ParseNamesFromHttpResponse;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code HypervisorAsyncClient}
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "HypervisorAsyncClientTest")
public class HypervisorAsyncClientTest extends BaseCloudStackAsyncClientTest<HypervisorAsyncClient> {
public void testListHypervisors() throws SecurityException, NoSuchMethodException, IOException {
Method method = HypervisorAsyncClient.class.getMethod("listHypervisors");
HttpRequest httpRequest = processor.createRequest(method);
assertRequestLineEquals(httpRequest,
"GET http://localhost:8080/client/api?response=json&command=listHypervisors HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ParseNamesFromHttpResponse.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testListHypervisorsInZon() throws SecurityException, NoSuchMethodException, IOException {
Method method = HypervisorAsyncClient.class.getMethod("listHypervisorsInZone", long.class);
HttpRequest httpRequest = processor.createRequest(method, 11);
assertRequestLineEquals(httpRequest,
"GET http://localhost:8080/client/api?response=json&command=listHypervisors&zoneid=11 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ParseNamesFromHttpResponse.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(httpRequest);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<HypervisorAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<HypervisorAsyncClient>>() {
};
}
}

View File

@ -0,0 +1,47 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.features;
import static org.testng.Assert.assertTrue;
import java.util.Set;
import org.jclouds.cloudstack.domain.Zone;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code HypervisorClientLiveTest}
*
* @author Adrian Cole
*/
@Test(groups = "live", sequential = true, testName = "HypervisorClientLiveTest")
public class HypervisorClientLiveTest extends BaseCloudStackClientLiveTest {
public void testListHypervisors() throws Exception {
Set<String> response = client.getHypervisorClient().listHypervisors();
assert null != response;
assertTrue(response.size() >= 0);
for (Zone zone : client.getZoneClient().listZones()) {
Set<String> zoneHype = client.getHypervisorClient().listHypervisorsInZone(zone.getId());
assert response.containsAll(zoneHype);
}
}
}

View File

@ -24,6 +24,7 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.io.IOException;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -56,6 +57,7 @@ public class LoadBalancerClientLiveTest extends BaseCloudStackClientLiveTest {
private LoadBalancerRule rule;
private RetryablePredicate<LoadBalancerRule> loadBalancerRuleActive;
private Network network;
private boolean networksDisabled;
@BeforeGroups(groups = "live")
public void setupClient() {
@ -64,14 +66,20 @@ public class LoadBalancerClientLiveTest extends BaseCloudStackClientLiveTest {
loadBalancerRuleActive = new RetryablePredicate<LoadBalancerRule>(new LoadBalancerRuleActive(client), 60, 1, 1,
TimeUnit.SECONDS);
prefix += "rule";
try {
network = find(client.getNetworkClient().listNetworks(), NetworkPredicates.hasLoadBalancerService());
vm = VirtualMachineClientLiveTest.createVirtualMachineInNetwork(network, client, jobComplete,
virtualMachineRunning);
if (vm.getPassword() != null)
password = vm.getPassword();
} catch (NoSuchElementException e) {
networksDisabled = true;
}
}
public void testCreateLoadBalancerRule() throws Exception {
if (networksDisabled)
return;
while (rule == null) {
ip = reuseOrAssociate.apply(network);
try {
@ -94,6 +102,8 @@ public class LoadBalancerClientLiveTest extends BaseCloudStackClientLiveTest {
@Test(dependsOnMethods = "testCreateLoadBalancerRule")
public void testAssignToLoadBalancerRule() throws Exception {
if (networksDisabled)
return;
assert jobComplete.apply(client.getLoadBalancerClient().assignVirtualMachinesToLoadBalancerRule(rule.getId(),
vm.getId()));
assertEquals(client.getLoadBalancerClient().listVirtualMachinesAssignedToLoadBalancerRule(rule.getId()).size(), 1);
@ -120,6 +130,8 @@ public class LoadBalancerClientLiveTest extends BaseCloudStackClientLiveTest {
@Test(dependsOnMethods = "testAssignToLoadBalancerRule", expectedExceptions = SshException.class)
public void testRemoveFromLoadBalancerRule() throws Exception {
if (networksDisabled)
throw new SshException();
assert jobComplete.apply(client.getLoadBalancerClient().removeVirtualMachinesFromLoadBalancerRule(rule.getId(),
vm.getId()));
assertEquals(client.getLoadBalancerClient().listVirtualMachinesAssignedToLoadBalancerRule(rule.getId()).size(), 0);

View File

@ -24,6 +24,7 @@ import static com.google.common.collect.Iterables.getOnlyElement;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.NoSuchElementException;
import java.util.Set;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
@ -52,19 +53,26 @@ public class NATClientLiveTest extends BaseCloudStackClientLiveTest {
private VirtualMachine vm;
private IPForwardingRule rule;
private Network network;
private boolean networksDisabled;
@BeforeGroups(groups = "live")
public void setupClient() {
super.setupClient();
prefix += "nat";
try {
network = find(client.getNetworkClient().listNetworks(), NetworkPredicates.supportsStaticNAT());
vm = VirtualMachineClientLiveTest.createVirtualMachineInNetwork(network, client, jobComplete,
virtualMachineRunning);
if (vm.getPassword() != null)
password = vm.getPassword();
} catch (NoSuchElementException e) {
networksDisabled = true;
}
}
public void testCreateIPForwardingRule() throws Exception {
if (networksDisabled)
return;
for (ip = reuseOrAssociate.apply(network); (!ip.isStaticNAT() || ip.getVirtualMachineId() != vm.getId()); ip = reuseOrAssociate
.apply(network)) {
// check to see if someone already grabbed this ip

View File

@ -22,7 +22,6 @@ package org.jclouds.cloudstack.features;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.NoSuchElementException;
import java.util.Set;
import org.jclouds.cloudstack.domain.DiskOffering;
@ -70,16 +69,9 @@ public class OfferingClientLiveTest extends BaseCloudStackClientLiveTest {
long offeringCount = response.size();
assertTrue(offeringCount >= 0);
for (ServiceOffering offering : response) {
try {
ServiceOffering newDetails = Iterables.getOnlyElement(client.getOfferingClient().listServiceOfferings(
ListServiceOfferingsOptions.Builder.id(offering.getId())));
assertEquals(offering, newDetails);
assert false : "should be a bug as of 2.2.0";
} catch (NoSuchElementException e) {
}
// bug as of 2.2.0
assertEquals(client.getOfferingClient().getServiceOffering(offering.getId()), null);
assert offering.getId() > 0 : offering;
assert offering.getName() != null : offering;

View File

@ -22,6 +22,7 @@ package org.jclouds.cloudstack.features;
import java.io.IOException;
import java.lang.reflect.Method;
import org.jclouds.cloudstack.options.AccountInDomainOptions;
import org.jclouds.cloudstack.options.ListSecurityGroupsOptions;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ReleasePayloadAndReturn;
@ -34,6 +35,9 @@ import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.inject.TypeLiteral;
/**
@ -115,6 +119,104 @@ public class SecurityGroupAsyncClientTest extends BaseCloudStackAsyncClientTest<
}
public void testAuthorizeIngressPortsToCIDRs() throws SecurityException, NoSuchMethodException, IOException {
Method method = SecurityGroupAsyncClient.class.getMethod("authorizeIngressPortsToCIDRs", long.class,
String.class, int.class, int.class, Iterable.class, AccountInDomainOptions[].class);
HttpRequest httpRequest = processor.createRequest(method, 2, "tcp", 22, 22, ImmutableSet.of("1.1.1.1/24",
"1.2.2.2/16"));
assertRequestLineEquals(
httpRequest,
"GET http://localhost:8080/client/api?response=json&command=authorizeSecurityGroupIngress&securitygroupid=2&startport=22&protocol=tcp&endport=22&cidrlist=1.1.1.1%2F24%2C1.2.2.2%2F16 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, UnwrapOnlyNestedJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
checkFilters(httpRequest);
}
public void testAuthorizeIngressPortsToSecurityGroups() throws SecurityException, NoSuchMethodException, IOException {
Method method = SecurityGroupAsyncClient.class.getMethod("authorizeIngressPortsToSecurityGroups", long.class,
String.class, int.class, int.class, Multimap.class, AccountInDomainOptions[].class);
HttpRequest httpRequest = processor.createRequest(method, 2, "tcp", 22, 22, ImmutableMultimap.of("adrian",
"group1", "adrian", "group2", "bob", "group1"));
assertRequestLineEquals(
httpRequest,
"GET http://localhost:8080/client/api?response=json&command=authorizeSecurityGroupIngress&securitygroupid=2&startport=22&protocol=tcp&endport=22&usersecuritygrouplist%5B0%5D.account=adrian&usersecuritygrouplist%5B0%5D.group=group1&usersecuritygrouplist%5B1%5D.account=adrian&usersecuritygrouplist%5B1%5D.group=group2&usersecuritygrouplist%5B2%5D.account=bob&usersecuritygrouplist%5B2%5D.group=group1 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, UnwrapOnlyNestedJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
checkFilters(httpRequest);
}
public void testAuthorizeIngressICMPToCIDRs() throws SecurityException, NoSuchMethodException, IOException {
Method method = SecurityGroupAsyncClient.class.getMethod("authorizeIngressICMPToCIDRs", long.class, int.class,
int.class, Iterable.class, AccountInDomainOptions[].class);
HttpRequest httpRequest = processor.createRequest(method, 2, 22, 22, ImmutableSet.of("1.1.1.1/24", "1.2.2.2/16"));
assertRequestLineEquals(
httpRequest,
"GET http://localhost:8080/client/api?response=json&command=authorizeSecurityGroupIngress&protocol=ICMP&securitygroupid=2&icmptype=22&icmpcode=22&cidrlist=1.1.1.1%2F24%2C1.2.2.2%2F16 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, UnwrapOnlyNestedJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
checkFilters(httpRequest);
}
public void testAuthorizeIngressICMPToSecurityGroups() throws SecurityException, NoSuchMethodException, IOException {
Method method = SecurityGroupAsyncClient.class.getMethod("authorizeIngressICMPToSecurityGroups", long.class,
int.class, int.class, Multimap.class, AccountInDomainOptions[].class);
HttpRequest httpRequest = processor.createRequest(method, 2, 22, 22, ImmutableMultimap.of("adrian", "group1",
"adrian", "group2", "bob", "group1"));
assertRequestLineEquals(
httpRequest,
"GET http://localhost:8080/client/api?response=json&command=authorizeSecurityGroupIngress&protocol=ICMP&securitygroupid=2&icmptype=22&icmpcode=22&usersecuritygrouplist%5B0%5D.account=adrian&usersecuritygrouplist%5B0%5D.group=group1&usersecuritygrouplist%5B1%5D.account=adrian&usersecuritygrouplist%5B1%5D.group=group2&usersecuritygrouplist%5B2%5D.account=bob&usersecuritygrouplist%5B2%5D.group=group1 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, UnwrapOnlyNestedJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
checkFilters(httpRequest);
}
public void testRevokeIngressRule() throws SecurityException, NoSuchMethodException, IOException {
Method method = SecurityGroupAsyncClient.class.getMethod("revokeIngressRule", long.class,
AccountInDomainOptions[].class);
HttpRequest httpRequest = processor.createRequest(method, 5, AccountInDomainOptions.Builder.accountInDomain(
"adrian", 1));
assertRequestLineEquals(httpRequest,
"GET http://localhost:8080/client/api?response=json&command=revokeSecurityGroupIngress&id=5&account=adrian&domainid=1 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, UnwrapOnlyNestedJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnVoidOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testDeleteSecurityGroup() throws SecurityException, NoSuchMethodException, IOException {
Method method = SecurityGroupAsyncClient.class.getMethod("deleteSecurityGroup", long.class);
HttpRequest httpRequest = processor.createRequest(method, 5);

View File

@ -21,15 +21,24 @@ package org.jclouds.cloudstack.features;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.NoSuchElementException;
import org.jclouds.cloudstack.domain.IngressRule;
import org.jclouds.cloudstack.domain.SecurityGroup;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.domain.Zone;
import org.jclouds.cloudstack.options.AccountInDomainOptions;
import org.jclouds.cloudstack.options.ListSecurityGroupsOptions;
import org.jclouds.net.IPSocket;
import org.jclouds.util.Strings2;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
/**
@ -39,12 +48,19 @@ import com.google.common.collect.Iterables;
*/
@Test(groups = "live", sequential = true, testName = "SecurityGroupClientLiveTest")
public class SecurityGroupClientLiveTest extends BaseCloudStackClientLiveTest {
public SecurityGroupClientLiveTest() {
prefix += "2";
}
private SecurityGroup group;
private boolean securityGroupsSupported;
private VirtualMachine vm;
private Zone zone;
public void testCreateDestroySecurityGroup() throws Exception {
@Test
public void testCreateDestroySecurityGroup() {
try {
Iterables.find(client.getZoneClient().listZones(), new Predicate<Zone>() {
zone = Iterables.find(client.getZoneClient().listZones(), new Predicate<Zone>() {
@Override
public boolean apply(Zone arg0) {
@ -52,10 +68,13 @@ public class SecurityGroupClientLiveTest extends BaseCloudStackClientLiveTest {
}
});
securityGroupsSupported = true;
for (SecurityGroup securityGroup : client.getSecurityGroupClient().listSecurityGroups(
ListSecurityGroupsOptions.Builder.named(prefix)))
ListSecurityGroupsOptions.Builder.named(prefix))) {
for (IngressRule rule : securityGroup.getIngressRules())
assert this.jobComplete.apply(client.getSecurityGroupClient().revokeIngressRule(rule.getId())) : rule;
client.getSecurityGroupClient().deleteSecurityGroup(securityGroup.getId());
}
group = client.getSecurityGroupClient().createSecurityGroup(prefix);
assertEquals(group.getName(), prefix);
checkGroup(group);
@ -66,13 +85,106 @@ public class SecurityGroupClientLiveTest extends BaseCloudStackClientLiveTest {
}
} catch (NoSuchElementException e) {
e.printStackTrace();
}
}
protected void checkGroup(SecurityGroup group) throws InterruptedException {
// sometimes this comes up different
// assertEquals(group, client.getSecurityGroupClient().getSecurityGroup(group.getId()));
public static String getCurrentCIDR() throws IOException {
URL url = new URL("http://checkip.amazonaws.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
// http://bugs.cloud.com/show_bug.cgi?id=8969
// return Strings2.toStringAndClose(connection.getInputStream()).trim()+"/32";
return Strings2.toStringAndClose(connection.getInputStream()).trim();
}
@Test(dependsOnMethods = "testCreateDestroySecurityGroup")
public void testCreateIngress() throws Exception {
if (!securityGroupsSupported)
return;
String cidr = getCurrentCIDR();
ImmutableSet<String> cidrs = ImmutableSet.of(cidr);
assert jobComplete.apply(client.getSecurityGroupClient().authorizeIngressICMPToCIDRs(group.getId(), 0, 8, cidrs)) : group;
assert jobComplete.apply(client.getSecurityGroupClient().authorizeIngressPortsToCIDRs(group.getId(), "TCP", 22,
22, cidrs)) : group;
AccountInDomainOptions.Builder.accountInDomain(group.getAccount(), group.getDomainId());
// replace with get once bug is fixed where getGroup returns only one ingress rule
group = Iterables.find(client.getSecurityGroupClient().listSecurityGroups(), new Predicate<SecurityGroup>() {
@Override
public boolean apply(SecurityGroup input) {
return input.getId() == group.getId();
}
});
IngressRule ICMPPingRule = Iterables.find(group.getIngressRules(), new Predicate<IngressRule>() {
@Override
public boolean apply(IngressRule input) {
return "icmp".equals(input.getProtocol());
}
});
assert ICMPPingRule.getId() > 0 : ICMPPingRule;
assert "icmp".equals(ICMPPingRule.getProtocol()) : ICMPPingRule;
assert ICMPPingRule.getStartPort() == -1 : ICMPPingRule;
assert ICMPPingRule.getEndPort() == -1 : ICMPPingRule;
assert ICMPPingRule.getICMPCode() == 0 : ICMPPingRule;
assert ICMPPingRule.getICMPType() == 8 : ICMPPingRule;
assert ICMPPingRule.getAccount() == null : ICMPPingRule;
assert ICMPPingRule.getSecurityGroupName() == null : ICMPPingRule;
assert cidr.equals(ICMPPingRule.getCIDR()) : ICMPPingRule;
IngressRule SSHRule = Iterables.find(group.getIngressRules(), new Predicate<IngressRule>() {
@Override
public boolean apply(IngressRule input) {
return "tcp".equals(input.getProtocol());
}
});
assert SSHRule.getId() > 0 : SSHRule;
assert "tcp".equals(SSHRule.getProtocol()) : SSHRule;
assert SSHRule.getStartPort() == 22 : SSHRule;
assert SSHRule.getEndPort() == 22 : SSHRule;
assert SSHRule.getICMPCode() == -1 : SSHRule;
assert SSHRule.getICMPType() == -1 : SSHRule;
assert SSHRule.getAccount() == null : SSHRule;
assert SSHRule.getSecurityGroupName() == null : SSHRule;
assert cidr.equals(SSHRule.getCIDR()) : SSHRule;
}
public void testListSecurityGroup() throws Exception {
if (!securityGroupsSupported)
return;
for (SecurityGroup securityGroup : client.getSecurityGroupClient().listSecurityGroups())
checkGroup(securityGroup);
}
@Test(dependsOnMethods = "testCreateIngress")
public void testCreateVMInSecurityGroup() throws Exception {
if (!securityGroupsSupported)
return;
vm = VirtualMachineClientLiveTest.createVirtualMachineWithSecurityGroupInZone(zone.getId(), group.getId(),
client, jobComplete, virtualMachineRunning);
if (vm.getPassword() != null)
password = vm.getPassword();
// ingress port 22
checkSSH(new IPSocket(vm.getIPAddress(), 22));
// ingress icmp disabled as this is platform dependent and may actually just try tcp port 7
// assert InetAddress.getByName(vm.getIPAddress()).isReachable(1000) : vm;
}
protected void checkGroup(SecurityGroup group) {
// http://bugs.cloud.com/show_bug.cgi?id=8968
if (group.getIngressRules().size() <= 1)
assertEquals(group, client.getSecurityGroupClient().getSecurityGroup(group.getId()));
assert group.getId() > 0 : group;
assert group.getName() != null : group;
assert group.getAccount() != null : group;
@ -83,7 +195,12 @@ public class SecurityGroupClientLiveTest extends BaseCloudStackClientLiveTest {
@AfterGroups(groups = "live")
protected void tearDown() {
if (vm != null) {
assert jobComplete.apply(client.getVirtualMachineClient().destroyVirtualMachine(vm.getId()));
}
if (group != null) {
for (IngressRule rule : group.getIngressRules())
assert this.jobComplete.apply(client.getSecurityGroupClient().revokeIngressRule(rule.getId())) : rule;
client.getSecurityGroupClient().deleteSecurityGroup(group.getId());
assertEquals(client.getSecurityGroupClient().getSecurityGroup(group.getId()), null);
}

View File

@ -61,11 +61,8 @@ public class TemplateAsyncClientTest extends BaseCloudStackAsyncClientTest<Templ
public void testListTemplatesOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = TemplateAsyncClient.class.getMethod("listTemplates", ListTemplatesOptions.class);
HttpRequest httpRequest = processor
.createRequest(
method,
ListTemplatesOptions.Builder.accountInDomain("adrian", 6).hypervisor("xen")
.filter(TemplateFilter.FEATURED));
HttpRequest httpRequest = processor.createRequest(method, ListTemplatesOptions.Builder.accountInDomain("adrian",
6).hypervisor("xen").filter(TemplateFilter.FEATURED));
assertRequestLineEquals(
httpRequest,
@ -82,11 +79,11 @@ public class TemplateAsyncClientTest extends BaseCloudStackAsyncClientTest<Templ
}
public void testGetTemplate() throws SecurityException, NoSuchMethodException, IOException {
Method method = TemplateAsyncClient.class.getMethod("getTemplate", long.class);
HttpRequest httpRequest = processor.createRequest(method, 5);
Method method = TemplateAsyncClient.class.getMethod("getTemplateInZone", long.class, long.class);
HttpRequest httpRequest = processor.createRequest(method, 1, 5);
assertRequestLineEquals(httpRequest,
"GET http://localhost:8080/client/api?response=json&command=listTemplates&templatefilter=executable&id=5 HTTP/1.1");
"GET http://localhost:8080/client/api?response=json&command=listTemplates&templatefilter=executable&zoneid=1&id=5 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);

View File

@ -25,7 +25,7 @@ import static org.testng.Assert.assertTrue;
import java.util.Set;
import org.jclouds.cloudstack.domain.Template;
import org.jclouds.cloudstack.options.ListTemplatesOptions;
import static org.jclouds.cloudstack.options.ListTemplatesOptions.Builder.zoneId;
import org.testng.annotations.Test;
import com.google.common.collect.Iterables;
@ -45,9 +45,9 @@ public class TemplateClientLiveTest extends BaseCloudStackClientLiveTest {
assertTrue(templateCount >= 0);
for (Template template : response) {
Template newDetails = Iterables.getOnlyElement(client.getTemplateClient().listTemplates(
ListTemplatesOptions.Builder.id(template.getId())));
zoneId(template.getZoneId()).id(template.getId())));
assertEquals(template, newDetails);
assertEquals(template, client.getTemplateClient().getTemplate(template.getId()));
assertEquals(template, client.getTemplateClient().getTemplateInZone(template.getZoneId(), template.getId()));
assert template.getId() > 0 : template;
assert template.getName() != null : template;
assert template.getDisplayText() != null : template;

View File

@ -38,12 +38,16 @@ import org.jclouds.cloudstack.domain.AsyncJob;
import org.jclouds.cloudstack.domain.GuestIPType;
import org.jclouds.cloudstack.domain.NIC;
import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.SecurityGroup;
import org.jclouds.cloudstack.domain.ServiceOffering;
import org.jclouds.cloudstack.domain.Template;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.domain.Zone;
import org.jclouds.cloudstack.options.DeployVirtualMachineOptions;
import org.jclouds.cloudstack.options.ListTemplatesOptions;
import org.jclouds.cloudstack.options.ListVirtualMachinesOptions;
import org.jclouds.cloudstack.predicates.CorrectHypervisorForZone;
import org.jclouds.cloudstack.predicates.OSCategoryIn;
import org.jclouds.cloudstack.predicates.TemplatePredicates;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.util.InetAddresses2;
@ -51,8 +55,10 @@ import org.testng.annotations.AfterGroups;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Throwables;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Ordering;
import com.google.common.net.HostSpecifier;
@ -77,24 +83,26 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest {
RetryablePredicate<VirtualMachine> virtualMachineRunning) {
Set<Network> networks = client.getNetworkClient().listNetworks();
if (networks.size() > 0) {
return createVirtualMachineInNetwork(Iterables.get(networks, 0), client, jobComplete, virtualMachineRunning);
return createVirtualMachineInNetwork(get(networks, 0), client, jobComplete, virtualMachineRunning);
} else {
return createVirtualMachineWithSecurityGroup(find(client.getSecurityGroupClient().listSecurityGroups(),
new Predicate<SecurityGroup>() {
return createVirtualMachineWithSecurityGroupInZone(find(client.getZoneClient().listZones(),
new Predicate<Zone>() {
@Override
public boolean apply(SecurityGroup arg0) {
return arg0.getName().equals("default");
public boolean apply(Zone arg0) {
return arg0.isSecurityGroupsEnabled();
}
}), client, jobComplete, virtualMachineRunning);
}).getId(), get(client.getSecurityGroupClient().listSecurityGroups(), 0).getId(), client,
jobComplete, virtualMachineRunning);
}
}
public static VirtualMachine createVirtualMachineWithSecurityGroup(SecurityGroup group, CloudStackClient client,
RetryablePredicate<Long> jobComplete, RetryablePredicate<VirtualMachine> virtualMachineRunning) {
return createVirtualMachineWithOptionsInZone(new DeployVirtualMachineOptions().securityGroupId(group.getId()),
get(client.getZoneClient().listZones(), 0).getId(), client, jobComplete, virtualMachineRunning);
public static VirtualMachine createVirtualMachineWithSecurityGroupInZone(long zoneId, long groupId,
CloudStackClient client, RetryablePredicate<Long> jobComplete,
RetryablePredicate<VirtualMachine> virtualMachineRunning) {
return createVirtualMachineWithOptionsInZone(new DeployVirtualMachineOptions().securityGroupId(groupId), zoneId,
client, jobComplete, virtualMachineRunning);
}
public static VirtualMachine createVirtualMachineInNetwork(Network network, CloudStackClient client,
@ -108,36 +116,26 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest {
public static VirtualMachine createVirtualMachineWithOptionsInZone(DeployVirtualMachineOptions options,
final long zoneId, CloudStackClient client, RetryablePredicate<Long> jobComplete,
RetryablePredicate<VirtualMachine> virtualMachineRunning) {
// TODO enum, as this is way too easy to mess up.
Set<String> acceptableCategories = ImmutableSet.of("Ubuntu", "CentOS");
final Predicate<Template> hypervisorPredicate = new CorrectHypervisorForZone(client).apply(zoneId);
final Predicate<Template> osTypePredicate = new OSCategoryIn(client).apply(acceptableCategories);
Predicate<Template> templatePredicate = Predicates.<Template> and(TemplatePredicates.isReady(),
hypervisorPredicate, osTypePredicate);
Iterable<Template> templates = filter(client.getTemplateClient().listTemplates(
ListTemplatesOptions.Builder.zoneId(zoneId)), templatePredicate);
if (Iterables.any(templates, TemplatePredicates.isPasswordEnabled())) {
templates = filter(templates, TemplatePredicates.isPasswordEnabled());
}
if (Iterables.size(templates) == 0) {
throw new NoSuchElementException(templatePredicate.toString());
}
long templateId = get(templates, 0).getId();
long serviceOfferingId = DEFAULT_SIZE_ORDERING.min(client.getOfferingClient().listServiceOfferings()).getId();
Iterable<Template> templates = filter(client.getTemplateClient().listTemplates(), new Predicate<Template>() {
@Override
public boolean apply(Template arg0) {
return arg0.isReady() && (arg0.isCrossZones() || arg0.getZoneId() == zoneId)
&& or(equalTo("Ubuntu 10.04 (64-bit)"), equalTo("CentOS 5.3 (64-bit)")).apply(arg0.getOSType());
}
});
if (Iterables.size(templates) == 0) {
throw new NoSuchElementException();
}
long templateId;
try {
// prefer password enabled
templateId = find(templates, new Predicate<Template>() {
@Override
public boolean apply(Template arg0) {
return arg0.isPasswordEnabled();
}
}).getId();
} catch (NoSuchElementException e) {
templateId = get(templates, 0).getId();
}
System.out.printf("serviceOfferingId %d, templateId %d, zoneId %d, options %s%n", serviceOfferingId, templateId,
zoneId, options);
AsyncCreateResponse job = client.getVirtualMachineClient().deployVirtualMachine(serviceOfferingId, templateId,
@ -211,9 +209,8 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest {
@AfterGroups(groups = "live")
protected void tearDown() {
if (vm != null) {
Long job = client.getVirtualMachineClient().destroyVirtualMachine(vm.getId());
assert job != null;
assert jobComplete.apply(job);
assert jobComplete.apply(client.getVirtualMachineClient().stopVirtualMachine(vm.getId())) : vm;
assert jobComplete.apply(client.getVirtualMachineClient().destroyVirtualMachine(vm.getId())) : vm;
assert virtualMachineDestroyed.apply(vm);
}
super.tearDown();

View File

@ -0,0 +1,57 @@
/**
*
* Copyright (C) 2010 Cloud Conscious) LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.cloudstack.functions;
import static org.testng.Assert.assertEquals;
import org.jclouds.cloudstack.domain.Capabilities;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue;
import org.jclouds.io.Payloads;
import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ListCapabilitiesResponseTest {
public void test() {
UnwrapOnlyNestedJsonValue<Capabilities> parser = Guice.createInjector(new GsonModule()).getInstance(
Key.get(new TypeLiteral<UnwrapOnlyNestedJsonValue<Capabilities>>() {
}));
Capabilities response = parser
.apply(new HttpResponse(
200,
"ok",
Payloads
.newStringPayload("{ \"listcapabilitiesresponse\" : { \"capability\" : {\"securitygroupsenabled\":true,\"cloudstackversion\":\"2.2\",\"userpublictemplateenabled\":true} } }")));
assertEquals(Capabilities.builder().securityGroupsEnabled(true).sharedTemplatesEnabled(true).cloudStackVersion(
"2.2").build(), response);
}
}

View File

@ -33,7 +33,7 @@ import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.collect.ImmutableSortedSet;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
@ -59,25 +59,49 @@ public class ListSecurityGroupsResponseTest {
public void test() {
InputStream is = getClass().getResourceAsStream("/listsecuritygroupsresponse.json");
Set<SecurityGroup> expects = ImmutableSet.<SecurityGroup> of(SecurityGroup.builder().id(3).name("default")
.description("Default Security Group").account("adrian").domainId(1).domain("ROOT").ingressRules(
ImmutableSet.of(IngressRule.builder().id(8).protocol("tcp").startPort(22).endPort(22).CIDR(
"0.0.0.0/32").build(),
Set<SecurityGroup> expects = ImmutableSortedSet.<SecurityGroup> naturalOrder().add(
IngressRule.builder().id(9).protocol("icmp").ICMPType(-1).ICMPCode(-1).securityGroupName(
"default").account("adrian").build(),
SecurityGroup.builder().id(12).name("adriancole").account("adrian").domainId(1).domain("ROOT").build()).add(
SecurityGroup.builder().id(13).name("default").description("description").account("adrian").domainId(1)
.domain("ROOT").ingressRules(
ImmutableSet.of(
IngressRule.builder().id(10).protocol("tcp").startPort(80).endPort(80).securityGroupName(
"default").account("adrian").build())).build(),
IngressRule.builder().id(5).protocol("tcp").startPort(22).endPort(22)
.securityGroupName("adriancole").account("adrian").build(),
SecurityGroup.builder().id(15).name("adriancole").account("adrian").domainId(1).domain("ROOT").build());
IngressRule.builder().id(6).protocol("udp").startPort(11).endPort(11).CIDR(
"1.1.1.1/24").build())).build()).add(
SecurityGroup.builder().id(14).name("1").description("description").account("adrian").domainId(1)
.domain("ROOT").ingressRules(
ImmutableSet.of(
IngressRule.builder().id(7).protocol("tcp").startPort(10).endPort(10).CIDR(
"1.1.1.1/24").build(),
IngressRule.builder().id(8).protocol("tcp").startPort(10).endPort(10).CIDR(
"2.2.2.2/16").build())).build()).add(
SecurityGroup.builder().id(15).name("2").description("description").account("adrian").domainId(1)
.domain("ROOT").build(),
SecurityGroup.builder().id(16).name("with1and2").description("description").account("adrian")
.domainId(1).domain("ROOT").ingressRules(
ImmutableSet.of(
IngressRule.builder().id(9).protocol("icmp").ICMPType(-1).ICMPCode(-1)
.securityGroupName("1").account("adrian").build(),
IngressRule.builder().id(10).protocol("tcp").startPort(22).endPort(22)
.securityGroupName("1").account("adrian").build(),
IngressRule.builder().id(11).protocol("tcp").startPort(22).endPort(22)
.securityGroupName("2").account("adrian").build())).build()).build();
UnwrapOnlyNestedJsonValue<Set<SecurityGroup>> parser = i.getInstance(Key
.get(new TypeLiteral<UnwrapOnlyNestedJsonValue<Set<SecurityGroup>>>() {
}));
Set<SecurityGroup> response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
Set<SecurityGroup> response = ImmutableSortedSet.copyOf(parser.apply(new HttpResponse(200, "ok", Payloads
.newInputStreamPayload(is))));
assertEquals(Sets.newHashSet(response), expects);
assertEquals(response, expects);
}
}

View File

@ -19,7 +19,7 @@
package org.jclouds.cloudstack.options;
import static org.jclouds.cloudstack.options.ListSecurityGroupsOptions.Builder.account;
import static org.jclouds.cloudstack.options.ListSecurityGroupsOptions.Builder.accountInDomain;
import static org.jclouds.cloudstack.options.ListSecurityGroupsOptions.Builder.domainId;
import static org.jclouds.cloudstack.options.ListSecurityGroupsOptions.Builder.id;
import static org.jclouds.cloudstack.options.ListSecurityGroupsOptions.Builder.named;
@ -49,12 +49,12 @@ public class ListSecurityGroupsOptionsTest {
}
public void testAccount() {
ListSecurityGroupsOptions options = new ListSecurityGroupsOptions().account("account");
ListSecurityGroupsOptions options = new ListSecurityGroupsOptions().accountInDomain("account", 1);
assertEquals(ImmutableList.of("account"), options.buildQueryParameters().get("account"));
}
public void testAccountStatic() {
ListSecurityGroupsOptions options = account("account");
ListSecurityGroupsOptions options = accountInDomain("account", 1);
assertEquals(ImmutableList.of("account"), options.buildQueryParameters().get("account"));
}

View File

@ -1 +1 @@
{ "listsecuritygroupsresponse" : { "securitygroup" : [ {"id":3,"name":"default","description":"Default Security Group","account":"adrian","domainid":1,"domain":"ROOT","ingressrule":[{"ruleid":8,"protocol":"tcp","startport":22,"endport":22,"cidr":"0.0.0.0/32"},{"ruleid":9,"protocol":"icmp","icmptype":-1,"icmpcode":-1,"securitygroupname":"default","account":"adrian"},{"ruleid":10,"protocol":"tcp","startport":80,"endport":80,"securitygroupname":"default","account":"adrian"}]}, {"id":15,"name":"adriancole","account":"adrian","domainid":1,"domain":"ROOT"} ] } }
{ "listsecuritygroupsresponse" : { "securitygroup" : [ {"id":12,"name":"adriancole","account":"adrian","domainid":1,"domain":"ROOT"}, {"id":13,"name":"default","description":"description","account":"adrian","domainid":1,"domain":"ROOT","ingressrule":[{"ruleid":5,"protocol":"tcp","startport":22,"endport":22,"securitygroupname":"adriancole","account":"adrian"},{"ruleid":6,"protocol":"udp","startport":11,"endport":11,"cidr":"1.1.1.1/24"}]}, {"id":14,"name":"1","description":"description","account":"adrian","domainid":1,"domain":"ROOT","ingressrule":[{"ruleid":7,"protocol":"tcp","startport":10,"endport":10,"cidr":"1.1.1.1/24"},{"ruleid":8,"protocol":"tcp","startport":10,"endport":10,"cidr":"2.2.2.2/16"}]}, {"id":15,"name":"2","description":"description","account":"adrian","domainid":1,"domain":"ROOT"}, {"id":16,"name":"with1and2","description":"description","account":"adrian","domainid":1,"domain":"ROOT","ingressrule":[{"ruleid":9,"protocol":"icmp","icmptype":-1,"icmpcode":-1,"securitygroupname":"1","account":"adrian"},{"ruleid":10,"protocol":"tcp","startport":22,"endport":22,"securitygroupname":"1","account":"adrian"},{"ruleid":11,"protocol":"tcp","startport":22,"endport":22,"securitygroupname":"2","account":"adrian"}]} ] } }

View File

@ -148,9 +148,13 @@
<category name="jclouds.ssh">
<priority value="TRACE" />
<appender-ref ref="ASYNCSSH" />
</category><!--
<category name="jclouds.signature">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.wire">
--><category name="jclouds.wire">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>