mirror of https://github.com/apache/jclouds.git
updated cloudstack to work with both security group and advanced networking
This commit is contained in:
parent
f5fa2d983b
commit
94ac74d711
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -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 + "]";
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
|
@ -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();
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 + ")";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -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 + ")";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>>() {
|
||||
};
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>>() {
|
||||
};
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
|
||||
|
|
|
@ -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"}]} ] } }
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue