mirror of https://github.com/apache/jclouds.git
roughed in cloudstack compute service adapter
This commit is contained in:
parent
e9cff5e17c
commit
281c92a581
|
@ -57,7 +57,7 @@ public interface ComputeServiceConstants {
|
|||
public static class ReferenceData {
|
||||
@Inject(optional = true)
|
||||
@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
|
||||
|
|
|
@ -21,8 +21,9 @@ package org.jclouds.cloudstack;
|
|||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.cloudstack.compute.config.CloudStackComputeServiceContextModule;
|
||||
import org.jclouds.cloudstack.config.CloudStackRestClientModule;
|
||||
import org.jclouds.rest.RestContextBuilder;
|
||||
import org.jclouds.compute.ComputeServiceContextBuilder;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
|
@ -30,12 +31,18 @@ import com.google.inject.Module;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class CloudStackContextBuilder extends RestContextBuilder<CloudStackClient, CloudStackAsyncClient> {
|
||||
public class CloudStackContextBuilder extends ComputeServiceContextBuilder<CloudStackClient, CloudStackAsyncClient> {
|
||||
|
||||
public CloudStackContextBuilder(Properties 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) {
|
||||
modules.add(new CloudStackRestClientModule());
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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() + ""));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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<? extends NodeMetadata> 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));
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
|
@ -64,8 +64,6 @@ import org.jclouds.http.annotation.Redirection;
|
|||
import org.jclouds.http.annotation.ServerError;
|
||||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||
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.config.RestClientModule;
|
||||
|
||||
|
@ -107,14 +105,6 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
|
|||
@Override
|
||||
protected void configure() {
|
||||
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
|
||||
bind(SocketOpen.class).toInstance(new SocketOpen() {
|
||||
|
||||
@Override
|
||||
public boolean apply(IPSocket arg0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
install(new CloudStackParserModule());
|
||||
super.configure();
|
||||
}
|
||||
|
|
|
@ -253,6 +253,7 @@ public class Template implements Comparable<Template> {
|
|||
private String name;
|
||||
@SerializedName("templatetype")
|
||||
private Type type;
|
||||
//TODO: this should be a type
|
||||
private String status;
|
||||
private Format format;
|
||||
private String hypervisor;
|
||||
|
@ -277,6 +278,7 @@ public class Template implements Comparable<Template> {
|
|||
@SerializedName("jobid")
|
||||
private Long jobId;
|
||||
@SerializedName("jobstatus")
|
||||
//TODO: this should be a type
|
||||
private String jobStatus;
|
||||
|
||||
public Template(long id, String displayText, String domain, long domainId, String account, long accountId,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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"));
|
||||
}
|
||||
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -36,6 +36,8 @@ import org.jclouds.cloudstack.predicates.JobComplete;
|
|||
import org.jclouds.cloudstack.predicates.UserPredicates;
|
||||
import org.jclouds.cloudstack.predicates.VirtualMachineDestroyed;
|
||||
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.domain.Credentials;
|
||||
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.RetryablePredicate;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.RestContextFactory;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.testng.annotations.AfterGroups;
|
||||
|
@ -81,6 +82,8 @@ public class BaseCloudStackClientLiveTest {
|
|||
|
||||
protected ReuseOrAssociateNewPublicIPAddress reuseOrAssociate;
|
||||
|
||||
protected ComputeServiceContext computeContext;
|
||||
|
||||
protected void setupCredentials() {
|
||||
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider
|
||||
+ ".identity must be set. ex. apiKey");
|
||||
|
@ -121,9 +124,11 @@ public class BaseCloudStackClientLiveTest {
|
|||
public void setupClient() {
|
||||
setupCredentials();
|
||||
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);
|
||||
|
||||
context = computeContext.getProviderSpecificContext();
|
||||
|
||||
client = context.getApi();
|
||||
// check access
|
||||
Iterable<User> users = Iterables.concat(client.getAccountClient().listAccounts());
|
||||
|
|
Loading…
Reference in New Issue