You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2014/10/27 18:25:49 UTC
[2/3] JCLOUDS-292: Added CloudSigma2 ComputeService
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/functions/ServerInfoToNodeMetadata.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/functions/ServerInfoToNodeMetadata.java b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/functions/ServerInfoToNodeMetadata.java
new file mode 100644
index 0000000..2cfc1b0
--- /dev/null
+++ b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/functions/ServerInfoToNodeMetadata.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.cloudsigma2.compute.functions;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+import org.jclouds.cloudsigma2.CloudSigma2Api;
+import org.jclouds.cloudsigma2.domain.ServerDrive;
+import org.jclouds.cloudsigma2.domain.ServerInfo;
+import org.jclouds.cloudsigma2.domain.ServerStatus;
+import org.jclouds.cloudsigma2.domain.Tag;
+import org.jclouds.compute.domain.HardwareBuilder;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadataBuilder;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.domain.Credentials;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.location.suppliers.all.JustProvider;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import java.util.Map;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Predicates.notNull;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.collect.Iterables.transform;
+
+@Singleton
+public class ServerInfoToNodeMetadata implements Function<ServerInfo, NodeMetadata> {
+
+ private final ServerDriveToVolume serverDriveToVolume;
+ private final NICToAddress nicToAddress;
+ private final Map<ServerStatus, NodeMetadata.Status> serverStatusToNodeStatus;
+ private final GroupNamingConvention groupNamingConventionWithPrefix;
+ private final GroupNamingConvention groupNamingConventionWithoutPrefix;
+ private final Map<String, Credentials> credentialStore;
+ private final JustProvider locations;
+ private final CloudSigma2Api api;
+
+ @Inject
+ public ServerInfoToNodeMetadata(ServerDriveToVolume serverDriveToVolume, NICToAddress nicToAddress,
+ Map<ServerStatus, NodeMetadata.Status> serverStatusToNodeStatus,
+ GroupNamingConvention.Factory groupNamingConvention,
+ Map<String, Credentials> credentialStore,
+ JustProvider locations, CloudSigma2Api api) {
+ this.serverDriveToVolume = checkNotNull(serverDriveToVolume, "serverDriveToVolume");
+ this.nicToAddress = checkNotNull(nicToAddress, "nicToAddress");
+ this.serverStatusToNodeStatus = checkNotNull(serverStatusToNodeStatus, "serverStatusToNodeStatus");
+ this.groupNamingConventionWithPrefix = checkNotNull(groupNamingConvention, "groupNamingConvention").create();
+ this.groupNamingConventionWithoutPrefix = groupNamingConvention.createWithoutPrefix();
+ this.credentialStore = checkNotNull(credentialStore, "credentialStore");
+ this.locations = checkNotNull(locations, "locations");
+ this.api = checkNotNull(api, "api");
+ }
+
+ @Override
+ public NodeMetadata apply(ServerInfo serverInfo) {
+ NodeMetadataBuilder builder = new NodeMetadataBuilder();
+
+ builder.ids(serverInfo.getUuid());
+ builder.name(serverInfo.getName());
+ builder.group(groupNamingConventionWithoutPrefix.extractGroup(serverInfo.getName()));
+ builder.location(getOnlyElement(locations.get()));
+
+ builder.hardware(new HardwareBuilder().ids(serverInfo.getUuid()).processor(new Processor(1, serverInfo.getCpu()))
+ .ram(serverInfo.getMemory().intValue())
+ .volumes(Iterables.transform(serverInfo.getDrives(), serverDriveToVolume)).build());
+
+ builder.tags(readTags(serverInfo));
+ builder.userMetadata(serverInfo.getMeta());
+ builder.imageId(extractImageId(serverInfo));
+ builder.status(serverStatusToNodeStatus.get(serverInfo.getStatus()));
+ builder.publicAddresses(filter(transform(serverInfo.getNics(), nicToAddress), notNull()));
+
+ // CloudSigma does not provide a way to get the credentials.
+ // Try to return them from the credential store
+ Credentials credentials = credentialStore.get("node#" + serverInfo.getUuid());
+ if (credentials instanceof LoginCredentials) {
+ builder.credentials(LoginCredentials.class.cast(credentials));
+ }
+
+ return builder.build();
+ }
+
+ private static String extractImageId(ServerInfo serverInfo) {
+ String imageId = serverInfo.getMeta().get("image_id");
+
+ if (imageId == null) {
+ ServerDrive serverBootDrive = null;
+ for (ServerDrive serverDrive : serverInfo.getDrives()) {
+ if (serverDrive.getBootOrder() != null
+ && (serverBootDrive == null || serverDrive.getBootOrder() < serverBootDrive.getBootOrder())) {
+ serverBootDrive = serverDrive;
+ }
+ }
+ if (serverBootDrive != null) {
+ imageId = serverBootDrive.getDriveUuid();
+ }
+ }
+
+ return imageId;
+ }
+
+ private Iterable<String> readTags(ServerInfo serverInfo) {
+ return transform(serverInfo.getTags(), new Function<Tag, String>() {
+ @Override
+ public String apply(Tag input) {
+ Tag tag = api.getTagInfo(input.getUuid());
+ if (tag.getName() == null) {
+ return input.getUuid();
+ }
+ String tagWithoutPrefix = groupNamingConventionWithPrefix.groupInSharedNameOrNull(tag.getName());
+ return tagWithoutPrefix != null ? tagWithoutPrefix : tag.getName();
+ }
+ });
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/functions/TemplateOptionsToStatementWithoutPublicKey.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/functions/TemplateOptionsToStatementWithoutPublicKey.java b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/functions/TemplateOptionsToStatementWithoutPublicKey.java
new file mode 100644
index 0000000..077917b
--- /dev/null
+++ b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/functions/TemplateOptionsToStatementWithoutPublicKey.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.cloudsigma2.compute.functions;
+
+import com.google.common.collect.ImmutableList;
+import org.jclouds.compute.functions.TemplateOptionsToStatement;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.scriptbuilder.InitScript;
+import org.jclouds.scriptbuilder.domain.Statement;
+import org.jclouds.scriptbuilder.domain.StatementList;
+import org.jclouds.scriptbuilder.statements.ssh.InstallRSAPrivateKey;
+
+import javax.inject.Singleton;
+
+/**
+ * Convert the template options into a statement, but ignoring the public key.
+ * <p/>
+ * The {@link org.jclouds.cloudsigma2.compute.strategy.CloudSigma2ComputeServiceAdapter} already takes care of
+ * installing it using the server metadata.
+ */
+@Singleton
+public class TemplateOptionsToStatementWithoutPublicKey extends TemplateOptionsToStatement {
+
+ @Override
+ public Statement apply(TemplateOptions options) {
+ ImmutableList.Builder<Statement> builder = ImmutableList.builder();
+ if (options.getRunScript() != null) {
+ builder.add(options.getRunScript());
+ }
+ if (options.getPrivateKey() != null) {
+ builder.add(new InstallRSAPrivateKey(options.getPrivateKey()));
+ }
+
+ ImmutableList<Statement> bootstrap = builder.build();
+ if (bootstrap.isEmpty()) {
+ return null;
+ }
+
+ if (options.getTaskName() == null && !(options.getRunScript() instanceof InitScript)) {
+ options.nameTask("bootstrap");
+ }
+ return bootstrap.size() == 1 ? bootstrap.get(0) : new StatementList(bootstrap);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/options/CloudSigma2TemplateOptions.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/options/CloudSigma2TemplateOptions.java b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/options/CloudSigma2TemplateOptions.java
new file mode 100644
index 0000000..db43a7d
--- /dev/null
+++ b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/options/CloudSigma2TemplateOptions.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.cloudsigma2.compute.options;
+
+import com.google.common.base.Objects.ToStringHelper;
+import org.jclouds.cloudsigma2.domain.DeviceEmulationType;
+import org.jclouds.cloudsigma2.domain.Model;
+import org.jclouds.compute.options.TemplateOptions;
+
+public class CloudSigma2TemplateOptions extends TemplateOptions {
+
+ private DeviceEmulationType deviceEmulationType = DeviceEmulationType.VIRTIO;
+ private Model nicModel = Model.VIRTIO;
+ private String vncPassword;
+
+ /**
+ * Configures the device emulation type.
+ */
+ public CloudSigma2TemplateOptions deviceEmulationType(DeviceEmulationType deviceEmulationType) {
+ this.deviceEmulationType = deviceEmulationType;
+ return this;
+ }
+
+ /**
+ * Configures the type of NICs to create.
+ */
+ public CloudSigma2TemplateOptions nicModel(Model nicModel) {
+ this.nicModel = nicModel;
+ return this;
+ }
+
+ /**
+ * Configures the vnc password.
+ */
+ public CloudSigma2TemplateOptions vncPassword(String vncPassword) {
+ this.vncPassword = vncPassword;
+ return this;
+ }
+
+ public DeviceEmulationType getDeviceEmulationType() {
+ return deviceEmulationType;
+ }
+
+ public Model getNicModel() {
+ return nicModel;
+ }
+
+ public String getVncPassword() {
+ return vncPassword;
+ }
+
+ @Override
+ public TemplateOptions clone() {
+ CloudSigma2TemplateOptions options = new CloudSigma2TemplateOptions();
+ copyTo(options);
+ return options;
+ }
+
+ @Override
+ public void copyTo(TemplateOptions to) {
+ super.copyTo(to);
+ if (to instanceof CloudSigma2TemplateOptions) {
+ CloudSigma2TemplateOptions eTo = CloudSigma2TemplateOptions.class.cast(to);
+ eTo.deviceEmulationType(deviceEmulationType);
+ eTo.nicModel(nicModel);
+ eTo.vncPassword(vncPassword);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + ((deviceEmulationType == null) ? 0 : deviceEmulationType.hashCode());
+ result = prime * result + ((nicModel == null) ? 0 : nicModel.hashCode());
+ result = prime * result + ((vncPassword == null) ? 0 : vncPassword.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ CloudSigma2TemplateOptions other = (CloudSigma2TemplateOptions) obj;
+ if (deviceEmulationType != other.deviceEmulationType)
+ return false;
+ if (nicModel != other.nicModel)
+ return false;
+ if (vncPassword == null) {
+ if (other.vncPassword != null)
+ return false;
+ } else if (!vncPassword.equals(other.vncPassword))
+ return false;
+ return true;
+ }
+
+ @Override
+ public ToStringHelper string() {
+ ToStringHelper toString = super.string().omitNullValues();
+ toString.add("deviceEmulationType", deviceEmulationType);
+ toString.add("nicModel", nicModel);
+ toString.add("vncPassword", vncPassword);
+ return toString;
+ }
+
+ public static class Builder {
+
+ /**
+ * @see CloudSigma2TemplateOptions#deviceEmulationType(DeviceEmulationType)
+ */
+ public CloudSigma2TemplateOptions deviceEmulationType(DeviceEmulationType deviceEmulationType) {
+ CloudSigma2TemplateOptions options = new CloudSigma2TemplateOptions();
+ options.deviceEmulationType(deviceEmulationType);
+ return options;
+ }
+
+ /**
+ * @see CloudSigma2TemplateOptions#nicModel(Model)
+ */
+ public CloudSigma2TemplateOptions nicModel(Model nicModel) {
+ CloudSigma2TemplateOptions options = new CloudSigma2TemplateOptions();
+ options.nicModel(nicModel);
+ return options;
+ }
+
+ /**
+ * @see CloudSigma2TemplateOptions#vncPassword(String)
+ */
+ public CloudSigma2TemplateOptions vncPassword(String vncPassword) {
+ CloudSigma2TemplateOptions options = new CloudSigma2TemplateOptions();
+ options.vncPassword(vncPassword);
+ return options;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/strategy/CloudSigma2ComputeServiceAdapter.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/strategy/CloudSigma2ComputeServiceAdapter.java b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/strategy/CloudSigma2ComputeServiceAdapter.java
new file mode 100644
index 0000000..69decb2
--- /dev/null
+++ b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/compute/strategy/CloudSigma2ComputeServiceAdapter.java
@@ -0,0 +1,407 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.cloudsigma2.compute.strategy;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSet.Builder;
+import com.google.common.collect.Maps;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.inject.Inject;
+
+import org.jclouds.Constants;
+import org.jclouds.cloudsigma2.CloudSigma2Api;
+import org.jclouds.cloudsigma2.compute.options.CloudSigma2TemplateOptions;
+import org.jclouds.cloudsigma2.domain.DriveInfo;
+import org.jclouds.cloudsigma2.domain.DriveStatus;
+import org.jclouds.cloudsigma2.domain.FirewallAction;
+import org.jclouds.cloudsigma2.domain.FirewallDirection;
+import org.jclouds.cloudsigma2.domain.FirewallIpProtocol;
+import org.jclouds.cloudsigma2.domain.FirewallPolicy;
+import org.jclouds.cloudsigma2.domain.FirewallRule;
+import org.jclouds.cloudsigma2.domain.IPConfiguration;
+import org.jclouds.cloudsigma2.domain.IPConfigurationType;
+import org.jclouds.cloudsigma2.domain.LibraryDrive;
+import org.jclouds.cloudsigma2.domain.MediaType;
+import org.jclouds.cloudsigma2.domain.NIC;
+import org.jclouds.cloudsigma2.domain.ServerDrive;
+import org.jclouds.cloudsigma2.domain.ServerInfo;
+import org.jclouds.cloudsigma2.domain.ServerStatus;
+import org.jclouds.cloudsigma2.domain.Tag;
+import org.jclouds.cloudsigma2.domain.VLANInfo;
+import org.jclouds.compute.ComputeServiceAdapter;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.HardwareBuilder;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.Volume;
+import org.jclouds.compute.domain.internal.VolumeImpl;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.logging.Logger;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import java.math.BigInteger;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.base.Throwables.propagate;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.transform;
+import static com.google.common.collect.Lists.transform;
+import static com.google.common.util.concurrent.Futures.allAsList;
+import static com.google.common.util.concurrent.Futures.getUnchecked;
+import static org.jclouds.cloudsigma2.config.CloudSigma2Properties.PROPERTY_DELETE_DRIVES;
+import static org.jclouds.cloudsigma2.config.CloudSigma2Properties.PROPERTY_VNC_PASSWORD;
+import static org.jclouds.cloudsigma2.config.CloudSigma2Properties.TIMEOUT_DRIVE_CLONED;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
+
+@Singleton
+public class CloudSigma2ComputeServiceAdapter implements
+ ComputeServiceAdapter<ServerInfo, Hardware, LibraryDrive, Location> {
+
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ private final CloudSigma2Api api;
+ private final ListeningExecutorService userExecutor;
+ private final String defaultVncPassword;
+ private final Predicate<DriveInfo> driveCloned;
+ private final Predicate<String> serverStopped;
+ private final boolean destroyDrives;
+ private final GroupNamingConvention groupNamingConvention;
+
+ @Inject
+ public CloudSigma2ComputeServiceAdapter(CloudSigma2Api api,
+ @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService
+ userExecutor,
+ @Named(PROPERTY_VNC_PASSWORD) String defaultVncPassword,
+ @Named(TIMEOUT_DRIVE_CLONED) Predicate<DriveInfo> driveCloned,
+ @Named(TIMEOUT_NODE_SUSPENDED) Predicate<String> serverStopped,
+ @Named(PROPERTY_DELETE_DRIVES) boolean destroyDrives,
+ GroupNamingConvention.Factory groupNamingConvention) {
+ this.api = checkNotNull(api, "api");
+ this.userExecutor = checkNotNull(userExecutor, "userExecutor");
+ this.defaultVncPassword = checkNotNull(defaultVncPassword, "defaultVncPassword");
+ this.driveCloned = checkNotNull(driveCloned, "driveCloned");
+ this.serverStopped = checkNotNull(serverStopped, "serverStopped");
+ this.destroyDrives = destroyDrives;
+ this.groupNamingConvention = checkNotNull(groupNamingConvention, "groupNamingConvention").create();
+ }
+
+ @Override
+ public NodeAndInitialCredentials<ServerInfo> createNodeWithGroupEncodedIntoName(String group, String name,
+ Template template) {
+ CloudSigma2TemplateOptions options = template.getOptions().as(CloudSigma2TemplateOptions.class);
+ Image image = template.getImage();
+ Hardware hardware = template.getHardware();
+
+ DriveInfo drive = api.getLibraryDrive(image.getProviderId());
+
+ if (!drive.getMedia().equals(MediaType.CDROM)) {
+ logger.debug(">> cloning library drive %s...", image.getProviderId());
+
+ drive = api.cloneLibraryDrive(image.getProviderId(), null);
+ driveCloned.apply(drive);
+
+ // Refresh the drive object and verify the clone operation didn't time out
+ drive = api.getDriveInfo(drive.getUuid());
+ DriveStatus status = drive.getStatus();
+
+ if (DriveStatus.UNMOUNTED != status) {
+ if (destroyDrives) {
+ // Rollback the cloned drive, if needed
+ logger.error(">> clone operation failed. Rolling back drive (%s)...", drive);
+ destroyDrives(ImmutableList.of(drive.getUuid()));
+ }
+ throw new IllegalStateException("Resource is in invalid status: " + status);
+ }
+
+ logger.debug(">> drive cloned (%s)...", drive);
+ }
+
+ ImmutableList.Builder<FirewallRule> firewallRulesBuilder = ImmutableList.builder();
+ for (int port : options.getInboundPorts()) {
+ firewallRulesBuilder.add(new FirewallRule.Builder().action(FirewallAction.ACCEPT)
+ .ipProtocol(FirewallIpProtocol.TCP).direction(FirewallDirection.IN).destinationPort("" + port).build());
+ }
+
+ List<NIC> nics = null;
+ try {
+ logger.debug(">> creating firewall policies...");
+ FirewallPolicy firewallPolicy = api.createFirewallPolicy(new FirewallPolicy.Builder().rules(
+ firewallRulesBuilder.build()).build());
+ nics = configureNICs(options, firewallPolicy);
+ } catch (Exception ex) {
+ if (destroyDrives) {
+ logger.debug(">> rolling back the cloned drive...", drive.getUuid());
+ destroyDrives(ImmutableList.of(drive.getUuid()));
+ }
+ throw propagate(ex);
+ }
+
+ List<Tag> tagIds = configureTags(options);
+
+ // Cloud init images expect the public key in the server metadata
+ Map<String, String> metadata = Maps.newLinkedHashMap();
+ metadata.put("image_id", image.getProviderId());
+ if (!Strings.isNullOrEmpty(options.getPublicKey())) {
+ metadata.put("ssh_public_key", options.getPublicKey());
+ }
+ metadata.putAll(options.getUserMetadata());
+
+ ServerInfo serverInfo = null;
+ try {
+ logger.debug(">> creating server...");
+
+ serverInfo = api.createServer(new ServerInfo.Builder()
+ .name(name)
+ .cpu((int) hardware.getProcessors().get(0).getSpeed())
+ .memory(BigInteger.valueOf(hardware.getRam()).multiply(BigInteger.valueOf(1024 * 1024)))
+ .drives(ImmutableList.of(drive.toServerDrive(1, "0:1", options.getDeviceEmulationType())))
+ .nics(nics)
+ .meta(metadata)
+ .tags(tagIds)
+ .vncPassword(Optional.fromNullable(options.getVncPassword()).or(defaultVncPassword)).build());
+
+ api.startServer(serverInfo.getUuid());
+
+ return new NodeAndInitialCredentials<ServerInfo>(serverInfo, serverInfo.getUuid(), LoginCredentials.builder()
+ .build());
+ } catch (Exception ex) {
+ try {
+ if (serverInfo != null) {
+ logger.debug(">> rolling back the server...");
+ api.deleteServer(serverInfo.getUuid());
+ }
+ } finally {
+ try {
+ if (destroyDrives) {
+ logger.debug(">> rolling back the cloned drive...");
+ destroyDrives(ImmutableList.of(drive.getUuid()));
+ }
+ } finally {
+ deleteTags(tagIds);
+ }
+ }
+ throw propagate(ex);
+ }
+ }
+
+ @Override
+ public Iterable<Hardware> listHardwareProfiles() {
+ // Return a hardcoded list of hardware profiles until
+ // https://issues.apache.org/jira/browse/JCLOUDS-482 is fixed
+ Builder<Hardware> hardware = ImmutableSet.builder();
+ Builder<Integer> ramSetBuilder = ImmutableSet.builder();
+ Builder<Double> cpuSetBuilder = ImmutableSet.builder();
+ for (int i = 1; i < 65; i++) {
+ ramSetBuilder.add(i * 1024);
+ }
+ for (int i = 1; i < 41; i++) {
+ cpuSetBuilder.add((double) i * 1000);
+ }
+ for (int ram : ramSetBuilder.build()) {
+ for (double cpu : cpuSetBuilder.build()) {
+ hardware.add(new HardwareBuilder().ids(String.format("cpu=%f,ram=%d", cpu, ram))
+ .processor(new Processor(1, cpu)).ram(ram)
+ .volumes(ImmutableList.<Volume>of(new VolumeImpl(null, true, false))).build());
+ }
+ }
+ return hardware.build();
+ }
+
+ @Override
+ public Iterable<LibraryDrive> listImages() {
+ return api.listLibraryDrives().concat();
+ }
+
+ @Override
+ public LibraryDrive getImage(String uuid) {
+ return api.getLibraryDrive(uuid);
+ }
+
+ @Override
+ public Iterable<Location> listLocations() {
+ // Nothing to return here. Each provider will configure the locations
+ return ImmutableSet.<Location>of();
+ }
+
+ @Override
+ public ServerInfo getNode(String uuid) {
+ return api.getServerInfo(uuid);
+ }
+
+ @Override
+ public void destroyNode(String uuid) {
+ ServerInfo server = api.getServerInfo(uuid);
+
+ if (ServerStatus.RUNNING == server.getStatus()) {
+ api.stopServer(uuid);
+ waitUntilServerIsStopped(uuid);
+ }
+
+ deleteTags(server.getTags());
+
+ List<String> driveIds = transform(server.getDrives(), new Function<ServerDrive, String>() {
+ @Override
+ public String apply(ServerDrive input) {
+ return input.getDriveUuid();
+ }
+ });
+
+ logger.debug(">> deleting server...");
+ api.deleteServer(uuid);
+
+ if (destroyDrives) {
+ logger.debug(">> deleting server drives...");
+ destroyDrives(driveIds);
+ }
+ }
+
+ @Override
+ public void rebootNode(String uuid) {
+ api.stopServer(uuid);
+ waitUntilServerIsStopped(uuid);
+ api.startServer(uuid);
+ }
+
+ @Override
+ public void resumeNode(String uuid) {
+ api.startServer(uuid);
+ }
+
+ @Override
+ public void suspendNode(String uuid) {
+ api.stopServer(uuid);
+ }
+
+ @Override
+ public Iterable<ServerInfo> listNodes() {
+ return api.listServersInfo().concat();
+ }
+
+ @Override
+ public Iterable<ServerInfo> listNodesByIds(final Iterable<String> uuids) {
+ // Only fetch the requested nodes. Do it in parallel.
+ ListenableFuture<List<ServerInfo>> futures = allAsList(transform(uuids,
+ new Function<String, ListenableFuture<ServerInfo>>() {
+ @Override
+ public ListenableFuture<ServerInfo> apply(final String input) {
+ return userExecutor.submit(new Callable<ServerInfo>() {
+ @Override
+ public ServerInfo call() throws Exception {
+ return api.getServerInfo(input);
+ }
+ });
+ }
+ }));
+
+ return getUnchecked(futures);
+ }
+
+ private void waitUntilServerIsStopped(String uuid) {
+ serverStopped.apply(uuid);
+ ServerInfo server = api.getServerInfo(uuid);
+ checkState(server.getStatus() == ServerStatus.STOPPED, "Resource is in invalid status: %s", server.getStatus());
+ }
+
+ private List<NIC> configureNICs(CloudSigma2TemplateOptions options, FirewallPolicy firewallPolicy) {
+ ImmutableList.Builder<NIC> nics = ImmutableList.builder();
+ for (String network : options.getNetworks()) {
+ VLANInfo vlan = api.getVLANInfo(network);
+ checkArgument(vlan != null, "network %s not found", network);
+ nics.add(new NIC.Builder().vlan(vlan).firewallPolicy(firewallPolicy).model(options.getNicModel()).build());
+ }
+
+ // If no network has been specified, assign an IP from the DHCP
+ if (options.getNetworks().isEmpty()) {
+ logger.debug(">> no networks configured. Will assign an IP from the DHCP...");
+ NIC nic = new NIC.Builder().firewallPolicy(firewallPolicy).model(options.getNicModel())
+ .ipV4Configuration(new IPConfiguration.Builder().configurationType(IPConfigurationType.DHCP).build())
+ .build();
+ nics.add(nic);
+ }
+
+ return nics.build();
+ }
+
+ private List<Tag> configureTags(CloudSigma2TemplateOptions options) {
+ ImmutableList.Builder<Tag> builder = ImmutableList.builder();
+ for (String tagName : options.getTags()) {
+ String nameWithPrefix = groupNamingConvention.sharedNameForGroup(tagName);
+ builder.add(new Tag.Builder().name(nameWithPrefix).build());
+ }
+
+ List<Tag> tags = builder.build();
+ builder = ImmutableList.builder();
+
+ if (!tags.isEmpty()) {
+ logger.debug(">> creating tags...");
+ builder.addAll(api.createTags(tags));
+ }
+
+ return builder.build();
+ }
+
+ private void deleteTags(List<Tag> tags) {
+ logger.debug(">> deleting server tags...");
+ Iterable<Tag> customTags = filter(tags, new Predicate<Tag>() {
+ @Override
+ public boolean apply(Tag input) {
+ // Only delete the tags jclouds has set
+ Tag tag = api.getTagInfo(input.getUuid());
+ return groupNamingConvention.groupInSharedNameOrNull(tag.getName()) != null;
+ }
+ });
+
+ for (Tag tag : customTags) {
+ try {
+ // Try to delete the tags but don't fail if the can't be deleted
+ api.deleteTag(tag.getUuid());
+ } catch (Exception ex) {
+ logger.warn(ex, ">> could not delete tag: %s", tag);
+ }
+ }
+ }
+
+ private void destroyDrives(List<String> driveIds) {
+ try {
+ // Try to delete the drives but don't fail if the can't be deleted, as the server has been already removed.
+ api.deleteDrives(driveIds);
+ } catch (Exception ex) {
+ logger.warn(ex, ">> could not delete drives: [%s]", Joiner.on(',').join(driveIds));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/config/CloudSigma2Properties.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/config/CloudSigma2Properties.java b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/config/CloudSigma2Properties.java
index 66a35a7..b83ae0d 100644
--- a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/config/CloudSigma2Properties.java
+++ b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/config/CloudSigma2Properties.java
@@ -19,8 +19,19 @@ package org.jclouds.cloudsigma2.config;
public class CloudSigma2Properties {
/**
- * default VNC password used on new machines
+ * Default VNC password used on new machines
*/
public static final String PROPERTY_VNC_PASSWORD = "jclouds.cloudsigma.vnc-password";
-
+
+ /**
+ * Time in milliseconds to wait for a drive to be cloned
+ * Default: 60000
+ */
+ public static final String TIMEOUT_DRIVE_CLONED = "jclouds.cloudsigma.timeout.drive-cloned";
+
+ /**
+ * Controls if the drives of a server should be destroyed when deleting the server
+ * Default: true
+ */
+ public static final String PROPERTY_DELETE_DRIVES = "jclouds.cloudsigma.delete-drives";
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/Drive.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/Drive.java b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/Drive.java
index ec2ff76..14570d4 100644
--- a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/Drive.java
+++ b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/Drive.java
@@ -166,7 +166,7 @@ public class Drive extends Item {
* @param deviceChannel device channel in format {controller:unit} ex. 0:1, 0:2, etc.
* @param deviceEmulationType device emulation type
*/
- public ServerDrive toServerDrive(int bootOrder, String deviceChannel, DeviceEmulationType deviceEmulationType) {
+ public ServerDrive toServerDrive(Integer bootOrder, String deviceChannel, DeviceEmulationType deviceEmulationType) {
return new ServerDrive(bootOrder, deviceChannel, deviceEmulationType, this.uuid);
}
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/DrivesListRequestFieldsGroup.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/DrivesListRequestFieldsGroup.java b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/DrivesListRequestFieldsGroup.java
index 9100050..56aad17 100644
--- a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/DrivesListRequestFieldsGroup.java
+++ b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/DrivesListRequestFieldsGroup.java
@@ -16,7 +16,7 @@
*/
package org.jclouds.cloudsigma2.domain;
-import com.google.common.base.Joiner;
+import java.util.Iterator;
public class DrivesListRequestFieldsGroup {
private final Iterable<String> fields;
@@ -31,6 +31,18 @@ public class DrivesListRequestFieldsGroup {
@Override
public String toString() {
- return Joiner.on(',').join(fields);
+ String returnString = "";
+
+ Iterator<?> iterator = fields.iterator();
+
+ while (iterator.hasNext()) {
+ returnString += iterator.next();
+
+ if (iterator.hasNext()) {
+ returnString += ",";
+ }
+ }
+
+ return returnString;
}
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/FirewallPolicy.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/FirewallPolicy.java b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/FirewallPolicy.java
index 50cf8ea..05ba638 100644
--- a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/FirewallPolicy.java
+++ b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/FirewallPolicy.java
@@ -30,6 +30,7 @@ public class FirewallPolicy extends Item {
private Map<String, String> meta;
private Owner owner;
private List<FirewallRule> rules;
+ private List<Tag> tags;
private List<Server> servers;
/**
@@ -69,6 +70,15 @@ public class FirewallPolicy extends Item {
}
/**
+ * @param tags Many related resources. Can be either a list of URIs or list of individually nested resource data.
+ * @return
+ */
+ public Builder tags(List<Tag> tags) {
+ this.tags = ImmutableList.copyOf(tags);
+ return this;
+ }
+
+ /**
* @param resourceUri Resource URI
* @return
*/
@@ -98,25 +108,37 @@ public class FirewallPolicy extends Item {
return this;
}
+ public static Builder fromFirewallPolicy(FirewallPolicy firewallPolicy) {
+ return new Builder()
+ .resourceUri(firewallPolicy.getResourceUri())
+ .uuid(firewallPolicy.getUuid())
+ .rules(firewallPolicy.getRules())
+ .name(firewallPolicy.getName())
+ .meta(firewallPolicy.getMeta())
+ .tags(firewallPolicy.getTags());
+ }
+
public FirewallPolicy build() {
- return new FirewallPolicy(meta, name, owner, resourceUri, rules, servers, uuid);
+ return new FirewallPolicy(meta, name, owner, resourceUri, rules, servers, tags, uuid);
}
}
private final Map<String, String> meta;
private final Owner owner;
private final List<FirewallRule> rules;
+ private final List<Tag> tags;
private final List<Server> servers;
@ConstructorProperties({
- "meta", "name", "owner", "resource_uri", "rules", "servers", "uuid"
+ "meta", "name", "owner", "resource_uri", "rules", "servers", "tags", "uuid"
})
public FirewallPolicy(Map<String, String> meta, String name, Owner owner, URI resourceUri, List<FirewallRule> rules,
- List<Server> servers, String uuid) {
+ List<Server> servers, List<Tag> tags, String uuid) {
super(uuid, name, resourceUri);
this.meta = meta;
this.owner = owner;
this.rules = rules == null ? new ArrayList<FirewallRule>() : rules;
+ this.tags = tags == null ? new ArrayList<Tag>() : tags;
this.servers = servers == null ? new ArrayList<Server>() : servers;
}
@@ -163,6 +185,13 @@ public class FirewallPolicy extends Item {
}
/**
+ * @return Related resources URI list.
+ */
+ public List<Tag> getTags() {
+ return tags;
+ }
+
+ /**
* @return UUID of the policy
*/
public String getUuid() {
@@ -172,7 +201,7 @@ public class FirewallPolicy extends Item {
@Override
public boolean equals(Object o) {
if (this == o) return true;
- if (!(o instanceof FirewallPolicy)) return false;
+ if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
FirewallPolicy that = (FirewallPolicy) o;
@@ -181,6 +210,7 @@ public class FirewallPolicy extends Item {
if (owner != null ? !owner.equals(that.owner) : that.owner != null) return false;
if (rules != null ? !rules.equals(that.rules) : that.rules != null) return false;
if (servers != null ? !servers.equals(that.servers) : that.servers != null) return false;
+ if (tags != null ? !tags.equals(that.tags) : that.tags != null) return false;
return true;
}
@@ -191,6 +221,7 @@ public class FirewallPolicy extends Item {
result = 31 * result + (meta != null ? meta.hashCode() : 0);
result = 31 * result + (owner != null ? owner.hashCode() : 0);
result = 31 * result + (rules != null ? rules.hashCode() : 0);
+ result = 31 * result + (tags != null ? tags.hashCode() : 0);
result = 31 * result + (servers != null ? servers.hashCode() : 0);
return result;
}
@@ -199,12 +230,10 @@ public class FirewallPolicy extends Item {
public String toString() {
return "[" +
"meta=" + meta +
- ", name='" + name + '\'' +
", owner=" + owner +
- ", resourceUri='" + resourceUri + '\'' +
", rules=" + rules +
+ ", tags=" + tags +
", servers=" + servers +
- ", uuid='" + uuid + '\'' +
"]";
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/LibraryDrive.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/LibraryDrive.java b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/LibraryDrive.java
index d479867..d7a0ca5 100644
--- a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/LibraryDrive.java
+++ b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/LibraryDrive.java
@@ -38,6 +38,7 @@ public class LibraryDrive extends DriveInfo {
private String os;
private boolean isPaid;
private String url;
+ private String version;
public Builder arch(String arch) {
this.arch = arch;
@@ -84,6 +85,11 @@ public class LibraryDrive extends DriveInfo {
return this;
}
+ public Builder version(String version) {
+ this.version = version;
+ return this;
+ }
+
/**
* {@inheritDoc}
*/
@@ -226,7 +232,7 @@ public class LibraryDrive extends DriveInfo {
public LibraryDrive build() {
return new LibraryDrive(uuid, name, resourceUri, size, owner, status, allowMultimount, affinities, jobs,
licenses, media, meta, mountedOn, tags, arch, category, description, isFavorite, imageType, installNotes,
- os, isPaid, url);
+ os, isPaid, url, version);
}
}
@@ -243,18 +249,20 @@ public class LibraryDrive extends DriveInfo {
@Named("paid")
private final boolean isPaid;
private final String url;
+ private final String version;
@ConstructorProperties({
"uuid", "name", "resource_uri", "size", "owner", "status",
"allow_multimount", "affinities", "jobs", "licenses",
"media", "meta", "mounted_on", "tags", "arch", "category",
- "description", "favourite", "image_type", "install_notes", "os", "paid", "url"
+ "description", "favourite", "image_type", "install_notes",
+ "os", "paid", "url", "version"
})
public LibraryDrive(String uuid, String name, URI resourceUri, BigInteger size, Owner owner, DriveStatus status,
boolean allowMultimount, List<String> affinities, List<Job> jobs, List<DriveLicense> licenses,
MediaType media, Map<String, String> meta, List<Server> mountedOn, List<String> tags,
String arch, List<String> category, String description, boolean favorite, String imageType,
- String installNotes, String os, boolean paid, String url) {
+ String installNotes, String os, boolean paid, String url, String version) {
super(uuid, name, resourceUri, size, owner, status, allowMultimount, affinities, jobs, licenses, media, meta,
mountedOn, tags);
this.arch = arch;
@@ -266,6 +274,7 @@ public class LibraryDrive extends DriveInfo {
this.os = os;
this.isPaid = paid;
this.url = url;
+ this.version = version;
}
/**
@@ -331,10 +340,17 @@ public class LibraryDrive extends DriveInfo {
return url;
}
+ /**
+ * @return Operating system version.
+ */
+ public String getVersion() {
+ return version;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
- if (!(o instanceof LibraryDrive)) return false;
+ if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
LibraryDrive that = (LibraryDrive) o;
@@ -348,6 +364,7 @@ public class LibraryDrive extends DriveInfo {
if (installNotes != null ? !installNotes.equals(that.installNotes) : that.installNotes != null) return false;
if (os != null ? !os.equals(that.os) : that.os != null) return false;
if (url != null ? !url.equals(that.url) : that.url != null) return false;
+ if (version != null ? !version.equals(that.version) : that.version != null) return false;
return true;
}
@@ -364,15 +381,14 @@ public class LibraryDrive extends DriveInfo {
result = 31 * result + (os != null ? os.hashCode() : 0);
result = 31 * result + (isPaid ? 1 : 0);
result = 31 * result + (url != null ? url.hashCode() : 0);
+ result = 31 * result + (version != null ? version.hashCode() : 0);
return result;
}
@Override
public String toString() {
- return "[uuid=" + uuid + ", name=" + name + ", size=" + size + ", owner=" + owner + ", status=" + status
- + ", affinities=" + affinities + ", jobs=" + jobs + ", licenses=" + licenses + ", media=" + media
- + ", meta=" + meta + ", mountedOn=" + mountedOn + ", tags=" + tags +
- ", arch='" + arch + '\'' +
+ return "LibraryDrive{" +
+ "arch='" + arch + '\'' +
", category=" + category +
", description='" + description + '\'' +
", isFavorite=" + isFavorite +
@@ -381,6 +397,7 @@ public class LibraryDrive extends DriveInfo {
", os='" + os + '\'' +
", isPaid=" + isPaid +
", url='" + url + '\'' +
- "]";
+ ", version='" + version + '\'' +
+ '}';
}
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/ServerAvailabilityGroup.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/ServerAvailabilityGroup.java b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/ServerAvailabilityGroup.java
index 4104f15..855e782 100644
--- a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/ServerAvailabilityGroup.java
+++ b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/ServerAvailabilityGroup.java
@@ -16,10 +16,9 @@
*/
package org.jclouds.cloudsigma2.domain;
+import java.util.Iterator;
import java.util.List;
-import com.google.common.base.Joiner;
-
public class ServerAvailabilityGroup {
private final List<String> uuids;
@@ -51,6 +50,18 @@ public class ServerAvailabilityGroup {
@Override
public String toString() {
- return Joiner.on(',').join(uuids);
+ String returnString = "";
+
+ Iterator<?> iterator = uuids.iterator();
+
+ while (iterator.hasNext()) {
+ returnString += iterator.next();
+
+ if (iterator.hasNext()) {
+ returnString += ",";
+ }
+ }
+
+ return returnString;
}
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/ServerDrive.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/ServerDrive.java b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/ServerDrive.java
index 7f69e35..cff05c1 100644
--- a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/ServerDrive.java
+++ b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/ServerDrive.java
@@ -22,12 +22,12 @@ import java.beans.ConstructorProperties;
public class ServerDrive {
public static class Builder {
- private int bootOrder;
+ private Integer bootOrder;
private String deviceChannel;
private DeviceEmulationType deviceEmulationType;
private Drive drive;
- public Builder bootOrder(int bootOrder) {
+ public Builder bootOrder(Integer bootOrder) {
this.bootOrder = bootOrder;
return this;
}
@@ -53,7 +53,7 @@ public class ServerDrive {
}
@Named("boot_order")
- private final int bootOrder;
+ private final Integer bootOrder;
@Named("dev_channel")
private final String deviceChannel;
@Named("device")
@@ -71,7 +71,7 @@ public class ServerDrive {
@ConstructorProperties({
"boot_order", "dev_channel", "device", "drive"
})
- public ServerDrive(int bootOrder, String deviceChannel, DeviceEmulationType deviceEmulationType, Drive drive) {
+ public ServerDrive(Integer bootOrder, String deviceChannel, DeviceEmulationType deviceEmulationType, Drive drive) {
this.bootOrder = bootOrder;
this.deviceChannel = deviceChannel;
this.deviceEmulationType = deviceEmulationType;
@@ -96,7 +96,7 @@ public class ServerDrive {
/**
* @return drive boot order
*/
- public int getBootOrder() {
+ public Integer getBootOrder() {
return bootOrder;
}
@@ -131,31 +131,37 @@ public class ServerDrive {
@Override
public boolean equals(Object o) {
if (this == o) return true;
- if (!(o instanceof ServerDrive)) return false;
+ if (o == null || getClass() != o.getClass()) return false;
ServerDrive that = (ServerDrive) o;
- if (bootOrder != that.bootOrder) return false;
- if (deviceChannel != null ? !deviceChannel.equals(that.deviceChannel) : that.deviceChannel != null)
- return false;
+ if (bootOrder != null ? !bootOrder.equals(that.bootOrder) : that.bootOrder != null) return false;
+ if (deviceChannel != null ? !deviceChannel.equals(that.deviceChannel) : that.deviceChannel != null) return false;
if (deviceEmulationType != that.deviceEmulationType) return false;
if (drive != null ? !drive.equals(that.drive) : that.drive != null) return false;
+ if (driveUuid != null ? !driveUuid.equals(that.driveUuid) : that.driveUuid != null) return false;
return true;
}
@Override
public int hashCode() {
- int result = bootOrder;
+ int result = bootOrder != null ? bootOrder.hashCode() : 0;
result = 31 * result + (deviceChannel != null ? deviceChannel.hashCode() : 0);
result = 31 * result + (deviceEmulationType != null ? deviceEmulationType.hashCode() : 0);
result = 31 * result + (drive != null ? drive.hashCode() : 0);
+ result = 31 * result + (driveUuid != null ? driveUuid.hashCode() : 0);
return result;
}
@Override
public String toString() {
- return "[bootOrder=" + bootOrder + ", deviceChannel=" + deviceChannel
- + ", deviceEmulationType=" + deviceEmulationType + ", drive=" + drive + "]";
+ return "ServerDrive{" +
+ "bootOrder=" + bootOrder +
+ ", deviceChannel='" + deviceChannel + '\'' +
+ ", deviceEmulationType=" + deviceEmulationType +
+ ", drive=" + drive +
+ ", driveUuid='" + driveUuid + '\'' +
+ '}';
}
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/ServerInfo.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/ServerInfo.java b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/ServerInfo.java
index 062eae5..f3e4a00 100644
--- a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/ServerInfo.java
+++ b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/domain/ServerInfo.java
@@ -39,7 +39,7 @@ public class ServerInfo extends Server {
private Map<String, String> meta;
private List<NIC> nics;
private List<String> requirements;
- private List<String> tags;
+ private List<Tag> tags;
private String vncPassword;
private int smp;
@@ -137,7 +137,7 @@ public class ServerInfo extends Server {
* @param tags list of tags this server is associated with
* @return ServerInfo Builder
*/
- public Builder tags(List<String> tags) {
+ public Builder tags(List<Tag> tags) {
this.tags = ImmutableList.copyOf(tags);
return this;
}
@@ -278,7 +278,7 @@ public class ServerInfo extends Server {
private final Map<String, String> meta;
private final List<NIC> nics;
private final List<String> requirements;
- private final List<String> tags;
+ private final List<Tag> tags;
@Named("vnc_password")
private final String vncPassword;
private final int smp;
@@ -292,7 +292,7 @@ public class ServerInfo extends Server {
public ServerInfo(String uuid, String name, URI resourceUri, Owner owner, ServerStatus status, ServerRuntime runtime,
int cpu, boolean cpusInsteadOfCores, List<ServerDrive> drives, boolean enableNuma,
boolean hvRelaxed, boolean hvTsc, BigInteger memory, Map<String, String> meta, List<NIC> nics,
- List<String> requirements, List<String> tags, String vncPassword, int smp) {
+ List<String> requirements, List<Tag> tags, String vncPassword, int smp) {
super(uuid, name, resourceUri, owner, status, runtime);
this.cpu = cpu;
this.cpusInsteadOfCores = cpusInsteadOfCores;
@@ -382,7 +382,7 @@ public class ServerInfo extends Server {
/**
* @return list of tags this server is associated with
*/
- public List<String> getTags() {
+ public List<Tag> getTags() {
return tags;
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/functions/internal/ParseTags.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/functions/internal/ParseTags.java b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/functions/internal/ParseTags.java
index c7427b1..ff6c1a8 100644
--- a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/functions/internal/ParseTags.java
+++ b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/functions/internal/ParseTags.java
@@ -67,25 +67,4 @@ public class ParseTags extends ParseJson<ParseTags.Tags> {
};
}
}
-
- public static class ToPagedIterableInfo extends ArgsToPagedIterable<Tag, ToPagedIterable> {
-
- private CloudSigma2Api api;
-
- @Inject
- public ToPagedIterableInfo(CloudSigma2Api api) {
- this.api = api;
- }
-
- @Override
- protected Function<Object, IterableWithMarker<Tag>> markerToNextForArgs(List<Object> args) {
- return new Function<Object, IterableWithMarker<Tag>>() {
- @Override
- public IterableWithMarker<Tag> apply(Object input) {
- PaginationOptions paginationOptions = PaginationOptions.class.cast(input);
- return api.listTagsInfo(paginationOptions);
- }
- };
- }
- }
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/handlers/CloudSigmaErrorHandler.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/handlers/CloudSigmaErrorHandler.java b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/handlers/CloudSigmaErrorHandler.java
index a2912e7..f41e865 100644
--- a/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/handlers/CloudSigmaErrorHandler.java
+++ b/cloudsigma2/src/main/java/org/jclouds/cloudsigma2/handlers/CloudSigmaErrorHandler.java
@@ -16,8 +16,11 @@
*/
package org.jclouds.cloudsigma2.handlers;
-import com.google.common.base.Throwables;
-import com.google.common.io.Closeables;
+import java.io.IOException;
+
+import javax.annotation.Resource;
+import javax.inject.Singleton;
+
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpResponse;
@@ -27,9 +30,8 @@ import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.util.Strings2;
-import javax.annotation.Resource;
-import javax.inject.Singleton;
-import java.io.IOException;
+import com.google.common.base.Throwables;
+import com.google.common.io.Closeables;
/**
* This will parse and set an appropriate exception on the command object.
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/CloudSigma2ApiExpectTest.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/CloudSigma2ApiExpectTest.java b/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/CloudSigma2ApiExpectTest.java
index e5ff7ad..1395eae 100644
--- a/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/CloudSigma2ApiExpectTest.java
+++ b/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/CloudSigma2ApiExpectTest.java
@@ -16,8 +16,16 @@
*/
package org.jclouds.cloudsigma2;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Maps;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.MediaType;
+
import org.jclouds.cloudsigma2.domain.AccountBalance;
import org.jclouds.cloudsigma2.domain.CalcSubscription;
import org.jclouds.cloudsigma2.domain.CreateSubscriptionRequest;
@@ -52,14 +60,8 @@ import org.jclouds.http.HttpResponse;
import org.jclouds.rest.internal.BaseRestApiExpectTest;
import org.testng.annotations.Test;
-import javax.ws.rs.core.MediaType;
-import java.math.BigInteger;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Maps;
@Test(groups = "unit")
public class CloudSigma2ApiExpectTest extends BaseRestApiExpectTest<CloudSigma2Api> {
@@ -323,7 +325,7 @@ public class CloudSigma2ApiExpectTest extends BaseRestApiExpectTest<CloudSigma2A
@Test
public void testCloneDrive() throws Exception {
- String uuid = "e96f3c63-6f50-47eb-9401-a56c5ccf6b32";
+ String uuid = "92ca1450-417e-4cc1-983b-1015777e2591";
CloudSigma2Api api = requestSendsResponse(
postBuilder()
.payload(payloadFromResourceWithContentType("/drives-create-request.json",
@@ -331,7 +333,7 @@ public class CloudSigma2ApiExpectTest extends BaseRestApiExpectTest<CloudSigma2A
.endpoint(endpoint + "drives/" + uuid + "/action/?do=clone")
.build(),
responseBuilder()
- .payload(payloadFromResourceWithContentType("/drives-detail.json", MediaType.APPLICATION_JSON))
+ .payload(payloadFromResourceWithContentType("/drive-cloned.json", MediaType.APPLICATION_JSON))
.build());
DriveInfo result = api.cloneDrive(uuid, new DriveInfo.Builder()
@@ -404,7 +406,7 @@ public class CloudSigma2ApiExpectTest extends BaseRestApiExpectTest<CloudSigma2A
@Test
public void testCloneLibraryDrive() throws Exception {
- String uuid = "e96f3c63-6f50-47eb-9401-a56c5ccf6b32";
+ String uuid = "8c45d8d9-4efd-44ec-9833-8d52004b4298";
CloudSigma2Api api = requestSendsResponse(
postBuilder()
.payload(payloadFromResourceWithContentType("/libdrives-create-request.json",
@@ -412,7 +414,7 @@ public class CloudSigma2ApiExpectTest extends BaseRestApiExpectTest<CloudSigma2A
.endpoint(endpoint + "libdrives/" + uuid + "/action/?do=clone")
.build(),
responseBuilder()
- .payload(payloadFromResourceWithContentType("/libdrives-single.json", MediaType.APPLICATION_JSON))
+ .payload(payloadFromResourceWithContentType("/libdrives-cloned.json", MediaType.APPLICATION_JSON))
.build());
DriveInfo result = api.cloneLibraryDrive(uuid, new LibraryDrive.Builder()
@@ -817,6 +819,27 @@ public class CloudSigma2ApiExpectTest extends BaseRestApiExpectTest<CloudSigma2A
}
@Test
+ public void testGetFirewallPolicy() throws Exception {
+ String uuid = "9001b532-857a-405a-8e50-54e342871e77";
+ CloudSigma2Api api = requestsSendResponses(
+ getBuilder()
+ .endpoint(endpoint + "fwpolicies/" + uuid + "/")
+ .build(),
+ responseBuilder()
+ .payload(payloadFromResourceWithContentType("/fwpolicies-get-single.json",
+ MediaType.APPLICATION_JSON))
+ .build(),
+ getBuilder()
+ .endpoint(endpoint + "fwpolicies/failure")
+ .build(),
+ HttpResponse.builder()
+ .statusCode(404)
+ .build());
+
+ assertNotNull(api.getFirewallPolicy(uuid));
+ }
+
+ @Test
public void testCreateFirewallPolicies() throws Exception {
CloudSigma2Api api = requestSendsResponse(
postBuilder()
@@ -1000,6 +1023,26 @@ public class CloudSigma2ApiExpectTest extends BaseRestApiExpectTest<CloudSigma2A
}
@Test
+ public void testDeleteFirewallPolicy() throws Exception {
+ String uuid = "9001b532-857a-405a-8e50-54e342871e77";
+
+ CloudSigma2Api api = requestsSendResponses(
+ deleteBuilder()
+ .endpoint(endpoint + "fwpolicies/" + uuid + "/")
+ .build(),
+ responseBuilder()
+ .build(),
+ deleteBuilder()
+ .endpoint(endpoint + "fwpolicies/failure")
+ .build(),
+ HttpResponse.builder()
+ .statusCode(404)
+ .build());
+
+ api.deleteFirewallPolicy(uuid);
+ }
+
+ @Test
public void testGetVLANInfo() throws Exception {
String uuid = "96537817-f4b6-496b-a861-e74192d3ccb0";
CloudSigma2Api api = requestSendsResponse(
@@ -1276,50 +1319,6 @@ public class CloudSigma2ApiExpectTest extends BaseRestApiExpectTest<CloudSigma2A
}
@Test
- public void testListTagsInfo() throws Exception {
- CloudSigma2Api api = requestsSendResponses(
- getBuilder()
- .endpoint(endpoint + "tags/detail/")
- .build(),
- responseBuilder()
- .payload(payloadFromResourceWithContentType("/tags-detail-first-page.json",
- MediaType.APPLICATION_JSON))
- .build(),
- getBuilder()
- .endpoint(endpoint + "tags/detail/")
- .addQueryParam("limit", "1")
- .addQueryParam("offset", "1")
- .build(),
- responseBuilder()
- .payload(payloadFromResourceWithContentType("/tags-detail-last-page.json",
- MediaType.APPLICATION_JSON))
- .build());
-
-
- List<Tag> tags = api.listTagsInfo().concat().toList();
-
- assertEquals(tags.size(), 2);
- assertEquals(tags.get(0).getUuid(), "956e2ca0-dee3-4b3f-a1be-a6e86f90946f");
- assertEquals(tags.get(1).getUuid(), "68bb0cfc-0c76-4f37-847d-7bb705c5ae46");
- }
-
-
- @Test
- public void testListTagsInfoPaginatedCollection() throws Exception {
- CloudSigma2Api api = requestSendsResponse(
- getBuilder()
- .endpoint(endpoint + "tags/detail/?limit=2&offset=2")
- .build(),
- responseBuilder()
- .payload(payloadFromResourceWithContentType("/tags-detail.json", MediaType.APPLICATION_JSON))
- .build());
-
- for (Tag tag : api.listTagsInfo(new PaginationOptions.Builder().limit(2).offset(2).build())) {
- assertNotNull(tag);
- }
- }
-
- @Test
public void testGetTagInfo() throws Exception {
String uuid = "68bb0cfc-0c76-4f37-847d-7bb705c5ae46";
CloudSigma2Api api = requestSendsResponse(
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/CloudSigma2ApiLiveTest.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/CloudSigma2ApiLiveTest.java b/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/CloudSigma2ApiLiveTest.java
index 5fcf1bb..751dea8 100644
--- a/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/CloudSigma2ApiLiveTest.java
+++ b/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/CloudSigma2ApiLiveTest.java
@@ -70,10 +70,13 @@ import com.google.common.collect.Maps;
public class CloudSigma2ApiLiveTest extends BaseApiLiveTest<CloudSigma2Api> {
private DriveInfo createdDrive;
+ private DriveInfo clonedDrive;
+ private LibraryDrive clonedLibraryDrive;
private List<DriveInfo> createdDrives;
private ServerInfo createdServer;
private List<ServerInfo> createdServers;
private FirewallPolicy createdFirewallPolicy;
+ private List<FirewallPolicy> createdFirewallPolicies;
private Tag createdTag;
private List<Tag> createdTags;
@@ -142,11 +145,23 @@ public class CloudSigma2ApiLiveTest extends BaseApiLiveTest<CloudSigma2Api> {
checkDrive(editedDrive, api.editDrive(createdDrive.getUuid(), editedDrive));
}
+ @Test(dependsOnMethods = {"testCreateDrive"})
+ public void testCloneDrive() throws Exception {
+ clonedDrive = api.cloneDrive(createdDrive.getUuid(), null);
+ checkDrive(createdDrive, clonedDrive);
+ }
+
@Test(dependsOnMethods = {"testEditDrive", "testCreateTag", "testEditTag"})
public void testDeleteDrive() throws Exception {
String uuid = createdDrive.getUuid();
api.deleteDrive(uuid);
assertNull(api.getDriveInfo(uuid));
+ String clonedDriveUuid = clonedDrive.getUuid();
+ api.deleteDrive(clonedDriveUuid);
+ assertNull(api.getDriveInfo(clonedDriveUuid));
+ String clonedLibraryDriveUuid = clonedLibraryDrive.getUuid();
+ api.deleteDrive(clonedLibraryDriveUuid);
+ assertNull(api.getDriveInfo(clonedLibraryDriveUuid));
}
@Test(dependsOnMethods = {"testCreateDrives"})
@@ -175,6 +190,13 @@ public class CloudSigma2ApiLiveTest extends BaseApiLiveTest<CloudSigma2Api> {
}
}
+ @Test
+ public void testCloneLibraryDrive() throws Exception {
+ LibraryDrive libraryDrive = api.listLibraryDrives().concat().get(0);
+ clonedLibraryDrive = api.cloneLibraryDrive(libraryDrive.getUuid(), null);
+ checkLibraryDrive(libraryDrive, clonedLibraryDrive);
+ }
+
@Test(dependsOnMethods = {"testCreateServers"})
public void testListServers() throws Exception {
assertNotNull(api.listServers());
@@ -273,6 +295,15 @@ public class CloudSigma2ApiLiveTest extends BaseApiLiveTest<CloudSigma2Api> {
assertNotNull(api.listFirewallPoliciesInfo());
}
+ @Test(dependsOnMethods = {"testCreateFirewallPolicies"})
+ public void testGetFirewallPolicy() throws Exception {
+ for (FirewallPolicy firewallPolicy : api.listFirewallPoliciesInfo().concat()) {
+ FirewallPolicy receivedPolicy = api.getFirewallPolicy(firewallPolicy.getUuid());
+ checkFirewallPolicy(firewallPolicy, receivedPolicy);
+ assertEquals(firewallPolicy.getUuid(), receivedPolicy.getUuid());
+ }
+ }
+
@Test
public void testCreateFirewallPolicies() throws Exception {
List<FirewallPolicy> newFirewallPolicies = ImmutableList.of(
@@ -329,7 +360,7 @@ public class CloudSigma2ApiLiveTest extends BaseApiLiveTest<CloudSigma2Api> {
.build()))
.build());
- List<FirewallPolicy> createdFirewallPolicies = api.createFirewallPolicies(newFirewallPolicies);
+ createdFirewallPolicies = api.createFirewallPolicies(newFirewallPolicies);
assertEquals(newFirewallPolicies.size(), createdFirewallPolicies.size());
for (int i = 0; i < newFirewallPolicies.size(); i++) {
@@ -403,6 +434,23 @@ public class CloudSigma2ApiLiveTest extends BaseApiLiveTest<CloudSigma2Api> {
checkFirewallPolicy(editedPolicy, api.editFirewallPolicy(createdFirewallPolicy.getUuid(), editedPolicy));
}
+ @Test(dependsOnMethods = {"testEditFirewallPolicy", "testCreateFirewallPolicies"})
+ public void deleteFirewallPolicies() throws Exception {
+ ImmutableList.Builder<String> stringListBuilder = ImmutableList.builder();
+
+ stringListBuilder.add(createdFirewallPolicy.getUuid());
+ api.deleteFirewallPolicy(createdFirewallPolicy.getUuid());
+
+ for (FirewallPolicy firewallPolicy : createdFirewallPolicies) {
+ stringListBuilder.add(firewallPolicy.getUuid());
+ api.deleteFirewallPolicy(firewallPolicy.getUuid());
+ }
+
+ ImmutableList<String> uuids = stringListBuilder.build();
+ FluentIterable<FirewallPolicy> servers = api.listFirewallPolicies().concat();
+ assertFalse(any(transform(servers, extractUuid()), in(uuids)));
+ }
+
@Test
public void testListVLANs() throws Exception {
assertNotNull(api.listVLANs());
@@ -429,7 +477,7 @@ public class CloudSigma2ApiLiveTest extends BaseApiLiveTest<CloudSigma2Api> {
.meta(meta)
.build();
- if (!api.listVLANs().isEmpty()) {
+ if (!api.listVLANs().concat().isEmpty()) {
checkVlAN(vlanInfo, api.editVLAN(api.listVLANs().concat().get(0).getUuid(), vlanInfo));
}
}
@@ -460,7 +508,7 @@ public class CloudSigma2ApiLiveTest extends BaseApiLiveTest<CloudSigma2Api> {
.meta(meta)
.build();
- if (!api.listIPs().isEmpty()) {
+ if (!api.listIPs().concat().isEmpty()) {
checkIP(ip, api.editIP(api.listIPs().concat().get(0).getUuid(), ip));
}
}
@@ -471,11 +519,6 @@ public class CloudSigma2ApiLiveTest extends BaseApiLiveTest<CloudSigma2Api> {
}
@Test(dependsOnMethods = {"testCreateTags"})
- public void testListTagsInfo() throws Exception {
- assertNotNull(api.listTagsInfo());
- }
-
- @Test(dependsOnMethods = {"testCreateTags"})
public void testGetTagInfo() throws Exception {
for (Tag tag : api.listTags().concat()) {
assertNotNull(api.getTagInfo(tag.getUuid()));
@@ -652,6 +695,18 @@ public class CloudSigma2ApiLiveTest extends BaseApiLiveTest<CloudSigma2Api> {
assertEquals(newDrive.getMedia(), createdDrive.getMedia());
}
+ private void checkLibraryDrive(LibraryDrive newDrive, LibraryDrive createdDrive) {
+ checkDrive(newDrive, createdDrive);
+ Map<String, String> meta = createdDrive.getMeta();
+
+ assertEquals(newDrive.getArch() == null ? "None" : newDrive.getArch(), meta.get("arch"));
+ assertEquals(newDrive.getDescription() == null ? "None" : newDrive.getDescription(), meta.get("description"));
+ assertEquals(newDrive.getImageType() == null ? "None" : newDrive.getImageType(), meta.get("image_type"));
+ assertEquals(newDrive.getInstallNotes() == null ? "None" : newDrive.getInstallNotes(), meta.get("install_notes"));
+ assertEquals(newDrive.getOs() == null ? "None" : newDrive.getOs(), meta.get("os"));
+ assertEquals(newDrive.getVersion() == null ? "None" : newDrive.getVersion(), meta.get("version"));
+ }
+
private void checkServer(ServerInfo newServer, ServerInfo createdServer) {
assertEquals(newServer.getName(), createdServer.getName());
assertEquals(newServer.getMemory(), createdServer.getMemory());
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/CloudSigma2ComputeServiceLiveTest.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/CloudSigma2ComputeServiceLiveTest.java b/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/CloudSigma2ComputeServiceLiveTest.java
new file mode 100644
index 0000000..d0b5a91
--- /dev/null
+++ b/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/CloudSigma2ComputeServiceLiveTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.cloudsigma2.compute;
+
+import com.google.inject.Module;
+import org.jclouds.compute.domain.ExecResponse;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.internal.BaseComputeServiceLiveTest;
+import org.jclouds.sshj.config.SshjSshClientModule;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "CloudSigma2ComputeServiceLiveTest")
+public class CloudSigma2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
+
+ public CloudSigma2ComputeServiceLiveTest() {
+ provider = "cloudsigma2";
+
+ }
+
+ @Override
+ protected Module getSshModule() {
+ return new SshjSshClientModule();
+ }
+
+ // CloudSigma templates require manual interaction to change the password on the first login.
+ // The only way to automatically authenticate to a server is to use an image that supports Cloud Init
+ // and provide the public key
+ @Override
+ protected Template buildTemplate(TemplateBuilder templateBuilder) {
+ Template template = super.buildTemplate(templateBuilder);
+ template.getOptions().authorizePublicKey(keyPair.get("public"));
+ return template;
+ }
+
+ @Override
+ protected void checkResponseEqualsHostname(ExecResponse execResponse, NodeMetadata node1) {
+ // CloudSigma does not return the hostname
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/config/DriveClonedPredicateTest.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/config/DriveClonedPredicateTest.java b/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/config/DriveClonedPredicateTest.java
new file mode 100644
index 0000000..acabdb3
--- /dev/null
+++ b/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/config/DriveClonedPredicateTest.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.cloudsigma2.compute.config;
+
+import org.easymock.EasyMock;
+import org.jclouds.cloudsigma2.CloudSigma2Api;
+import org.jclouds.cloudsigma2.compute.config.CloudSigma2ComputeServiceContextModule.DriveClonedPredicate;
+import org.jclouds.cloudsigma2.domain.DriveInfo;
+import org.jclouds.cloudsigma2.domain.DriveStatus;
+import org.testng.annotations.Test;
+
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * Unit tests for the drive cloned predicate
+ */
+@Test(groups = "unit", testName = "DriveClonedPredicateTest")
+public class DriveClonedPredicateTest {
+
+ public void testDriveCloned() {
+ CloudSigma2Api api = EasyMock.createMock(CloudSigma2Api.class);
+
+ for (DriveStatus status : DriveStatus.values()) {
+ expect(api.getDriveInfo(status.name())).andReturn(mockDrive(status));
+ }
+
+ replay(api);
+
+ DriveClonedPredicate predicate = new DriveClonedPredicate(api);
+
+ assertFalse(predicate.apply(mockDrive(DriveStatus.COPYING)));
+ assertFalse(predicate.apply(mockDrive(DriveStatus.UNAVAILABLE)));
+ assertTrue(predicate.apply(mockDrive(DriveStatus.MOUNTED)));
+ assertTrue(predicate.apply(mockDrive(DriveStatus.UNMOUNTED)));
+
+ verify(api);
+ }
+
+ private static DriveInfo mockDrive(DriveStatus status) {
+ return new DriveInfo.Builder().uuid(status.name()).status(status).build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/config/ServerStatusPredicatePredicateTest.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/config/ServerStatusPredicatePredicateTest.java b/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/config/ServerStatusPredicatePredicateTest.java
new file mode 100644
index 0000000..ea17420
--- /dev/null
+++ b/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/config/ServerStatusPredicatePredicateTest.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.cloudsigma2.compute.config;
+
+import org.easymock.EasyMock;
+import org.jclouds.cloudsigma2.CloudSigma2Api;
+import org.jclouds.cloudsigma2.compute.config.CloudSigma2ComputeServiceContextModule.ServerStatusPredicate;
+import org.jclouds.cloudsigma2.domain.ServerInfo;
+import org.testng.annotations.Test;
+
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.jclouds.cloudsigma2.domain.ServerStatus.STOPPED;
+import static org.jclouds.cloudsigma2.domain.ServerStatus.STOPPING;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * Unit tests for the server status predicate.
+ */
+@Test(groups = "unit", testName = "ServerStatusPredicatePredicateTest")
+public class ServerStatusPredicatePredicateTest {
+
+ public void testServerStatus() {
+ CloudSigma2Api api = EasyMock.createMock(CloudSigma2Api.class);
+
+ expect(api.getServerInfo("one")).andReturn(new ServerInfo.Builder().status(STOPPED).build());
+ expect(api.getServerInfo("two")).andReturn(new ServerInfo.Builder().status(STOPPING).build());
+
+ replay(api);
+
+ ServerStatusPredicate predicate = new ServerStatusPredicate(api, STOPPED);
+ assertTrue(predicate.apply("one"));
+ assertFalse(predicate.apply("two"));
+
+ verify(api);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a7dd1933/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/functions/LibraryDriveToImageTest.java
----------------------------------------------------------------------
diff --git a/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/functions/LibraryDriveToImageTest.java b/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/functions/LibraryDriveToImageTest.java
new file mode 100644
index 0000000..313ea61
--- /dev/null
+++ b/cloudsigma2/src/test/java/org/jclouds/cloudsigma2/compute/functions/LibraryDriveToImageTest.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.cloudsigma2.compute.functions;
+
+import com.google.common.collect.ImmutableMap;
+import org.jclouds.cloudsigma2.domain.DriveStatus;
+import org.jclouds.cloudsigma2.domain.LibraryDrive;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.ImageBuilder;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.domain.OsFamily;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import static org.jclouds.cloudsigma2.compute.config.CloudSigma2ComputeServiceContextModule.driveStatusToImageStatus;
+import static org.testng.Assert.assertEquals;
+
+@Test(groups = "unit", testName = "LibraryDriveToImageTest")
+public class LibraryDriveToImageTest {
+
+ private LibraryDrive input;
+ private Image expected;
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ input = new LibraryDrive.Builder()
+ .uuid("0bc6b02c-7ea2-4c5c-bf07-41c4cec2797d")
+ .name("Debian 7.3 Server")
+ .description("Debian 7.3 Server - amd64 Pre-Installed English with Python, SSH and VirtIO support. " +
+ "Last update 2014/02/15.")
+ .os("linux")
+ .arch("64")
+ .version("7.3")
+ .status(DriveStatus.UNMOUNTED)
+ .meta(ImmutableMap.of("test_key", "test_value",
+ "sample key", "sample value"))
+ .build();
+
+ expected = new ImageBuilder()
+ .ids("0bc6b02c-7ea2-4c5c-bf07-41c4cec2797d")
+ .userMetadata(ImmutableMap.of("test_key", "test_value",
+ "sample key", "sample value"))
+ .name("Debian 7.3 Server")
+ .description("Debian 7.3 Server - amd64 Pre-Installed English with Python, SSH and VirtIO support. " +
+ "Last update 2014/02/15.")
+ .operatingSystem(OperatingSystem.builder()
+ .name("Debian 7.3 Server")
+ .arch("64")
+ .family(OsFamily.LINUX)
+ .version("7.3")
+ .is64Bit(true)
+ .description("Debian 7.3 Server - amd64 Pre-Installed English with Python, SSH and VirtIO support. " +
+ "Last update 2014/02/15.")
+ .build())
+ .status(Image.Status.UNRECOGNIZED)
+ .build();
+ }
+
+ public void testConvertLibraryDrive() {
+ LibraryDriveToImage function = new LibraryDriveToImage(driveStatusToImageStatus);
+ Image converted = function.apply(input);
+ assertEquals(converted, expected);
+ assertEquals(converted.getUserMetadata(), expected.getUserMetadata());
+ assertEquals(converted.getName(), expected.getName());
+ assertEquals(converted.getDescription(), expected.getDescription());
+ assertEquals(converted.getStatus(), expected.getStatus());
+ assertEquals(converted.getOperatingSystem(), expected.getOperatingSystem());
+ }
+}