roughed in cloudstack compute service adapter

This commit is contained in:
Adrian Cole 2011-11-10 02:11:10 +01:00
parent e9cff5e17c
commit 281c92a581
22 changed files with 1818 additions and 15 deletions

View File

@ -57,7 +57,7 @@ public interface ComputeServiceConstants {
public static class ReferenceData { public static class ReferenceData {
@Inject(optional = true) @Inject(optional = true)
@Named(PROPERTY_OS_VERSION_MAP_JSON) @Named(PROPERTY_OS_VERSION_MAP_JSON)
public String osVersionMapJson = "{\"suse\":{\"\":\"\",\"11\":\"11\",\"11 SP1\":\"11 SP1\"},\"debian\":{\"\":\"\",\"lenny\":\"5.0\",\"squeeze\":\"6.0\"},\"centos\":{\"\":\"\",\"5\":\"5.0\",\"5.2\":\"5.2\",\"5.3\":\"5.3\",\"5.4\":\"5.4\",\"5.5\":\"5.5\",\"5.6\":\"5.6\",\"5.7\":\"5.7\",\"6.0\":\"6.0\"},\"rhel\":{\"\":\"\",\"5\":\"5.0\",\"5.2\":\"5.2\",\"5.3\":\"5.3\",\"5.4\":\"5.4\",\"5.5\":\"5.5\",\"5.6\":\"5.6\",\"5.7\":\"5.7\",\"6.0\":\"6.0\"},\"solaris\":{\"\":\"\",\"10\":\"10\"},\"ubuntu\":{\"\":\"\",\"hardy\":\"8.04\",\"karmic\":\"9.10\",\"lucid\":\"10.04\",\"10.04.1\":\"10.04\",\"maverick\":\"10.10\",\"natty\":\"11.04\",\"oneiric\":\"11.10\",\"precise\":\"12.04\"},\"windows\":{\"\":\"\",\"2003\":\"2003\",\"2003 Standard\":\"2003\",\"2003 R2\":\"2003 R2\",\"2008\":\"2008\",\"2008 Web\":\"2008\",\"2008 Server\":\"2008\",\"Server 2008\":\"2008\",\"2008 R1\":\"2008 R1\",\"2008 R2\":\"2008 R2\",\"Server 2008 R2\":\"2008 R2\",\"2008 Server R2\":\"2008 R2\",\"2008 SP2\":\"2008 SP2\",\"Server 2008 SP2\":\"2008 SP2\"}}"; public String osVersionMapJson = "{\"suse\":{\"\":\"\",\"11\":\"11\",\"11 SP1\":\"11 SP1\"},\"debian\":{\"\":\"\",\"lenny\":\"5.0\",\"squeeze\":\"6.0\"},\"centos\":{\"\":\"\",\"5\":\"5.0\",\"5.2\":\"5.2\",\"5.3\":\"5.3\",\"5.4\":\"5.4\",\"5.5\":\"5.5\",\"5.6\":\"5.6\",\"5.7\":\"5.7\",\"6.0\":\"6.0\"},\"rhel\":{\"\":\"\",\"5\":\"5.0\",\"5.2\":\"5.2\",\"5.3\":\"5.3\",\"5.4\":\"5.4\",\"5.5\":\"5.5\",\"5.6\":\"5.6\",\"5.7\":\"5.7\",\"6.0\":\"6.0\"},\"solaris\":{\"\":\"\",\"10\":\"10\"},\"ubuntu\":{\"\":\"\",\"hardy\":\"8.04\",\"karmic\":\"9.10\",\"lucid\":\"10.04\",\"10.04.1\":\"10.04\",\"maverick\":\"10.10\",\"natty\":\"11.04\",\"oneiric\":\"11.10\",\"precise\":\"12.04\"},\"windows\":{\"\":\"\",\"7\":\"7\",\"2003\":\"2003\",\"2003 Standard\":\"2003\",\"2003 R2\":\"2003 R2\",\"2008\":\"2008\",\"2008 Web\":\"2008\",\"2008 Server\":\"2008\",\"Server 2008\":\"2008\",\"2008 R1\":\"2008 R1\",\"2008 R2\":\"2008 R2\",\"Server 2008 R2\":\"2008 R2\",\"2008 Server R2\":\"2008 R2\",\"2008 SP2\":\"2008 SP2\",\"Server 2008 SP2\":\"2008 SP2\"}}";
} }
@Singleton @Singleton

View File

@ -21,8 +21,9 @@ package org.jclouds.cloudstack;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
import org.jclouds.cloudstack.compute.config.CloudStackComputeServiceContextModule;
import org.jclouds.cloudstack.config.CloudStackRestClientModule; import org.jclouds.cloudstack.config.CloudStackRestClientModule;
import org.jclouds.rest.RestContextBuilder; import org.jclouds.compute.ComputeServiceContextBuilder;
import com.google.inject.Module; import com.google.inject.Module;
@ -30,12 +31,18 @@ import com.google.inject.Module;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class CloudStackContextBuilder extends RestContextBuilder<CloudStackClient, CloudStackAsyncClient> { public class CloudStackContextBuilder extends ComputeServiceContextBuilder<CloudStackClient, CloudStackAsyncClient> {
public CloudStackContextBuilder(Properties props) { public CloudStackContextBuilder(Properties props) {
super(CloudStackClient.class, CloudStackAsyncClient.class, props); super(CloudStackClient.class, CloudStackAsyncClient.class, props);
} }
@Override
protected void addContextModule(List<Module> modules) {
modules.add(new CloudStackComputeServiceContextModule());
}
@Override
protected void addClientModule(List<Module> modules) { protected void addClientModule(List<Module> modules) {
modules.add(new CloudStackRestClientModule()); modules.add(new CloudStackRestClientModule());
} }

View File

@ -0,0 +1,137 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudstack.compute.config;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.cloudstack.CloudStackAsyncClient;
import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.compute.functions.ServiceOfferingToHardware;
import org.jclouds.cloudstack.compute.functions.TemplateToImage;
import org.jclouds.cloudstack.compute.functions.TemplateToOperatingSystem;
import org.jclouds.cloudstack.compute.functions.VirtualMachineToNodeMetadata;
import org.jclouds.cloudstack.compute.functions.ZoneToLocation;
import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
import org.jclouds.cloudstack.compute.strategy.CloudStackComputeServiceAdapter;
import org.jclouds.cloudstack.domain.OSType;
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.features.GuestOSClient;
import org.jclouds.cloudstack.predicates.JobComplete;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.Location;
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.collect.Maps;
import com.google.inject.Provides;
import com.google.inject.TypeLiteral;
/**
*
* @author Adrian Cole
*/
public class CloudStackComputeServiceContextModule
extends
ComputeServiceAdapterContextModule<CloudStackClient, CloudStackAsyncClient, VirtualMachine, ServiceOffering, Template, Zone> {
public CloudStackComputeServiceContextModule() {
super(CloudStackClient.class, CloudStackAsyncClient.class);
}
@Override
protected void configure() {
super.configure();
bind(new TypeLiteral<ComputeServiceAdapter<VirtualMachine, ServiceOffering, Template, Zone>>() {
}).to(CloudStackComputeServiceAdapter.class);
bind(new TypeLiteral<Function<VirtualMachine, NodeMetadata>>() {
}).to(VirtualMachineToNodeMetadata.class);
bind(new TypeLiteral<Function<Template, org.jclouds.compute.domain.Image>>() {
}).to(TemplateToImage.class);
bind(new TypeLiteral<Function<ServiceOffering, org.jclouds.compute.domain.Hardware>>() {
}).to(ServiceOfferingToHardware.class);
bind(new TypeLiteral<Function<Zone, Location>>() {
}).to(ZoneToLocation.class);
bind(new TypeLiteral<Supplier<Location>>() {
}).to(OnlyLocationOrFirstZone.class);
bind(TemplateOptions.class).to(CloudStackTemplateOptions.class);
bind(new TypeLiteral<Function<Template, OperatingSystem>>() {
}).to(TemplateToOperatingSystem.class);
}
@Provides
@Singleton
@Memoized
public Supplier<Map<Long, String>> listOSCategories(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final CloudStackClient client) {
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<Long, String>>(authException,
seconds, new Supplier<Map<Long, String>>() {
@Override
public Map<Long, String> get() {
GuestOSClient guestOSClient = client.getGuestOSClient();
return guestOSClient.listOSCategories();
}
});
}
@Provides
@Singleton
@Memoized
public Supplier<Map<Long, OSType>> listOSTypes(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final CloudStackClient client) {
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<Long, OSType>>(authException,
seconds, new Supplier<Map<Long, OSType>>() {
@Override
public Map<Long, OSType> get() {
GuestOSClient guestOSClient = client.getGuestOSClient();
return Maps.uniqueIndex(guestOSClient.listOSTypes(), new Function<OSType, Long>() {
@Override
public Long apply(OSType arg0) {
return arg0.getId();
}
});
}
});
}
@Provides
@Singleton
protected Predicate<Long> jobComplete(JobComplete jobComplete) {
// TODO: parameterize
return new RetryablePredicate<Long>(jobComplete, 1200, 1, 5, TimeUnit.SECONDS);
}
}

View File

@ -0,0 +1,55 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudstack.compute.functions;
import javax.inject.Singleton;
import org.jclouds.cloudstack.domain.ServiceOffering;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.HardwareBuilder;
import org.jclouds.compute.domain.Processor;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
/**
*/
@Singleton
public class ServiceOfferingToHardware implements Function<ServiceOffering, Hardware> {
@Override
public Hardware apply(ServiceOffering offering) {
return new HardwareBuilder()
.id(offering.getId() + "")
// TODO: can the id be ambigious? should we include the domain if available?
.providerId(offering.getId() + "")
.name(offering.getName())
.tags(offering.getTags())
.processors(ImmutableList.of(new Processor(offering.getCpuNumber(), offering.getCpuSpeed())))
.ram(offering.getMemory())//
// TODO .volumes()
// displayText
// created
// haSupport
// storageType
// TODO where's the location of this?
.build();
}
}

View File

@ -0,0 +1,82 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudstack.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.cloudstack.domain.Template;
import org.jclouds.collect.FindResourceInSet;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.domain.Location;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
/**
*/
@Singleton
public class TemplateToImage implements Function<Template, Image> {
private final FindLocationForTemplate findLocationForTemplate;
private final Function<Template, OperatingSystem> templateToOperatingSystem;
@Inject
public TemplateToImage(FindLocationForTemplate findLocationForTemplate,
Function<Template, OperatingSystem> templateToOperatingSystem) {
this.findLocationForTemplate = checkNotNull(findLocationForTemplate, "findLocationForTemplate");
this.templateToOperatingSystem = checkNotNull(templateToOperatingSystem, "templateToOperatingSystem");
}
@Override
public Image apply(Template template) {
checkNotNull(template, "template");
OperatingSystem os = templateToOperatingSystem.apply(template);
ImageBuilder builder = new ImageBuilder().id(template.getZoneId() + "/" + template.getId())
.providerId(template.getId() + "").name(template.getName()).description(template.getDisplayText())
.operatingSystem(os);
if (!template.isCrossZones())
builder.location(findLocationForTemplate.apply(template));
return builder.build();
}
@Singleton
public static class FindLocationForTemplate extends FindResourceInSet<Template, Location> {
@Inject
public FindLocationForTemplate(@Memoized Supplier<Set<? extends Location>> location) {
super(location);
}
@Override
public boolean matches(Template from, Location input) {
return input.getId().equals(Long.toString(from.getZoneId()));
}
}
}

View File

@ -0,0 +1,76 @@
package org.jclouds.cloudstack.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.cloudstack.domain.OSType;
import org.jclouds.cloudstack.domain.Template;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OperatingSystem.Builder;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.util.ComputeServiceUtils;
import org.jclouds.logging.Logger;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
/**
*
* @author Adrian Cole
*/
@Singleton
public class TemplateToOperatingSystem implements Function<Template, OperatingSystem> {
// CentOS 5.2 (32-bit)
public static final Pattern DEFAULT_PATTERN = Pattern.compile(".* ([0-9.]+) ?\\(.*");
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final Supplier<Map<Long, OSType>> osTypes;
private final Supplier<Map<Long, String>> osCategories;
private final Map<OsFamily, Map<String, String>> osVersionMap;
@Inject
public TemplateToOperatingSystem(@Memoized Supplier<Map<Long, OSType>> osTypes,
@Memoized Supplier<Map<Long, String>> osCategories, Map<OsFamily, Map<String, String>> osVersionMap) {
this.osTypes = checkNotNull(osTypes, "osTypes");
this.osCategories = checkNotNull(osCategories, "osCategories");
this.osVersionMap = checkNotNull(osVersionMap, "osVersionMap");
}
public OperatingSystem apply(Template from) {
Builder builder = OperatingSystem.builder().description(from.getOSType());
OSType type = osTypes.get().get(from.getOSTypeId());
if (type == null) {
logger.warn("type for template %s not found in %s", from, osTypes.get());
return builder.build();
}
builder.description(type.getDescription());
builder.is64Bit(type.getDescription().indexOf("64-bit") != -1);
String osCategory = osCategories.get().get(type.getOSCategoryId());
if (osCategory == null) {
logger.warn("category for OSType %s not found in %s", type, osCategories.get());
return builder.build();
}
builder.name(osCategory);
OsFamily family = OsFamily.fromValue(osCategory.toLowerCase());
builder.family(family);
Matcher matcher = DEFAULT_PATTERN.matcher(type.getDescription());
if (matcher.find()) {
builder.version(ComputeServiceUtils.parseVersionOrReturnEmptyString(family, matcher.group(1), osVersionMap));
}
return builder.build();
}
}

View File

@ -0,0 +1,162 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudstack.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.collect.FindResourceInSet;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.util.InetAddresses2;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
/**
* @author Adrian Cole
*/
@Singleton
public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, NodeMetadata> {
public static final Map<VirtualMachine.State, NodeState> vmStateToNodeState = ImmutableMap
.<VirtualMachine.State, NodeState> builder().put(VirtualMachine.State.STARTING, NodeState.PENDING)
.put(VirtualMachine.State.RUNNING, NodeState.RUNNING).put(VirtualMachine.State.STOPPING, NodeState.SUSPENDED)
.put(VirtualMachine.State.STOPPED, NodeState.PENDING)
.put(VirtualMachine.State.DESTROYED, NodeState.TERMINATED)
.put(VirtualMachine.State.EXPUNGING, NodeState.TERMINATED)
.put(VirtualMachine.State.MIGRATING, NodeState.PENDING).put(VirtualMachine.State.ERROR, NodeState.ERROR)
.put(VirtualMachine.State.UNKNOWN, NodeState.UNRECOGNIZED)
// TODO: is this really a state?
.put(VirtualMachine.State.SHUTDOWNED, NodeState.PENDING)
.put(VirtualMachine.State.UNRECOGNIZED, NodeState.UNRECOGNIZED).build();
private final Map<String, Credentials> credentialStore;
private final FindLocationForVirtualMachine findLocationForVirtualMachine;
private final FindHardwareForVirtualMachine findHardwareForVirtualMachine;
private final FindImageForVirtualMachine findImageForVirtualMachine;
@Inject
VirtualMachineToNodeMetadata(Map<String, Credentials> credentialStore,
FindLocationForVirtualMachine findLocationForVirtualMachine,
FindHardwareForVirtualMachine findHardwareForVirtualMachine,
FindImageForVirtualMachine findImageForVirtualMachine) {
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
this.findLocationForVirtualMachine = checkNotNull(findLocationForVirtualMachine, "findLocationForVirtualMachine");
this.findHardwareForVirtualMachine = checkNotNull(findHardwareForVirtualMachine, "findHardwareForVirtualMachine");
this.findImageForVirtualMachine = checkNotNull(findImageForVirtualMachine, "findImageForVirtualMachine");
}
@Override
public NodeMetadata apply(VirtualMachine from) {
// convert the result object to a jclouds NodeMetadata
NodeMetadataBuilder builder = new NodeMetadataBuilder();
String id = from.getZoneId() + "/" + from.getId();
builder.id(id);
builder.providerId(from.getId() + "");
builder.name(from.getName());
builder.hostname(from.getHostname());
builder.location(findLocationForVirtualMachine.apply(from));
builder.group(parseGroupFromName(from.getHostname()));
Image image = findImageForVirtualMachine.apply(from);
if (image != null) {
builder.imageId(image.getId());
builder.operatingSystem(image.getOperatingSystem());
}
Hardware hardware = findHardwareForVirtualMachine.apply(from);
if (hardware != null)
builder.hardware(hardware);
builder.state(vmStateToNodeState.get(from.getState()));
// TODO: check to see public or private
if (from.getIPAddress() != null) {
boolean isPrivate = InetAddresses2.isPrivateIPAddress(from.getIPAddress());
Set<String> addresses = ImmutableSet.<String> of(from.getIPAddress());
if (isPrivate)
builder.privateAddresses(addresses);
else
builder.publicAddresses(addresses);
}
builder.credentials(credentialStore.get("node#" + id));
return builder.build();
}
@Singleton
public static class FindLocationForVirtualMachine extends FindResourceInSet<VirtualMachine, Location> {
@Inject
public FindLocationForVirtualMachine(@Memoized Supplier<Set<? extends Location>> location) {
super(location);
}
@Override
public boolean matches(VirtualMachine from, Location input) {
return input.getId().equals(Long.toString(from.getZoneId()));
}
}
@Singleton
public static class FindHardwareForVirtualMachine extends FindResourceInSet<VirtualMachine, Hardware> {
@Inject
public FindHardwareForVirtualMachine(@Memoized Supplier<Set<? extends Hardware>> location) {
super(location);
}
@Override
public boolean matches(VirtualMachine from, Hardware input) {
return input.getProviderId().equals(Long.toString(from.getServiceOfferingId()));
}
}
@Singleton
public static class FindImageForVirtualMachine extends FindResourceInSet<VirtualMachine, Image> {
@Inject
public FindImageForVirtualMachine(@Memoized Supplier<Set<? extends Image>> location) {
super(location);
}
@Override
public boolean matches(VirtualMachine from, Image input) {
return input.getProviderId().equals(from.getTemplateId() + "")
// either location free image (location is null)
// or in the same zone as the VM
&& (input.getLocation() == null || input.getId().equals(from.getZoneId() + ""));
}
}
}

View File

@ -0,0 +1,54 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudstack.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Inject;
import org.jclouds.cloudstack.domain.Zone;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationBuilder;
import org.jclouds.domain.LocationScope;
import org.jclouds.location.suppliers.JustProvider;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
/**
* Converts an Zone into a Location.
*/
public class ZoneToLocation implements Function<Zone, Location> {
private final JustProvider provider;
// allow us to lazy discover the provider of a resource
@Inject
public ZoneToLocation(JustProvider provider) {
this.provider = checkNotNull(provider, "provider");
}
@Override
public Location apply(Zone zone) {
return new LocationBuilder().scope(LocationScope.ZONE).metadata(ImmutableMap.<String, Object> of())
.description(zone.getName()).id(Long.toString(zone.getId()))
.parent(Iterables.getOnlyElement(provider.get())).build();
}
}

View File

@ -0,0 +1,260 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudstack.compute.options;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import java.util.Set;
import org.jclouds.cloudstack.options.DeployVirtualMachineOptions;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.io.Payload;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
/**
* Contains options supported by the
* {@link ComputeService#createNodesInGroup(String, int, TemplateOptions)} and
* {@link ComputeService#runNodesWithTag(String, int, TemplateOptions)}
* operations on the <em>gogrid</em> provider.
*
* <h2>Usage</h2> The recommended way to instantiate a
* {@link CloudStackTemplateOptions} object is to statically import
* {@code CloudStackTemplateOptions.*} and invoke a static creation method
* followed by an instance mutator (if needed):
* <p>
*
* <pre>
* import static org.jclouds.compute.options.CloudStackTemplateOptions.Builder.*;
* ComputeService client = // get connection
* templateBuilder.options(inboundPorts(22, 80, 8080, 443));
* Set&lt;? extends NodeMetadata&gt; set = client.runNodesWithTag(tag, 2, templateBuilder.build());
* </pre>
*
* @author Adrian Cole
*/
public class CloudStackTemplateOptions extends TemplateOptions implements Cloneable {
protected Set<Long> securityGroupIds = Sets.<Long> newLinkedHashSet();
@Override
public CloudStackTemplateOptions clone() {
CloudStackTemplateOptions options = new CloudStackTemplateOptions();
copyTo(options);
return options;
}
@Override
public void copyTo(TemplateOptions to) {
super.copyTo(to);
if (to instanceof CloudStackTemplateOptions) {
CloudStackTemplateOptions eTo = CloudStackTemplateOptions.class.cast(to);
eTo.securityGroupIds(this.securityGroupIds);
}
}
/**
* @see DeployVirtualMachineOptions#securityGroupId
*/
public CloudStackTemplateOptions securityGroupId(long securityGroupId) {
this.securityGroupIds.add(securityGroupId);
return this;
}
/**
* @see DeployVirtualMachineOptions#securityGroupIds
*/
public CloudStackTemplateOptions securityGroupIds(Iterable<Long> securityGroupIds) {
Iterables.addAll(this.securityGroupIds, checkNotNull(securityGroupIds, "securityGroupIds was null"));
return this;
}
public Set<Long> getSecurityGroupIds() {
return securityGroupIds;
}
public static final CloudStackTemplateOptions NONE = new CloudStackTemplateOptions();
public static class Builder {
/**
* @see CloudStackTemplateOptions#securityGroupId
*/
public static CloudStackTemplateOptions securityGroupId(long id) {
CloudStackTemplateOptions options = new CloudStackTemplateOptions();
return options.securityGroupId(id);
}
/**
* @see CloudStackTemplateOptions#securityGroupIds
*/
public static CloudStackTemplateOptions securityGroupIds(Iterable<Long> securityGroupIds) {
CloudStackTemplateOptions options = new CloudStackTemplateOptions();
return options.securityGroupIds(securityGroupIds);
}
// methods that only facilitate returning the correct object type
/**
* @see TemplateOptions#inboundPorts(int...)
*/
public static CloudStackTemplateOptions inboundPorts(int... ports) {
CloudStackTemplateOptions options = new CloudStackTemplateOptions();
return CloudStackTemplateOptions.class.cast(options.inboundPorts(ports));
}
/**
* @see TemplateOptions#blockOnPort(int, int)
*/
public static CloudStackTemplateOptions blockOnPort(int port, int seconds) {
CloudStackTemplateOptions options = new CloudStackTemplateOptions();
return CloudStackTemplateOptions.class.cast(options.blockOnPort(port, seconds));
}
/**
* @see TemplateOptions#runScript(Payload)
*/
public static CloudStackTemplateOptions runScript(Payload script) {
CloudStackTemplateOptions options = new CloudStackTemplateOptions();
return CloudStackTemplateOptions.class.cast(options.runScript(script));
}
/**
* @see TemplateOptions#installPrivateKey(Payload)
*/
@Deprecated
public static CloudStackTemplateOptions installPrivateKey(Payload rsaKey) {
CloudStackTemplateOptions options = new CloudStackTemplateOptions();
return CloudStackTemplateOptions.class.cast(options.installPrivateKey(rsaKey));
}
/**
* @see TemplateOptions#authorizePublicKey(Payload)
*/
@Deprecated
public static CloudStackTemplateOptions authorizePublicKey(Payload rsaKey) {
CloudStackTemplateOptions options = new CloudStackTemplateOptions();
return CloudStackTemplateOptions.class.cast(options.authorizePublicKey(rsaKey));
}
/**
* @see TemplateOptions#userMetadata(Map)
*/
public static CloudStackTemplateOptions userMetadata(Map<String, String> userMetadata) {
CloudStackTemplateOptions options = new CloudStackTemplateOptions();
return CloudStackTemplateOptions.class.cast(options.userMetadata(userMetadata));
}
/**
* @see TemplateOptions#userMetadata(String, String)
*/
public static CloudStackTemplateOptions userMetadata(String key, String value) {
CloudStackTemplateOptions options = new CloudStackTemplateOptions();
return CloudStackTemplateOptions.class.cast(options.userMetadata(key, value));
}
}
// methods that only facilitate returning the correct object type
/**
* @see TemplateOptions#blockOnPort(int, int)
*/
@Override
public CloudStackTemplateOptions blockOnPort(int port, int seconds) {
return CloudStackTemplateOptions.class.cast(super.blockOnPort(port, seconds));
}
/**
* @see TemplateOptions#inboundPorts(int...)
*/
@Override
public CloudStackTemplateOptions inboundPorts(int... ports) {
return CloudStackTemplateOptions.class.cast(super.inboundPorts(ports));
}
/**
* @see TemplateOptions#authorizePublicKey(String)
*/
@Override
public CloudStackTemplateOptions authorizePublicKey(String publicKey) {
return CloudStackTemplateOptions.class.cast(super.authorizePublicKey(publicKey));
}
/**
* @see TemplateOptions#authorizePublicKey(Payload)
*/
@Override
@Deprecated
public CloudStackTemplateOptions authorizePublicKey(Payload publicKey) {
return CloudStackTemplateOptions.class.cast(super.authorizePublicKey(publicKey));
}
/**
* @see TemplateOptions#installPrivateKey(String)
*/
@Override
public CloudStackTemplateOptions installPrivateKey(String privateKey) {
return CloudStackTemplateOptions.class.cast(super.installPrivateKey(privateKey));
}
/**
* @see TemplateOptions#installPrivateKey(Payload)
*/
@Override
@Deprecated
public CloudStackTemplateOptions installPrivateKey(Payload privateKey) {
return CloudStackTemplateOptions.class.cast(super.installPrivateKey(privateKey));
}
/**
* @see TemplateOptions#runScript(Payload)
*/
@Override
public CloudStackTemplateOptions runScript(Payload script) {
return CloudStackTemplateOptions.class.cast(super.runScript(script));
}
/**
* @see TemplateOptions#runScript(byte[])
*/
@Override
@Deprecated
public CloudStackTemplateOptions runScript(byte[] script) {
return CloudStackTemplateOptions.class.cast(super.runScript(script));
}
/**
* {@inheritDoc}
*/
@Override
public CloudStackTemplateOptions userMetadata(Map<String, String> userMetadata) {
return CloudStackTemplateOptions.class.cast(super.userMetadata(userMetadata));
}
/**
* {@inheritDoc}
*/
@Override
public CloudStackTemplateOptions userMetadata(String key, String value) {
return CloudStackTemplateOptions.class.cast(super.userMetadata(key, value));
}
}

View File

@ -0,0 +1,165 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudstack.compute.strategy;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.filter;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.AsyncJob;
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.predicates.TemplatePredicates;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Credentials;
import org.jclouds.logging.Logger;
import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
/**
* defines the connection between the {@link CloudStackClient} implementation
* and the jclouds {@link ComputeService}
*
*/
@Singleton
public class CloudStackComputeServiceAdapter implements
ComputeServiceAdapter<VirtualMachine, ServiceOffering, Template, Zone> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final CloudStackClient client;
private final Predicate<Long> jobComplete;
@Inject
public CloudStackComputeServiceAdapter(CloudStackClient client, Predicate<Long> jobComplete) {
this.client = checkNotNull(client, "client");
this.jobComplete=checkNotNull(jobComplete, "jobComplete");
}
@Override
public VirtualMachine createNodeWithGroupEncodedIntoNameThenStoreCredentials(String group, String name,
org.jclouds.compute.domain.Template template, Map<String, Credentials> credentialStore) {
checkNotNull(template, "template was null");
checkNotNull(template.getOptions(), "template options was null");
checkArgument(template.getOptions().getClass().isAssignableFrom(CloudStackTemplateOptions.class),
"options class %s should have been assignable from CloudStackTemplateOptions", template.getOptions()
.getClass());
CloudStackTemplateOptions templateOptions = template.getOptions().as(CloudStackTemplateOptions.class);
DeployVirtualMachineOptions options = new DeployVirtualMachineOptions();
if (templateOptions.getSecurityGroupIds().size() > 0)
options.securityGroupIds(templateOptions.getSecurityGroupIds());
long zoneId = Long.parseLong(template.getLocation().getId());
long templateId = Long.parseLong(template.getImage().getProviderId());
long serviceOfferingId = Long.parseLong(template.getHardware().getProviderId());
System.out.printf("serviceOfferingId %d, templateId %d, zoneId %d, options %s%n", serviceOfferingId, templateId,
zoneId, options);
AsyncCreateResponse job = client.getVirtualMachineClient().deployVirtualMachineInZone(zoneId, serviceOfferingId,
templateId, options);
assert jobComplete.apply(job.getJobId());
AsyncJob<VirtualMachine> jobWithResult = client.getAsyncJobClient().<VirtualMachine> getAsyncJob(job.getJobId());
if (jobWithResult.getError() != null)
Throwables.propagate(new ExecutionException(String.format("job %s failed with exception %s", job.getId(),
jobWithResult.getError().toString())) {
private static final long serialVersionUID = 4371112085613620239L;
});
VirtualMachine vm = jobWithResult.getResult();
if (vm.isPasswordEnabled()) {
assert vm.getPassword() != null : vm;
Credentials credentials = new Credentials("root", vm.getPassword());
credentialStore.put("node#" + zoneId + "/" + vm.getId(), credentials);
} else {
// TODO: look for ssh key?
}
return vm;
}
@Override
public Iterable<ServiceOffering> listHardwareProfiles() {
// TODO: we may need to filter these
return client.getOfferingClient().listServiceOfferings();
}
@Override
public Iterable<Template> listImages() {
// TODO: we may need to filter these further
// we may also want to see if we can work with ssh keys
return filter(client.getTemplateClient().listTemplates(), TemplatePredicates.isPasswordEnabled());
}
@Override
public Iterable<VirtualMachine> listNodes() {
return client.getVirtualMachineClient().listVirtualMachines();
}
@Override
public Iterable<Zone> listLocations() {
// TODO: we may need to filter these
return client.getZoneClient().listZones();
}
@Override
public VirtualMachine getNode(String id) {
long guestId = Long.parseLong(id);
return client.getVirtualMachineClient().getVirtualMachine(guestId);
}
@Override
public void destroyNode(String id) {
long guestId = Long.parseLong(id);
client.getVirtualMachineClient().destroyVirtualMachine(guestId);
}
@Override
public void rebootNode(String id) {
client.getVirtualMachineClient().rebootVirtualMachine(Long.parseLong(id));
}
@Override
public void resumeNode(String id) {
client.getVirtualMachineClient().startVirtualMachine(Long.parseLong(id));
}
@Override
public void suspendNode(String id) {
client.getVirtualMachineClient().stopVirtualMachine(Long.parseLong(id));
}
}

View File

@ -64,8 +64,6 @@ import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError; import org.jclouds.http.annotation.ServerError;
import org.jclouds.json.config.GsonModule.DateAdapter; import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter; import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.config.RestClientModule;
@ -107,14 +105,6 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
@Override @Override
protected void configure() { protected void configure() {
bind(DateAdapter.class).to(Iso8601DateAdapter.class); bind(DateAdapter.class).to(Iso8601DateAdapter.class);
bind(SocketOpen.class).toInstance(new SocketOpen() {
@Override
public boolean apply(IPSocket arg0) {
return true;
}
});
install(new CloudStackParserModule()); install(new CloudStackParserModule());
super.configure(); super.configure();
} }

View File

@ -253,6 +253,7 @@ public class Template implements Comparable<Template> {
private String name; private String name;
@SerializedName("templatetype") @SerializedName("templatetype")
private Type type; private Type type;
//TODO: this should be a type
private String status; private String status;
private Format format; private Format format;
private String hypervisor; private String hypervisor;
@ -277,6 +278,7 @@ public class Template implements Comparable<Template> {
@SerializedName("jobid") @SerializedName("jobid")
private Long jobId; private Long jobId;
@SerializedName("jobstatus") @SerializedName("jobstatus")
//TODO: this should be a type
private String jobStatus; private String jobStatus;
public Template(long id, String displayText, String domain, long domainId, String account, long accountId, public Template(long id, String displayText, String domain, long domainId, String account, long accountId,

View File

@ -0,0 +1,155 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudstack.compute;
import static com.google.inject.name.Names.bindProperties;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import javax.inject.Singleton;
import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.CloudStackPropertiesBuilder;
import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
import org.jclouds.cloudstack.compute.strategy.CloudStackComputeServiceAdapter;
import org.jclouds.cloudstack.domain.ServiceOffering;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.features.BaseCloudStackClientLiveTest;
import org.jclouds.cloudstack.predicates.JobComplete;
import org.jclouds.cloudstack.predicates.TemplatePredicates;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.domain.Template;
import org.jclouds.domain.Credentials;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.ssh.SshClient;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.net.InetAddresses;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Module;
import com.google.inject.Provides;
@Test(groups = "live", singleThreaded = true, testName = "CloudStackComputeServiceAdapterLiveTest")
public class CloudStackComputeServiceAdapterLiveTest extends BaseCloudStackClientLiveTest {
private CloudStackComputeServiceAdapter adapter;
private VirtualMachine vm;
@BeforeGroups(groups = { "live" })
public void setupClient() {
super.setupClient();
Module module = new AbstractModule() {
@Override
protected void configure() {
bindProperties(binder(), new CloudStackPropertiesBuilder(new Properties()).build());
bind(CloudStackClient.class).toInstance(context.getApi());
}
@SuppressWarnings("unused")
@Provides
@Singleton
protected Predicate<Long> jobComplete(JobComplete jobComplete) {
return new RetryablePredicate<Long>(jobComplete, 1200, 1, 5, TimeUnit.SECONDS);
}
};
adapter = Guice.createInjector(module, new Log4JLoggingModule()).getInstance(
CloudStackComputeServiceAdapter.class);
}
@Test
public void testListLocations() {
assertFalse(Iterables.isEmpty(adapter.listLocations()));
}
@Test
public void testCreateNodeWithGroupEncodedIntoNameThenStoreCredentialsWithSecurityGroup() {
String group = "foo";
String name = "node" + new Random().nextInt();
Template template = computeContext.getComputeService().templateBuilder().build();
// TODO: look at SecurityGroupClientLiveTest for how to do this
template.getOptions().as(CloudStackTemplateOptions.class).securityGroupId(3l);
Map<String, Credentials> credentialStore = Maps.newLinkedHashMap();
vm = adapter.createNodeWithGroupEncodedIntoNameThenStoreCredentials(group, name, template, credentialStore);
// TODO: check security groups vm.getSecurityGroups(),
// check other things, like cpu correct, mem correct, image/os is correct
// (as possible)
assert credentialStore.containsKey("node#" + vm.getZoneId() + "/" + vm.getId()) : "credentials to log into vm not found "
+ vm;
assert InetAddresses.isInetAddress(vm.getIPAddress()) : vm;
doConnectViaSsh(vm, credentialStore.get("node#" + vm.getZoneId() + "/" + vm.getId()));
}
protected void doConnectViaSsh(VirtualMachine vm, Credentials creds) {
SshClient ssh = computeContext.utils().sshFactory().create(new IPSocket(vm.getIPAddress(), 22), creds);
try {
ssh.connect();
ExecResponse hello = ssh.exec("echo hello");
assertEquals(hello.getOutput().trim(), "hello");
System.err.println(ssh.exec("df -k").getOutput());
System.err.println(ssh.exec("mount").getOutput());
System.err.println(ssh.exec("uname -a").getOutput());
} finally {
if (ssh != null)
ssh.disconnect();
}
}
@Test
public void testListHardwareProfiles() {
Iterable<ServiceOffering> profiles = adapter.listHardwareProfiles();
assertFalse(Iterables.isEmpty(profiles));
for (ServiceOffering profile : profiles) {
// TODO: check that the results are valid
}
}
@Test
public void testListImages() {
Iterable<org.jclouds.cloudstack.domain.Template> templates = adapter.listImages();
assertFalse(Iterables.isEmpty(templates));
for (org.jclouds.cloudstack.domain.Template template : templates) {
assert TemplatePredicates.isPasswordEnabled().apply(template) : template;
}
}
@AfterGroups(groups = "live")
protected void tearDown() {
if (vm != null)
adapter.destroyNode(vm.getId() + "");
super.tearDown();
}
}

View File

@ -0,0 +1,63 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudstack.compute;
import org.jclouds.cloudstack.CloudStackAsyncClient;
import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.compute.BaseComputeServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.rest.RestContext;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Module;
/**
*
* Generally disabled, as it incurs higher fees.
*
* @author Adrian Cole
*/
@Test(groups = "live", enabled = true, singleThreaded = true)
public class CloudStackComputeServiceLiveTest extends BaseComputeServiceLiveTest {
public CloudStackComputeServiceLiveTest() {
provider = "cloudstack";
}
@Override
protected Module getSshModule() {
return new SshjSshClientModule();
}
public void testAssignability() throws Exception {
@SuppressWarnings("unused")
RestContext<CloudStackClient, CloudStackAsyncClient> tmContext = new ComputeServiceContextFactory()
.createContext(provider, identity, credential).getProviderSpecificContext();
}
// cloudstack does not support metadata
@Override
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
assert node.getUserMetadata().equals(ImmutableMap.<String, String> of()) : String.format(
"node userMetadata did not match %s %s", userMetadata, node);
}
}

View File

@ -0,0 +1,85 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudstack.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Properties;
import org.jclouds.Constants;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live", testName = "CloudStackExperimentLiveTest")
public class CloudStackExperimentLiveTest {
protected String provider = "cloudstack";
protected String identity;
protected String credential;
protected String endpoint;
protected String apiversion;
@BeforeClass
protected void setupCredentials() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = System.getProperty("test." + provider + ".credential");
endpoint = System.getProperty("test." + provider + ".endpoint");
apiversion = System.getProperty("test." + provider + ".apiversion");
}
protected Properties setupProperties() {
Properties overrides = new Properties();
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
overrides.setProperty(provider + ".identity", identity);
if (credential != null)
overrides.setProperty(provider + ".credential", credential);
if (endpoint != null)
overrides.setProperty(provider + ".endpoint", endpoint);
if (apiversion != null)
overrides.setProperty(provider + ".apiversion", apiversion);
return overrides;
}
@Test
public void testAndExperiment() {
ComputeServiceContext context = null;
try {
context = new ComputeServiceContextFactory().createContext("cloudstack",
ImmutableSet.<Module> of(new Log4JLoggingModule(), new SshjSshClientModule()), setupProperties());
assert context.getComputeService().listAssignableLocations().size() > 0;
} finally {
if (context != null)
context.close();
}
}
}

View File

@ -0,0 +1,61 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudstack.compute.functions;
import static org.testng.AssertJUnit.assertEquals;
import java.util.Set;
import org.jclouds.cloudstack.domain.ServiceOffering;
import org.jclouds.cloudstack.parse.ListServiceOfferingsResponseTest;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.HardwareBuilder;
import org.jclouds.compute.domain.Processor;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
/**
* Tests {@code ServiceOfferingToHardware}
*
*/
@Test(groups = "unit")
public class ServiceOfferingToHardwareTest {
static ServiceOfferingToHardware function = new ServiceOfferingToHardware();
static Hardware one = new HardwareBuilder().ids("1").name("Small Instance")
.processors(ImmutableList.of(new Processor(1, 500))).ram(512).build();
static Hardware two = new HardwareBuilder().ids("2").name("Medium Instance")
.processors(ImmutableList.of(new Processor(1, 1000))).ram(1024).build();
@Test
public void test() {
Set<Hardware> expected = ImmutableSet.of(one, two);
Set<ServiceOffering> offerings = new ListServiceOfferingsResponseTest().expected();
Iterable<Hardware> profiles = Iterables.transform(offerings, function);
assertEquals(profiles.toString(), expected.toString());
}
}

View File

@ -0,0 +1,81 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudstack.compute.functions;
import static org.testng.AssertJUnit.assertEquals;
import java.util.Set;
import org.jclouds.cloudstack.compute.functions.TemplateToImage.FindLocationForTemplate;
import org.jclouds.cloudstack.domain.Template;
import org.jclouds.cloudstack.parse.ListTemplatesResponseTest;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.domain.Location;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
/**
* Tests {@code TemplateToImage}
*
*/
@Test(groups = "unit")
public class TemplateToImageTest {
static Supplier<Set<? extends Location>> locationSupplier = Suppliers
.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(ZoneToLocationTest.one,
ZoneToLocationTest.two));
static TemplateToImage function = new TemplateToImage(new FindLocationForTemplate(locationSupplier),
TemplateToOperatingSystemTest.function);
// location free image
static Image one = new ImageBuilder().id("2/2").providerId("2").name("CentOS 5.3(64-bit) no GUI (XenServer)")
.operatingSystem(TemplateToOperatingSystemTest.one).description("CentOS 5.3(64-bit) no GUI (XenServer)")
.build();
// location free image
static Image two = new ImageBuilder().id("2/4").providerId("4").name("CentOS 5.5(64-bit) no GUI (KVM)")
.operatingSystem(TemplateToOperatingSystemTest.two).description("CentOS 5.5(64-bit) no GUI (KVM)").build();
static Image three = new ImageBuilder().id("2/203").providerId("203").name("Windows 7 KVM")
.operatingSystem(TemplateToOperatingSystemTest.three).description("Windows 7 KVM")
.location(ZoneToLocationTest.two).build();
// location free image
static Image four = new ImageBuilder().id("2/7").providerId("7").name("CentOS 5.3(64-bit) no GUI (vSphere)")
.operatingSystem(TemplateToOperatingSystemTest.four).description("CentOS 5.3(64-bit) no GUI (vSphere)")
.build();
static Image five = new ImageBuilder().id("2/241").providerId("241").name("kvmdev4")
.operatingSystem(TemplateToOperatingSystemTest.five).description("v5.6.28_Dev4")
.location(ZoneToLocationTest.two).build();
@Test
public void test() {
Set<Image> expected = ImmutableSet.of(one, two, three, four, five);
Set<Template> offerings = new ListTemplatesResponseTest().expected();
Iterable<Image> profiles = Iterables.transform(offerings, function);
assertEquals(profiles.toString(), expected.toString());
}
}

View File

@ -0,0 +1,89 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudstack.compute.functions;
import static org.testng.AssertJUnit.assertEquals;
import java.util.Map;
import java.util.Set;
import org.jclouds.cloudstack.domain.OSType;
import org.jclouds.cloudstack.domain.Template;
import org.jclouds.cloudstack.parse.ListOSCategoriesResponseTest;
import org.jclouds.cloudstack.parse.ListOSTypesResponseTest;
import org.jclouds.cloudstack.parse.ListTemplatesResponseTest;
import org.jclouds.compute.config.BaseComputeServiceContextModule;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.json.Json;
import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.inject.Guice;
/**
* Tests {@code TemplateToOperatingSystem}
*
*/
@Test(groups = "unit")
public class TemplateToOperatingSystemTest {
static Map<Long, OSType> ostypes = Maps.<Long, OSType> uniqueIndex(new ListOSTypesResponseTest().expected(),
new Function<OSType, Long>() {
@Override
public Long apply(OSType arg0) {
return arg0.getId();
}
});
static TemplateToOperatingSystem function = new TemplateToOperatingSystem(Suppliers.ofInstance(ostypes),
Suppliers.ofInstance(new ListOSCategoriesResponseTest().expected()), new BaseComputeServiceContextModule() {
}.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice.createInjector(new GsonModule())
.getInstance(Json.class)));
static OperatingSystem one = OperatingSystem.builder().name("CentOS").family(OsFamily.CENTOS).is64Bit(false)
.version("5.3").description("CentOS 5.3 (32-bit)").build();
static OperatingSystem two = OperatingSystem.builder().name("CentOS").family(OsFamily.CENTOS).is64Bit(true)
.version("5.5").description("CentOS 5.5 (64-bit)").build();
static OperatingSystem three = OperatingSystem.builder().name("Windows").family(OsFamily.WINDOWS).is64Bit(false)
.version("7").description("Windows 7 (32-bit)").build();
static OperatingSystem four = OperatingSystem.builder().name("CentOS").family(OsFamily.CENTOS).is64Bit(true)
.version("5.3").description("CentOS 5.3 (64-bit)").build();
static OperatingSystem five = OperatingSystem.builder().name("CentOS").family(OsFamily.CENTOS).is64Bit(true)
.version("5.4").description("CentOS 5.4 (64-bit)").build();
@Test
public void test() {
Set<OperatingSystem> expected = ImmutableSet.of(one, two, three, four, five);
Set<Template> offerings = new ListTemplatesResponseTest().expected();
Iterable<OperatingSystem> profiles = Iterables.transform(offerings, function);
assertEquals(profiles.toString(), expected.toString());
}
}

View File

@ -0,0 +1,125 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudstack.compute.functions;
import static org.testng.Assert.assertEquals;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.Set;
import org.jclouds.cloudstack.compute.functions.VirtualMachineToNodeMetadata.FindHardwareForVirtualMachine;
import org.jclouds.cloudstack.compute.functions.VirtualMachineToNodeMetadata.FindImageForVirtualMachine;
import org.jclouds.cloudstack.compute.functions.VirtualMachineToNodeMetadata.FindLocationForVirtualMachine;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.parse.ListVirtualMachinesResponseTest;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
/**
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "VirtualMachineToNodeMetadataTest")
public class VirtualMachineToNodeMetadataTest {
@Test
public void testApplyWhereVirtualMachineWithNoPassword() throws UnknownHostException {
// note we are testing when no credentials are here. otherwise would be
// ("node#416696", new
// Credentials("root", "password"))
Map<String, Credentials> credentialStore = ImmutableMap.<String, Credentials> of();
Supplier<Set<? extends Location>> locationSupplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(ZoneToLocationTest.one, ZoneToLocationTest.two));
Supplier<Set<? extends Hardware>> hardwareSupplier = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(ServiceOfferingToHardwareTest.one, ServiceOfferingToHardwareTest.two));
Supplier<Set<? extends Image>> imageSupplier = Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet
.<Image> of(TemplateToImageTest.one, TemplateToImageTest.two));
VirtualMachineToNodeMetadata parser = new VirtualMachineToNodeMetadata(credentialStore,
new FindLocationForVirtualMachine(locationSupplier), new FindHardwareForVirtualMachine(hardwareSupplier),
new FindImageForVirtualMachine(imageSupplier));
// notice if we've already parsed this properly here, we can rely on it.
VirtualMachine guest = Iterables.get(new ListVirtualMachinesResponseTest().expected(), 0);
NodeMetadata node = parser.apply(guest);
assertEquals(
node.toString(),
new NodeMetadataBuilder().id("1/54").providerId("54").name("i-3-54-VM").location(ZoneToLocationTest.one)
.state(NodeState.PENDING).privateAddresses(ImmutableSet.of("10.1.1.18"))
.hardware(ServiceOfferingToHardwareTest.one).imageId(TemplateToImageTest.one.getId())
.operatingSystem(TemplateToImageTest.one.getOperatingSystem()).build().toString());
// because it wasn't present in the credential store.
assertEquals(node.getCredentials(), null);
}
@Test
public void testApplyWhereVirtualMachineWithPassword() throws UnknownHostException {
Map<String, Credentials> credentialStore = ImmutableMap.<String, Credentials> of("node#1/54", new Credentials(
"root", "password"));
Supplier<Set<? extends Location>> locationSupplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(ZoneToLocationTest.one, ZoneToLocationTest.two));
Supplier<Set<? extends Hardware>> hardwareSupplier = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(ServiceOfferingToHardwareTest.one, ServiceOfferingToHardwareTest.two));
Supplier<Set<? extends Image>> imageSupplier = Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet
.<Image> of(TemplateToImageTest.one, TemplateToImageTest.two));
VirtualMachineToNodeMetadata parser = new VirtualMachineToNodeMetadata(credentialStore,
new FindLocationForVirtualMachine(locationSupplier), new FindHardwareForVirtualMachine(hardwareSupplier),
new FindImageForVirtualMachine(imageSupplier));
// notice if we've already parsed this properly here, we can rely on it.
VirtualMachine guest = Iterables.get(new ListVirtualMachinesResponseTest().expected(), 0);
NodeMetadata node = parser.apply(guest);
assertEquals(
node.toString(),
new NodeMetadataBuilder().id("1/54").providerId("54").name("i-3-54-VM").location(ZoneToLocationTest.one)
.state(NodeState.PENDING).privateAddresses(ImmutableSet.of("10.1.1.18"))
.hardware(ServiceOfferingToHardwareTest.one).imageId(TemplateToImageTest.one.getId())
.credentials(new Credentials("root", "password"))
.operatingSystem(TemplateToImageTest.one.getOperatingSystem()).build().toString());
assertEquals(node.getCredentials(), new Credentials("root", "password"));
}
}

View File

@ -0,0 +1,63 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudstack.compute.functions;
import static org.testng.AssertJUnit.assertEquals;
import java.net.URI;
import java.util.Set;
import org.jclouds.cloudstack.domain.Zone;
import org.jclouds.cloudstack.parse.ListZonesResponseTest;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationBuilder;
import org.jclouds.domain.LocationScope;
import org.jclouds.location.suppliers.JustProvider;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
/**
* Tests {@code ZoneToLocation}
*
* @author Jason King
*/
@Test(singleThreaded = true, groups = "unit")
public class ZoneToLocationTest {
static JustProvider justProvider = new JustProvider("cloudstack", URI.create("foo"), ImmutableSet.<String> of());
static ZoneToLocation function = new ZoneToLocation(justProvider);
static Location one = new LocationBuilder().parent(Iterables.get(justProvider.get(), 0)).scope(LocationScope.ZONE)
.description("San Jose 1").id("1").build();
static Location two = new LocationBuilder().parent(Iterables.get(justProvider.get(), 0)).scope(LocationScope.ZONE)
.description("Chicago").id("2").build();
@Test
public void test() {
Set<Location> expected = ImmutableSet.of(one, two);
Set<Zone> zones = new ListZonesResponseTest().expected();
Iterable<Location> locations = Iterables.transform(zones, function);
assertEquals(locations.toString(), expected.toString());
}
}

View File

@ -0,0 +1,86 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 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.compute.options;
import static org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions.Builder.securityGroupId;
import static org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions.Builder.securityGroupIds;
import static org.testng.Assert.assertEquals;
import org.jclouds.compute.options.TemplateOptions;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
/**
* Tests possible uses of {@code CloudStackTemplateOptions} and
* {@code CloudStackTemplateOptions.Builder.*}.
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during
// surefire
@Test(groups = "unit", testName = "CloudStackTemplateOptionsTest")
public class CloudStackTemplateOptionsTest {
@Test
public void testAs() {
TemplateOptions options = new CloudStackTemplateOptions();
assertEquals(options.as(CloudStackTemplateOptions.class), options);
}
@Test
public void testDefaultSecurityGroupIds() {
TemplateOptions options = new CloudStackTemplateOptions();
assertEquals(options.as(CloudStackTemplateOptions.class).getSecurityGroupIds(), ImmutableSet.of());
}
@Test
public void testSecurityGroupId() {
TemplateOptions options = new CloudStackTemplateOptions().securityGroupId(3l);
assertEquals(options.as(CloudStackTemplateOptions.class).getSecurityGroupIds(), ImmutableSet.of(3l));
}
@Test
public void testSecurityGroupIdStatic() {
TemplateOptions options = securityGroupId(3l);
assertEquals(options.as(CloudStackTemplateOptions.class).getSecurityGroupIds(), ImmutableSet.of(3l));
}
@Test
public void testSecurityGroupIds() {
TemplateOptions options = new CloudStackTemplateOptions().securityGroupIds(ImmutableSet.of(3l));
assertEquals(options.as(CloudStackTemplateOptions.class).getSecurityGroupIds(), ImmutableSet.of(3l));
}
@Test
public void testSecurityGroupIdsStatic() {
TemplateOptions options = securityGroupIds(ImmutableSet.of(3l));
assertEquals(options.as(CloudStackTemplateOptions.class).getSecurityGroupIds(), ImmutableSet.of(3l));
}
@Test
public void testSecurityGroupIdsNullHasDecentMessage() {
try {
new CloudStackTemplateOptions().securityGroupIds(null);
assert false : "should NPE";
} catch (NullPointerException e) {
assertEquals(e.getMessage(), "securityGroupIds was null");
}
}
}

View File

@ -36,6 +36,8 @@ import org.jclouds.cloudstack.predicates.JobComplete;
import org.jclouds.cloudstack.predicates.UserPredicates; import org.jclouds.cloudstack.predicates.UserPredicates;
import org.jclouds.cloudstack.predicates.VirtualMachineDestroyed; import org.jclouds.cloudstack.predicates.VirtualMachineDestroyed;
import org.jclouds.cloudstack.predicates.VirtualMachineRunning; import org.jclouds.cloudstack.predicates.VirtualMachineRunning;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ExecResponse; import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
@ -43,7 +45,6 @@ import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect; import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.ssh.SshClient; import org.jclouds.ssh.SshClient;
import org.jclouds.sshj.config.SshjSshClientModule; import org.jclouds.sshj.config.SshjSshClientModule;
import org.testng.annotations.AfterGroups; import org.testng.annotations.AfterGroups;
@ -81,6 +82,8 @@ public class BaseCloudStackClientLiveTest {
protected ReuseOrAssociateNewPublicIPAddress reuseOrAssociate; protected ReuseOrAssociateNewPublicIPAddress reuseOrAssociate;
protected ComputeServiceContext computeContext;
protected void setupCredentials() { protected void setupCredentials() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider
+ ".identity must be set. ex. apiKey"); + ".identity must be set. ex. apiKey");
@ -121,9 +124,11 @@ public class BaseCloudStackClientLiveTest {
public void setupClient() { public void setupClient() {
setupCredentials(); setupCredentials();
Properties overrides = setupProperties(); Properties overrides = setupProperties();
context = new RestContextFactory().createContext(provider, ImmutableSet.<Module> of(new Log4JLoggingModule()), computeContext = new ComputeServiceContextFactory().createContext(provider, ImmutableSet.<Module> of(new Log4JLoggingModule(), new SshjSshClientModule()),
overrides); overrides);
context = computeContext.getProviderSpecificContext();
client = context.getApi(); client = context.getApi();
// check access // check access
Iterable<User> users = Iterables.concat(client.getAccountClient().listAccounts()); Iterable<User> users = Iterables.concat(client.getAccountClient().listAccounts());