http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/compute/strategy/CreateResourcesThenCreateNodes.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/compute/strategy/CreateResourcesThenCreateNodes.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/compute/strategy/CreateResourcesThenCreateNodes.java new file mode 100644 index 0000000..8d302a2 --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/compute/strategy/CreateResourcesThenCreateNodes.java @@ -0,0 +1,360 @@ +/* + * 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.aliyun.ecs.compute.strategy; + +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import com.google.common.collect.Iterables; +import com.google.common.collect.Multimap; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import org.jclouds.Constants; +import org.jclouds.aliyun.ecs.ECSComputeServiceApi; +import org.jclouds.aliyun.ecs.compute.options.ECSServiceTemplateOptions; +import org.jclouds.aliyun.ecs.domain.IpProtocol; +import org.jclouds.aliyun.ecs.domain.KeyPair; +import org.jclouds.aliyun.ecs.domain.KeyPairRequest; +import org.jclouds.aliyun.ecs.domain.SecurityGroup; +import org.jclouds.aliyun.ecs.domain.SecurityGroupRequest; +import org.jclouds.aliyun.ecs.domain.Tag; +import org.jclouds.aliyun.ecs.domain.VPCRequest; +import org.jclouds.aliyun.ecs.domain.VSwitch; +import org.jclouds.aliyun.ecs.domain.VSwitchRequest; +import org.jclouds.aliyun.ecs.domain.Zone; +import org.jclouds.aliyun.ecs.domain.options.CreateSecurityGroupOptions; +import org.jclouds.aliyun.ecs.domain.options.CreateVPCOptions; +import org.jclouds.aliyun.ecs.domain.options.CreateVSwitchOptions; +import org.jclouds.aliyun.ecs.domain.options.ListVSwitchesOptions; +import org.jclouds.aliyun.ecs.domain.options.TagOptions; +import org.jclouds.compute.config.CustomizationResponse; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.functions.GroupNamingConvention; +import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; +import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap; +import org.jclouds.compute.strategy.ListNodesStrategy; +import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet; +import org.jclouds.logging.Logger; +import org.jclouds.ssh.SshKeys; + +import javax.annotation.Nullable; +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.RSAPublicKeySpec; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.collect.Iterables.get; +import static com.google.common.collect.Iterables.size; +import static org.jclouds.aliyun.ecs.domain.ResourceType.SECURITYGROUP; +import static org.jclouds.compute.util.ComputeServiceUtils.getPortRangesFromList; + +@Singleton +public class CreateResourcesThenCreateNodes extends CreateNodesWithGroupEncodedIntoNameThenAddToSet { + + public static final String INTERNET = "0.0.0.0/0"; + public static final String DEFAULT_CIDR_BLOCK = "172.16.1.0/24"; + public static final String JCLOUDS_KEYPAIR_IMPORTED = "jclouds-imported"; + public static final String PORT_RANGE_FORMAT = "%d/%d"; + protected static final String DEFAULT_DESCRIPTION_SUFFIX = "created by jclouds"; + protected static final String VSWITCH_PREFIX = "vswitch"; + protected static final String VPC_PREFIX = "vpc"; + + private final ECSComputeServiceApi api; + + @Resource + @Named(ComputeServiceConstants.COMPUTE_LOGGER) + protected Logger logger = Logger.NULL; + + @Inject + protected CreateResourcesThenCreateNodes(CreateNodeWithGroupEncodedIntoName addNodeWithGroupStrategy, + ListNodesStrategy listNodesStrategy, GroupNamingConvention.Factory namingConvention, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, + CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory, + ECSComputeServiceApi api) { + super(addNodeWithGroupStrategy, listNodesStrategy, namingConvention, userExecutor, + customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory); + this.api = api; + } + + @Override + public Map<?, ListenableFuture<Void>> execute(String group, int count, Template template, + Set<NodeMetadata> goodNodes, Map<NodeMetadata, Exception> badNodes, + Multimap<NodeMetadata, CustomizationResponse> customizationResponses) { + + String regionId = template.getLocation().getId(); + ECSServiceTemplateOptions options = template.getOptions().as(ECSServiceTemplateOptions.class); + + Optional<SecurityGroup> securityGroupOptional = tryFindSecurityGroupInRegion(regionId, options.getGroups()); + + String vpcIdFromSecurityGroup; + String vpcId; + + if (securityGroupOptional.isPresent()) { + vpcIdFromSecurityGroup = securityGroupOptional.get().vpcId(); + if (!Strings.isNullOrEmpty(options.getVSwitchId())) { + validateVSwitchId(regionId, options.getVSwitchId(), securityGroupOptional.get().name(), vpcIdFromSecurityGroup); + } else { + String message = String.format("Security group (%s) belongs to VPC (%s). Please specify a vSwitch Id of that VPC (%s) using ECSServiceTemplateOptions.vSwitchId", + securityGroupOptional.get().name(), + vpcIdFromSecurityGroup, + vpcIdFromSecurityGroup); + throw new IllegalStateException(message); + } + } else { + if (!Strings.isNullOrEmpty(options.getVSwitchId())) { + VSwitch vSwitch = tryFindVSwitch(regionId, options.getVSwitchId()); + vpcId = vSwitch.vpcId(); + } else { + vpcId = createDefaultVPC(regionId, group); + String vSwitchId = createDefaultVSwitch(regionId, vpcId, group); + options.vSwitchId(vSwitchId); + } + String createdSecurityGroupId = createSecurityGroupForOptions(group, regionId, vpcId, options); + options.securityGroups(createdSecurityGroupId); + } + + + // If keys haven't been configured, generate a key pair + if (Strings.isNullOrEmpty(options.getPublicKey()) && + Strings.isNullOrEmpty(options.getLoginPrivateKey())) { + String uniqueNameForGroup = namingConvention.create().uniqueNameForGroup(group); + KeyPairRequest keyPairRequest = generateKeyPair(regionId, uniqueNameForGroup); + options.keyPairName(keyPairRequest.getKeyPairName()); + options.overrideLoginPrivateKey(keyPairRequest.getPrivateKeyBody()); + } + + // If there is a script to run in the node, make sure a private key has + // been configured so jclouds will be able to access the node + if (options.getRunScript() != null && Strings.isNullOrEmpty(options.getLoginPrivateKey())) { + logger.warn(">> A runScript has been configured but no SSH key has been provided. Authentication will delegate to the ssh-agent"); + } + + // If there is a public key configured, then make sure there is a key pair for it + if (!Strings.isNullOrEmpty(options.getPublicKey())) { + KeyPair keyPair = getOrImportKeyPairForPublicKey(options, regionId); + options.keyPairName(keyPair.name()); + } + + Map<?, ListenableFuture<Void>> responses = super.execute(group, count, template, goodNodes, badNodes, customizationResponses); + + // Key pairs are only required to create the devices. + // Better to delete the auto-generated key pairs when they are mo more required + registerAutoGeneratedKeyPairCleanupCallbacks(responses, regionId, options.getKeyPairName()); + + return responses; + } + + private void validateVSwitchId(String regionId, + String vSwitchId, + String securityGroupName, + String vpcIdFromSecurityGroup) { + Optional<VSwitch> optionalVSwitch = tryFindVSwitchInVPC(regionId, vpcIdFromSecurityGroup, vSwitchId); + if (!optionalVSwitch.isPresent()) { + String message = String.format("security group (%s) and vSwitch (%s) must be in the same VPC_PREFIX (%s)", + securityGroupName, + optionalVSwitch.get().name(), + vpcIdFromSecurityGroup); + + throw new IllegalStateException(message); + } + } + + private String createDefaultVPC(String regionId, String group) { + String vpcName = String.format("%s-%s", VPC_PREFIX, group); + VPCRequest vpcRequest = api.vpcApi().create(regionId, CreateVPCOptions.Builder.vpcName(vpcName).description(String.format("%s - %s", VPC_PREFIX, DEFAULT_DESCRIPTION_SUFFIX))); + return vpcRequest.getVpcId(); + } + + private String createDefaultVSwitch(String regionId, String vpcId, String name) { + String vSwitchName = String.format("%s-%s", VSWITCH_PREFIX, name); + Zone zone = Iterables.getFirst(api.regionAndZoneApi().describeZones(regionId), null); + VSwitchRequest vSwitchRequest = api.vSwitchApi().create(zone.id(), DEFAULT_CIDR_BLOCK, vpcId, + CreateVSwitchOptions.Builder.vSwitchName(vSwitchName).description(String.format("%s - %s", vSwitchName, DEFAULT_DESCRIPTION_SUFFIX))); + return vSwitchRequest.getVSwitchId(); + } + + private KeyPair getOrImportKeyPairForPublicKey(ECSServiceTemplateOptions options, String regionId) { + logger.debug(">> checking if the key pair already exists..."); + PublicKey userKey = readPublicKey(options.getPublicKey()); + final String fingerprint = computeFingerprint(userKey); + KeyPair keyPair; + + synchronized (CreateResourcesThenCreateNodes.class) { + Optional<KeyPair> keyPairOptional = Iterables + .tryFind(api.sshKeyPairApi().list(regionId).concat(), new Predicate<KeyPair>() { + @Override + public boolean apply(KeyPair input) { + return input.keyPairFingerPrint().equals(fingerprint.replace(":", "")); + } + }); + if (!keyPairOptional.isPresent()) { + logger.debug(">> key pair not found. Importing a new key pair %s ...", fingerprint); + keyPair = api.sshKeyPairApi().importKeyPair( + regionId, + options.getPublicKey(), + namingConvention.create().uniqueNameForGroup(JCLOUDS_KEYPAIR_IMPORTED)); + logger.debug(">> key pair imported! %s", keyPair); + } else { + logger.debug(">> key pair found for key %s", fingerprint); + keyPair = keyPairOptional.get(); + } + return keyPair; + } + } + + private KeyPairRequest generateKeyPair(String regionId, String uniqueNameForGroup) { + logger.debug(">> creating default keypair for node..."); + KeyPairRequest keyPairRequest = api.sshKeyPairApi().create(regionId, uniqueNameForGroup); + logger.debug(">> keypair created! %s", keyPairRequest); + return keyPairRequest; + } + + private Optional<SecurityGroup> tryFindSecurityGroupInRegion(String regionId, final Set<String> securityGroups) { + checkArgument(securityGroups.size() <= 1, "Only one security group can be configured for each network interface"); + final String securityGroupId = Iterables.get(securityGroups, 0, null); + + if (securityGroupId != null) { + return api.securityGroupApi().list(regionId).concat().firstMatch(new Predicate<SecurityGroup>() { + @Override + public boolean apply(@Nullable SecurityGroup input) { + return securityGroupId.equals(input.id()); + } + }); + } + return Optional.absent(); + } + + private VSwitch tryFindVSwitch(String regionId, String vSwitchId) { + ListVSwitchesOptions listVSwitchesOptions = ListVSwitchesOptions.Builder.vSwitchId(vSwitchId); + Optional<VSwitch> optionalVSwitch = api.vSwitchApi().list(regionId, listVSwitchesOptions).first(); + if (!optionalVSwitch.isPresent()) { + String message = String.format("Cannot find a valid vSwitch with id (%s) within region (%s)", + vSwitchId, + regionId); + throw new IllegalStateException(message); + } + return optionalVSwitch.get(); + } + + private Optional<VSwitch> tryFindVSwitchInVPC(String regionId, String vpcId, String vSwitchId) { + ListVSwitchesOptions listVSwitchesOptions = ListVSwitchesOptions.Builder.vpcId(vpcId).vSwitchId(vSwitchId); + return api.vSwitchApi().list(regionId, listVSwitchesOptions).first(); + } + + private String createSecurityGroupForOptions(String group, String regionId, String vpcId, + ECSServiceTemplateOptions options) { + String name = namingConvention.create().sharedNameForGroup(group); + SecurityGroupRequest securityGroupRequest = api.securityGroupApi().create(regionId, + CreateSecurityGroupOptions.Builder + .securityGroupName(name) + .vpcId(vpcId)); + // add rules + Map<Integer, Integer> portRanges = getPortRangesFromList(options.getInboundPorts()); + for (Map.Entry<Integer, Integer> portRange : portRanges.entrySet()) { + String range = String.format(PORT_RANGE_FORMAT, portRange.getKey(), portRange.getValue()); + // TODO makes protocol and source CIDR configurable? + api.securityGroupApi().addInboundRule( + regionId, + securityGroupRequest.getSecurityGroupId(), + IpProtocol.TCP, + range, + INTERNET); + } + api.tagApi().add(regionId, securityGroupRequest.getSecurityGroupId(), SECURITYGROUP, + TagOptions.Builder + .tag(1, Tag.DEFAULT_OWNER_KEY, Tag.DEFAULT_OWNER_VALUE) + .tag(2, Tag.GROUP, group)); + return securityGroupRequest.getSecurityGroupId(); + } + + private void registerAutoGeneratedKeyPairCleanupCallbacks(Map<?, ListenableFuture<Void>> responses, + final String regionId, final String keyPairName) { + // The Futures.allAsList fails immediately if some of the futures fail. + // The Futures.successfulAsList, however, + // returns a list containing the results or 'null' for those futures that + // failed. We want to wait for all them + // (even if they fail), so better use the latter form. + ListenableFuture<List<Void>> aggregatedResponses = Futures.successfulAsList(responses.values()); + + // Key pairs must be cleaned up after all futures completed (even if some + // failed). + Futures.addCallback(aggregatedResponses, new FutureCallback<List<Void>>() { + @Override + public void onSuccess(List<Void> result) { + cleanupAutoGeneratedKeyPairs(keyPairName); + } + + @Override + public void onFailure(Throwable t) { + cleanupAutoGeneratedKeyPairs(keyPairName); + } + + private void cleanupAutoGeneratedKeyPairs(String keyPairName) { + logger.debug(">> cleaning up auto-generated key pairs..."); + try { + api.sshKeyPairApi().delete(regionId, keyPairName); + } catch (Exception ex) { + logger.warn(">> could not delete key pair %s: %s", keyPairName, ex.getMessage()); + } + } + }, userExecutor); + } + + + private static PublicKey readPublicKey(String publicKey) { + Iterable<String> parts = Splitter.on(' ').split(publicKey); + checkArgument(size(parts) >= 2, "bad format, should be: ssh-rsa AAAAB3..."); + String type = get(parts, 0); + + try { + if ("ssh-rsa".equals(type)) { + RSAPublicKeySpec spec = SshKeys.publicKeySpecFromOpenSSH(publicKey); + return KeyFactory.getInstance("RSA").generatePublic(spec); + } else { + throw new IllegalArgumentException("bad format, ssh-rsa is only supported"); + } + } catch (InvalidKeySpecException ex) { + throw new RuntimeException(ex); + } catch (NoSuchAlgorithmException ex) { + throw new RuntimeException(ex); + } + } + + private static String computeFingerprint(PublicKey key) { + if (key instanceof RSAPublicKey) { + RSAPublicKey rsaKey = (RSAPublicKey) key; + return SshKeys.fingerprint(rsaKey.getPublicExponent(), rsaKey.getModulus()); + } else { + throw new IllegalArgumentException("Only RSA keys are supported"); + } + } +}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/config/ECSComputeServiceHttpApiModule.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/config/ECSComputeServiceHttpApiModule.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/config/ECSComputeServiceHttpApiModule.java index 05ebc9f..1e84c6b 100644 --- a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/config/ECSComputeServiceHttpApiModule.java +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/config/ECSComputeServiceHttpApiModule.java @@ -16,15 +16,22 @@ */ package org.jclouds.aliyun.ecs.config; +import com.google.common.collect.ImmutableSet; +import com.google.inject.Provides; import org.jclouds.aliyun.ecs.ECSComputeServiceApi; import org.jclouds.aliyun.ecs.handlers.ECSComputeServiceErrorHandler; +import org.jclouds.aliyun.ecs.handlers.ECSErrorRetryHandler; import org.jclouds.http.HttpErrorHandler; +import org.jclouds.http.HttpRetryHandler; import org.jclouds.http.annotation.ClientError; import org.jclouds.http.annotation.Redirection; import org.jclouds.http.annotation.ServerError; import org.jclouds.rest.ConfiguresHttpApi; import org.jclouds.rest.config.HttpApiModule; +import javax.inject.Singleton; +import java.util.Set; + @ConfiguresHttpApi public class ECSComputeServiceHttpApiModule extends HttpApiModule<ECSComputeServiceApi> { @@ -35,4 +42,21 @@ public class ECSComputeServiceHttpApiModule extends HttpApiModule<ECSComputeServ bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ECSComputeServiceErrorHandler.class); } + @Override + protected void bindRetryHandlers() { + bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(ECSErrorRetryHandler.class); + } + + /** + * It combines the error codes explicitly described as retryable from ECS and VPC + * https://error-center.alibabacloud.com/status/product/Ecs?spm=a2c63.p38356.a3.5.2a9859c1Fzi5nr + * https://error-center.alibabacloud.com/status/product/Vpc?spm=a2c63.p38356.a3.1.1442dd2f4qFMSW + */ + @Provides + @ClientError + @Singleton + protected final Set<String> provideRetryableCodes() { + return ImmutableSet.of("InstanceNotReady", "IncorrectInstanceStatus.Initializing", "DependencyViolation", "IncorrectVpcStatus", "IncorrectStatus"); + } + } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/AllocatePublicIpAddressRequest.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/AllocatePublicIpAddressRequest.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/AllocatePublicIpAddressRequest.java new file mode 100644 index 0000000..8f03160 --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/AllocatePublicIpAddressRequest.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.aliyun.ecs.domain; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; + +import java.beans.ConstructorProperties; + +public class AllocatePublicIpAddressRequest extends Request { + + private final String ipAddress; + + @ConstructorProperties({ "RequestId", "IpAddress" }) + public AllocatePublicIpAddressRequest(String requestId, String ipAddress) { + super(requestId); + this.ipAddress = ipAddress; + } + + public String getInstanceId() { + return ipAddress; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + if (!super.equals(o)) + return false; + AllocatePublicIpAddressRequest that = (AllocatePublicIpAddressRequest) o; + return Objects.equal(ipAddress, that.ipAddress); + } + + @Override + public int hashCode() { + return Objects.hashCode(super.hashCode(), ipAddress); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("ipAddress", ipAddress).toString(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/AvailableResource.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/AvailableResource.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/AvailableResource.java new file mode 100644 index 0000000..338663c --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/AvailableResource.java @@ -0,0 +1,43 @@ +/* + * 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.aliyun.ecs.domain; + +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableMap; +import org.jclouds.json.SerializedNames; + +import java.util.List; +import java.util.Map; + +@AutoValue +public abstract class AvailableResource { + + AvailableResource() { + } + + @SerializedNames({ "Type", "SupportedResources" }) + public static AvailableResource create(String type, Map<String, List<SupportedResource>> supportedResources) { + return new AutoValue_AvailableResource(type, supportedResources == null ? + ImmutableMap.<String, List<SupportedResource>>of() : + ImmutableMap.copyOf(supportedResources)); + } + + public abstract String type(); + + public abstract Map<String, List<SupportedResource>> supportedResources(); + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/AvailableZone.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/AvailableZone.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/AvailableZone.java new file mode 100644 index 0000000..08e65b3 --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/AvailableZone.java @@ -0,0 +1,47 @@ +/* + * 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.aliyun.ecs.domain; + +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableMap; +import org.jclouds.json.SerializedNames; + +import java.util.List; +import java.util.Map; + +@AutoValue +public abstract class AvailableZone { + + AvailableZone() { + } + + @SerializedNames({ "Status", "RegionId", "AvailableResources", "ZoneId" }) + public static AvailableZone create(String status, String regionId, + Map<String, List<AvailableResource>> availableResources, String zoneId) { + return new AutoValue_AvailableZone(status, regionId, availableResources == null ? + ImmutableMap.<String, List<AvailableResource>>of() : + ImmutableMap.copyOf(availableResources), zoneId); + } + + public abstract String status(); + + public abstract String regionId(); + + public abstract Map<String, List<AvailableResource>> availableResources(); + + public abstract String zoneId(); +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/DedicatedHostAttribute.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/DedicatedHostAttribute.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/DedicatedHostAttribute.java new file mode 100644 index 0000000..dff8e3f --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/DedicatedHostAttribute.java @@ -0,0 +1,37 @@ +/* + * 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.aliyun.ecs.domain; + +import com.google.auto.value.AutoValue; +import org.jclouds.json.SerializedNames; + +@AutoValue +public abstract class DedicatedHostAttribute { + + DedicatedHostAttribute() { + } + + @SerializedNames({ "DedicatedHostId", "DedicatedHostName" }) + public static DedicatedHostAttribute create(String id, String name) { + return new AutoValue_DedicatedHostAttribute(id, name); + } + + public abstract String id(); + + public abstract String name(); + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/EipAddress.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/EipAddress.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/EipAddress.java new file mode 100644 index 0000000..10c158d --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/EipAddress.java @@ -0,0 +1,67 @@ +/* + * 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.aliyun.ecs.domain; + +import com.google.auto.value.AutoValue; +import com.google.common.base.CaseFormat; +import com.google.common.base.Enums; +import org.jclouds.json.SerializedNames; + +@AutoValue +public abstract class EipAddress { + + public enum InternetChargeType { + ECS_INSTANCE("EcsInstance"), + SLB_INSTANCE ("SlbInstance"), + NAT ("Nat"), + HA_VIP("HaVip"), + DEFAULT(""); + + private final String internetChargeType; + + InternetChargeType(String internetChargeType) { + this.internetChargeType = internetChargeType; + } + + public static InternetChargeType fromValue(String value) { + return Enums.getIfPresent(InternetChargeType.class, CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, value)).or(InternetChargeType.DEFAULT); + } + + public String internetChargeType() { + return internetChargeType; + } + + @Override + public String toString() { + return internetChargeType(); + } + } + + EipAddress() {} + + @SerializedNames({ "IpAddress", "AllocationId", "InternetChargeType" }) + public static EipAddress create(String ipAddress, String allocationId, InternetChargeType internetChargeType) { + return new AutoValue_EipAddress(ipAddress, allocationId, internetChargeType); + } + + public abstract String ipAddress(); + + public abstract String allocationId(); + + public abstract InternetChargeType internetChargeType(); + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/ErrorMessage.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/ErrorMessage.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/ErrorMessage.java new file mode 100644 index 0000000..aa3f684 --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/ErrorMessage.java @@ -0,0 +1,39 @@ +/* + * 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.aliyun.ecs.domain; + +import com.google.auto.value.AutoValue; +import org.jclouds.json.SerializedNames; + +@AutoValue +public abstract class ErrorMessage { + + ErrorMessage() {} + + @SerializedNames({ "RequestId", "HostId", "Code", "Message" }) + public static ErrorMessage create(String requestId, String hostId, String code, String message) { + return new AutoValue_ErrorMessage(requestId, hostId, code, message); + } + + public abstract String requestId(); + + public abstract String hostId(); + + public abstract String code(); + + public abstract String message(); +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Image.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Image.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Image.java index 328d6fe..1aee2c1 100644 --- a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Image.java +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Image.java @@ -17,6 +17,10 @@ package org.jclouds.aliyun.ecs.domain; import com.google.auto.value.AutoValue; +import com.google.common.base.CaseFormat; +import com.google.common.base.Enums; +import com.google.common.base.Joiner; +import com.google.common.base.Optional; import com.google.common.collect.ImmutableMap; import org.jclouds.json.SerializedNames; @@ -24,9 +28,31 @@ import java.util.Date; import java.util.List; import java.util.Map; +import static com.google.common.base.Preconditions.checkArgument; + @AutoValue public abstract class Image { + public enum Status { + AVAILABLE, UNAVAILABLE; + + + public static Status fromValue(String value) { + Optional<Status> status = Enums.getIfPresent(Status.class, value.toUpperCase()); + checkArgument(status.isPresent(), "Expected one of %s but was %s", Joiner.on(',').join(Status.values()), value); + return status.get(); + } + + public String value() { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name()); + } + + @Override + public String toString() { + return value(); + } + } + Image() {} @SerializedNames({"ImageId", "Description", "ProductCode", "OSType", "Architecture", "OSName", "DiskDeviceMappings", @@ -36,15 +62,15 @@ public abstract class Image { public static Image create(String id, String description, String productCode, String osType, String architecture, String osName, Map<String, List<DiskDeviceMapping>> diskDeviceMappings, String imageOwnerAlias, String progress, Boolean isSupportCloudinit, String usage, Date creationTime, - Map<String, List<Tag>> tags, String imageVersion, String status, String name, + Map<String, List<Tag>> tags, String imageVersion, Status status, String name, Boolean isSupportIoOptimized, Boolean isSelfShared, Boolean isCopied, Boolean isSubscribed, String platform, - String size) { - return new AutoValue_Image(id, description, productCode, osType, architecture, osName, - diskDeviceMappings == null ? - ImmutableMap.<String, List<DiskDeviceMapping>>of() : - ImmutableMap.copyOf(diskDeviceMappings), imageOwnerAlias, progress, isSupportCloudinit, usage, - creationTime, tags == null ? ImmutableMap.<String, List<Tag>>of() : ImmutableMap.copyOf(tags), imageVersion, - status, name, isSupportIoOptimized, isSelfShared, isCopied, isSubscribed, platform, size); + int size) { + return builder().id(id).description(description).productCode(productCode).osType(osType) + .architecture(architecture).osName(osName).diskDeviceMappings(diskDeviceMappings).imageOwnerAlias(imageOwnerAlias) + .progress(progress).isSupportCloudinit(isSupportCloudinit).usage(usage).creationTime(creationTime) + .tags(tags).imageVersion(imageVersion).status(status).name(name).isSupportIoOptimizeds(isSupportIoOptimized) + .isSelfShared(isSelfShared).isCopied(isCopied).isSubscribed(isSubscribed).platform(platform).size(size) + .build(); } public abstract String id(); @@ -75,7 +101,7 @@ public abstract class Image { public abstract String imageVersion(); - public abstract String status(); + public abstract Status status(); public abstract String name(); @@ -89,6 +115,72 @@ public abstract class Image { public abstract String platform(); - public abstract String size(); + public abstract int size(); + + public abstract Builder toBuilder(); + + public static Builder builder() { + return new AutoValue_Image.Builder(); + } + + @AutoValue.Builder + public abstract static class Builder { + + public abstract Builder id(String id); + + public abstract Builder description(String description); + + public abstract Builder productCode(String productCode); + + public abstract Builder osType(String osType); + + public abstract Builder architecture(String architecture); + + public abstract Builder osName(String osName); + + public abstract Builder diskDeviceMappings(Map<String, List<DiskDeviceMapping>> diskDeviceMappings); + + public abstract Builder imageOwnerAlias(String imageOwnerAlias); + + public abstract Builder progress(String progress); + + public abstract Builder isSupportCloudinit(Boolean isSupportCloudinit); + + public abstract Builder usage(String usage); + + public abstract Builder creationTime(Date creationTime); + + public abstract Builder tags(Map<String, List<Tag>> tags); + + public abstract Builder imageVersion(String imageVersion); + + public abstract Builder status(Status status); + + public abstract Builder name(String name); + + public abstract Builder isSupportIoOptimizeds(Boolean isSupportIoOptimizeds); + + public abstract Builder isSelfShared(Boolean isSelfShared); + + public abstract Builder isCopied(Boolean isCopied); + + public abstract Builder isSubscribed(Boolean isSubscribed); + + public abstract Builder platform(String platform); + + public abstract Builder size(int size); + + abstract Image autoBuild(); + + abstract Map<String, List<DiskDeviceMapping>> diskDeviceMappings(); + + abstract Map<String, List<Tag>> tags(); + + public Image build() { + diskDeviceMappings(diskDeviceMappings() != null ? ImmutableMap.copyOf(diskDeviceMappings()) : ImmutableMap.<String, List<DiskDeviceMapping>>of()); + tags(tags() != null ? ImmutableMap.copyOf(tags()) : ImmutableMap.<String, List<Tag>>of()); + return autoBuild(); + } + } } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Instance.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Instance.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Instance.java new file mode 100644 index 0000000..ddf2036 --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Instance.java @@ -0,0 +1,321 @@ +/* + * 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.aliyun.ecs.domain; + +import com.google.auto.value.AutoValue; +import com.google.common.base.CaseFormat; +import com.google.common.base.Enums; +import com.google.common.base.Joiner; +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableMap; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.json.SerializedNames; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +import static com.google.common.base.Preconditions.checkArgument; + +@AutoValue +public abstract class Instance { + + public enum InternetChargeType { + PAY_BY_TRAFFIC("PayByTraffic"), + DEFAULT(""); + + private final String internetChargeType; + + InternetChargeType(String internetChargeType) { + this.internetChargeType = internetChargeType; + } + + public static InternetChargeType fromValue(String value) { + return Enums.getIfPresent(InternetChargeType.class, CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, value)).or(InternetChargeType.DEFAULT); + } + + public String internetChargeType() { + return internetChargeType; + } + + @Override + public String toString() { + return internetChargeType(); + } + } + + + public enum Status { + STARTING, RUNNING, STOPPING, STOPPED; + + public static Status fromValue(String value) { + Optional<Status> status = Enums.getIfPresent(Status.class, value.toUpperCase()); + checkArgument(status.isPresent(), "Expected one of %s but was %s", Joiner.on(',').join(Status.values()), + value); + return status.get(); + } + } + + Instance() {} + + @SerializedNames( + { "InnerIpAddress", "ImageId", "InstanceTypeFamily", "VlanId", "NetworkInterfaces", "InstanceId", "EipAddress", + "InternetMaxBandwidthIn", "ZoneId", "InternetChargeType", "SpotStrategy", "StoppedMode", "SerialNumber", + "IoOptimized", "Memory", "Cpu", "VpcAttributes", "InternetMaxBandwidthOut", "DeviceAvailable", + "SecurityGroupIds", "SaleCycle", "SpotPriceLimit", "AutoReleaseTime", "StartTime", "InstanceName", + "Description", "ResourceGroupId", "OSType", "OSName", "InstanceNetworkType", "PublicIpAddress", + "HostName", "InstanceType", "CreationTime", "Status", "Tags", "ClusterId", "Recyclable", "RegionId", + "GPUSpec", "DedicatedHostAttribute", "OperationLocks", "InstanceChargeType", "GPUAmount", + "ExpiredTime" }) + public static Instance create(Map<String, List<String>> innerIpAddress, String imageId, String instanceTypeFamily, + String vlanId, Map<String, List<NetworkInterface>> networkInterfaces, String id, EipAddress eipAddress, + Integer internetMaxBandwidthIn, String zoneId, InternetChargeType internetChargeType, String spotStrategy, + String stoppedMode, String serialNumber, Boolean ioOptimized, Integer memory, Integer cpu, + VpcAttributes vpcAttributes, Integer internetMaxBandwidthOut, Boolean deviceAvailable, + Map<String, List<String>> securityGroupIds, String saleCycle, Double spotPriceLimit, String autoReleaseTime, + Date startTime, String name, String description, String resourceGroupId, String osType, String osName, + String instanceNetworkType, Map<String, List<String>> publicIpAddress, String hostname, String instanceType, + Date creationTime, Status status, Map<String, List<Tag>> tags, String clusterId, Boolean recyclable, + String regionId, String gpuSpec, DedicatedHostAttribute dedicatedHostAttribute, + Map<String, List<String>> operationLocks, String instanceChargeType, Integer gpuAmount, Date expiredTime) { + return builder().innerIpAddress(innerIpAddress).imageId(imageId).instanceTypeFamily(instanceTypeFamily).vlanId(vlanId) + .networkInterfaces(networkInterfaces).id(id).eipAddress(eipAddress).internetMaxBandwidthIn(internetMaxBandwidthIn) + .zoneId(zoneId).internetChargeType(internetChargeType).spotStrategy(spotStrategy).stoppedMode(stoppedMode).serialNumber(serialNumber) + .ioOptimized(ioOptimized).memory(memory).cpu(cpu).vpcAttributes(vpcAttributes).internetMaxBandwidthOut(internetMaxBandwidthOut).deviceAvailable(deviceAvailable) + .securityGroupIds(securityGroupIds).saleCycle(saleCycle).spotPriceLimit(spotPriceLimit).autoReleaseTime(autoReleaseTime).startTime(startTime).name(name) + .description(description).resourceGroupId(resourceGroupId).osType(osType).osName(osName).instanceNetworkType(instanceNetworkType).publicIpAddress(publicIpAddress) + .hostname(hostname).instanceType(instanceType).creationTime(creationTime).status(status).tags(tags).clusterId(clusterId).recyclable(recyclable).regionId(regionId) + .gpuSpec(gpuSpec).dedicatedHostAttribute(dedicatedHostAttribute).operationLocks(operationLocks).instanceChargeType(instanceChargeType).gpuAmount(gpuAmount) + .expiredTime(expiredTime).build(); + } + + public abstract Map<String, List<String>> innerIpAddress(); + + public abstract String imageId(); + + public abstract String instanceTypeFamily(); + + public abstract String vlanId(); + + public abstract Map<String, List<NetworkInterface>> networkInterfaces(); + + public abstract String id(); + + public abstract EipAddress eipAddress(); + + public abstract Integer internetMaxBandwidthIn(); + + public abstract String zoneId(); + + public abstract InternetChargeType internetChargeType(); + + public abstract String spotStrategy(); + + public abstract String stoppedMode(); + + public abstract String serialNumber(); + + public abstract Boolean ioOptimized(); + + public abstract Integer memory(); + + public abstract Integer cpu(); + + public abstract VpcAttributes vpcAttributes(); + + public abstract Integer internetMaxBandwidthOut(); + + public abstract Boolean deviceAvailable(); + + public abstract Map<String, List<String>> securityGroupIds(); + + public abstract String saleCycle(); + + public abstract Double spotPriceLimit(); + + public abstract String autoReleaseTime(); + + public abstract Date startTime(); + + public abstract String name(); + + public abstract String description(); + + public abstract String resourceGroupId(); + + public abstract String osType(); + + public abstract String osName(); + + public abstract String instanceNetworkType(); + + public abstract Map<String, List<String>> publicIpAddress(); + + public abstract String hostname(); + + public abstract String instanceType(); + + public abstract Date creationTime(); + + public abstract Status status(); + + @Nullable + public abstract Map<String, List<Tag>> tags(); + + public abstract String clusterId(); + + public abstract Boolean recyclable(); + + public abstract String regionId(); + + public abstract String gpuSpec(); + + public abstract DedicatedHostAttribute dedicatedHostAttribute(); + + public abstract Map<String, List<String>> operationLocks(); + + public abstract String instanceChargeType(); + + public abstract Integer gpuAmount(); + + public abstract Date expiredTime(); + + public abstract Builder toBuilder(); + + public static Builder builder() { + return new AutoValue_Instance.Builder(); + } + + @AutoValue.Builder + public abstract static class Builder { + + public abstract Builder innerIpAddress(Map<String, List<String>> innerIpAddress); + + public abstract Builder imageId(String imageId); + + public abstract Builder instanceTypeFamily(String instanceTypeFamily); + + public abstract Builder vlanId(String vlanId); + + public abstract Builder networkInterfaces(Map<String, List<NetworkInterface>> networkInterfaces); + + public abstract Builder id(String id); + + public abstract Builder eipAddress(EipAddress eipAddress); + + public abstract Builder internetMaxBandwidthIn(Integer internetMaxBandwidthIn); + + public abstract Builder zoneId(String zoneId); + + public abstract Builder internetChargeType(InternetChargeType internetChargeType); + + public abstract Builder spotStrategy(String spotStrategy); + + public abstract Builder stoppedMode(String stoppedMode); + + public abstract Builder serialNumber(String serialNumber); + + public abstract Builder ioOptimized(Boolean ioOptimized); + + public abstract Builder memory(Integer memory); + + public abstract Builder cpu(Integer cpu); + + public abstract Builder vpcAttributes(VpcAttributes vpcAttributes); + + public abstract Builder internetMaxBandwidthOut(Integer internetMaxBandwidthOut); + + public abstract Builder deviceAvailable(Boolean deviceAvailable); + + public abstract Builder securityGroupIds(Map<String, List<String>> securityGroupIds); + + public abstract Builder saleCycle(String saleCycle); + + public abstract Builder spotPriceLimit(Double spotPriceLimit); + + public abstract Builder autoReleaseTime(String autoReleaseTime); + + public abstract Builder startTime(Date startTime); + + public abstract Builder name(String name); + + public abstract Builder description(String description); + + public abstract Builder resourceGroupId(String resourceGroupId); + + public abstract Builder osType(String osType); + + public abstract Builder osName(String osName); + + public abstract Builder instanceNetworkType(String instanceNetworkType); + + public abstract Builder publicIpAddress(Map<String, List<String>> publicIpAddress); + + public abstract Builder hostname(String hostname); + + public abstract Builder instanceType(String instanceType); + + public abstract Builder creationTime(Date creationTime); + + public abstract Builder status(Status status); + + public abstract Builder tags(Map<String, List<Tag>> tags); + + public abstract Builder clusterId(String clusterId); + + public abstract Builder recyclable(Boolean recyclable); + + public abstract Builder regionId(String regionId); + + public abstract Builder gpuSpec(String gpuSpec); + + public abstract Builder dedicatedHostAttribute(DedicatedHostAttribute dedicatedHostAttribute); + + public abstract Builder operationLocks(Map<String, List<String>> operationLocks); + + public abstract Builder instanceChargeType(String InstanceChargeType); + + public abstract Builder gpuAmount(Integer gpuAmount); + + public abstract Builder expiredTime(Date expiredTime); + + abstract Instance autoBuild(); + + abstract Map<String, List<String>> innerIpAddress(); + + abstract Map<String, List<NetworkInterface>> networkInterfaces(); + + abstract Map<String, List<String>> securityGroupIds(); + + abstract Map<String, List<String>> publicIpAddress(); + + abstract Map<String, List<String>> operationLocks(); + + abstract Map<String, List<Tag>> tags(); + + public Instance build() { + innerIpAddress(innerIpAddress() == null ? ImmutableMap.<String, List<String>>of() : ImmutableMap.copyOf(innerIpAddress())); + securityGroupIds(securityGroupIds() == null ? ImmutableMap.<String, List<String>>of() : ImmutableMap.copyOf(securityGroupIds())); + networkInterfaces(networkInterfaces() == null ? ImmutableMap.<String, List<NetworkInterface>>of() : ImmutableMap.copyOf(networkInterfaces())); + publicIpAddress(publicIpAddress() == null ? ImmutableMap.<String, List<String>>of() : ImmutableMap.copyOf(publicIpAddress())); + operationLocks(operationLocks() == null ? ImmutableMap.<String, List<String>>of() : ImmutableMap.copyOf(operationLocks())); + tags(tags() != null ? ImmutableMap.copyOf(tags()) : ImmutableMap.<String, List<Tag>>of()); + return autoBuild(); + } + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/InstanceRequest.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/InstanceRequest.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/InstanceRequest.java new file mode 100644 index 0000000..ca615d0 --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/InstanceRequest.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.aliyun.ecs.domain; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; + +import java.beans.ConstructorProperties; + +public class InstanceRequest extends Request { + + private final String instanceId; + + @ConstructorProperties({ "RequestId", "InstanceId" }) + public InstanceRequest(String requestId, String instanceId) { + super(requestId); + this.instanceId = instanceId; + } + + public String getInstanceId() { + return instanceId; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + if (!super.equals(o)) + return false; + InstanceRequest that = (InstanceRequest) o; + return Objects.equal(instanceId, that.instanceId); + } + + @Override + public int hashCode() { + return Objects.hashCode(super.hashCode(), instanceId); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("instanceId", instanceId).toString(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/InstanceStatus.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/InstanceStatus.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/InstanceStatus.java new file mode 100644 index 0000000..4ee6777 --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/InstanceStatus.java @@ -0,0 +1,55 @@ +/* + * 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.aliyun.ecs.domain; + +import com.google.auto.value.AutoValue; +import com.google.common.base.Enums; +import com.google.common.base.Joiner; +import com.google.common.base.Optional; +import org.jclouds.json.SerializedNames; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * https://www.alibabacloud.com/help/doc-detail/25687.htm?spm=a2c63.p38356.a3.3.25a15566k0U5A4 + */ +@AutoValue +public abstract class InstanceStatus { + + InstanceStatus() { + } + + @SerializedNames({ "InstanceId", "Status" }) + public static InstanceStatus create(String instanceId, Status status) { + return new AutoValue_InstanceStatus(instanceId, status); + } + + public abstract String instanceId(); + + public abstract Status status(); + + public enum Status { + PENDING, STARTING, RUNNING, STOPPING, STOPPED; + + public static InstanceStatus.Status fromValue(String value) { + Optional<Status> status = Enums.getIfPresent(InstanceStatus.Status.class, value.toUpperCase()); + checkArgument(status.isPresent(), "Expected one of %s but was %s", + Joiner.on(',').join(InstanceStatus.Status.values()), value); + return status.get(); + } + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/InstanceType.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/InstanceType.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/InstanceType.java new file mode 100644 index 0000000..1802084 --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/InstanceType.java @@ -0,0 +1,85 @@ +/* + * 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.aliyun.ecs.domain; + +import com.google.auto.value.AutoValue; +import org.jclouds.json.SerializedNames; + +@AutoValue +public abstract class InstanceType { + + InstanceType() { + } + + @SerializedNames( + {"InstanceTypeId", "InstanceTypeFamily", "EniQuantity", + "GPUSpec", "CpuCoreCount", "MemorySize", "GPUAmount", "LocalStorageCategory" }) + public static InstanceType create(String id, String instanceTypeFamily, Integer eniQuantity, + String gpuSpec, Integer cpuCoreCount, Double memorySize, Double gpuAmount, String localStorageCategory) { + return builder() + .id(id).instanceTypeFamily(instanceTypeFamily).eniQuantity(eniQuantity) + .gpuSpec(gpuSpec).cpuCoreCount(cpuCoreCount).memorySize(memorySize) + .gpuAmount(gpuAmount).localStorageCategory(localStorageCategory) + .build(); + } + + public abstract String id(); + + public abstract Integer cpuCoreCount(); + + public abstract String instanceTypeFamily(); + + public abstract Integer eniQuantity(); + + public abstract String gpuSpec(); + + public abstract Double memorySize(); + + public abstract Double gpuAmount(); + + public abstract String localStorageCategory(); + + public abstract Builder toBuilder(); + + public static Builder builder() { + return new AutoValue_InstanceType.Builder(); + } + + @AutoValue.Builder + public abstract static class Builder { + + public abstract Builder id(String id); + + public abstract Builder cpuCoreCount(Integer cpuCoreCount); + + public abstract Builder instanceTypeFamily(String instanceTypeFamily); + + public abstract Builder eniQuantity(Integer eniQuantity); + + public abstract Builder gpuSpec(String gpuSpec); + + public abstract Builder memorySize(Double memorySize); + + public abstract Builder gpuAmount(Double gpuAmount); + + public abstract Builder localStorageCategory(String localStorageCategory); + + public abstract InstanceType build(); + + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/NetworkInterface.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/NetworkInterface.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/NetworkInterface.java new file mode 100644 index 0000000..6a3b6e9 --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/NetworkInterface.java @@ -0,0 +1,41 @@ +/* + * 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.aliyun.ecs.domain; + +import com.google.auto.value.AutoValue; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.json.SerializedNames; + +@AutoValue +public abstract class NetworkInterface { + + NetworkInterface() { + } + + @SerializedNames({ "MacAddress", "PrimaryIpAddress", "NetworkInterfaceId" }) + public static NetworkInterface create(String macAddress, String primaryIpAddress, String id) { + return new AutoValue_NetworkInterface(macAddress, primaryIpAddress, id); + } + + @Nullable + public abstract String macAddress(); + + public abstract String primaryIpAddress(); + + public abstract String id(); + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Permission.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Permission.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Permission.java index 003ccf1..bda9cb5 100644 --- a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Permission.java +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Permission.java @@ -50,7 +50,7 @@ public abstract class Permission { } public enum Direction { - EGRESS, ALL; + EGRESS, INGRESS, ALL; public static Direction fromValue(String value) { Optional<Direction> direction = Enums.getIfPresent(Direction.class, value.toUpperCase()); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/ResourceType.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/ResourceType.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/ResourceType.java new file mode 100644 index 0000000..9807d83 --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/ResourceType.java @@ -0,0 +1,42 @@ +/* + * 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.aliyun.ecs.domain; + +import com.google.common.base.Enums; +import com.google.common.base.Joiner; +import com.google.common.base.Optional; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * The type of the ECS resource. All values must be lowercase. + */ +public enum ResourceType { + DISK, INSTANCE, IMAGE, SECURITYGROUP, SNAPSHOT; + + public static ResourceType fromValue(String value) { + Optional<ResourceType> resourceType = Enums.getIfPresent(ResourceType.class, value.toUpperCase()); + checkArgument(resourceType.isPresent(), "Expected one of %s but was %s", Joiner.on(',').join(ResourceType.values()), value); + return resourceType.get(); + } + + @Override + public String toString() { + return name().toLowerCase(); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/SecurityGroup.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/SecurityGroup.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/SecurityGroup.java index 3fd0658..8709948 100644 --- a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/SecurityGroup.java +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/SecurityGroup.java @@ -17,18 +17,24 @@ package org.jclouds.aliyun.ecs.domain; import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableMap; import org.jclouds.json.SerializedNames; +import java.util.List; +import java.util.Map; + @AutoValue public abstract class SecurityGroup { SecurityGroup() { } - @SerializedNames({ "SecurityGroupId", "Description", "SecurityGroupName", "VpcId" }) + @SerializedNames({ "SecurityGroupId", "Description", "SecurityGroupName", "VpcId", "Tags" }) public static SecurityGroup create(String id, String description, String name, - String vpcId) { - return new AutoValue_SecurityGroup(id, description, name, vpcId); + String vpcId, Map<String, List<Tag>> tags) { + return new AutoValue_SecurityGroup(id, description, name, vpcId, tags == null ? + ImmutableMap.<String, List<Tag>>of() : + ImmutableMap.copyOf(tags)); } public abstract String id(); @@ -39,4 +45,6 @@ public abstract class SecurityGroup { public abstract String vpcId(); + public abstract Map<String, List<Tag>> tags(); + } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/SupportedResource.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/SupportedResource.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/SupportedResource.java new file mode 100644 index 0000000..3547004 --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/SupportedResource.java @@ -0,0 +1,52 @@ +/* + * 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.aliyun.ecs.domain; + +import com.google.auto.value.AutoValue; +import com.google.common.base.Enums; +import com.google.common.base.Joiner; +import com.google.common.base.Optional; +import org.jclouds.json.SerializedNames; + +import static com.google.common.base.Preconditions.checkArgument; + +@AutoValue +public abstract class SupportedResource { + + public enum Status { + AVAILABLE, SOLDOUT; + + public static Status fromValue(String value) { + Optional<Status> status = Enums.getIfPresent(Status.class, value.toUpperCase()); + checkArgument(status.isPresent(), "Expected one of %s but was %s", Joiner.on(',').join(Status.values()), value); + return status.get(); + } + } + + SupportedResource() { + } + + @SerializedNames({ "Status", "Value" }) + public static SupportedResource create(Status status, String value) { + return new AutoValue_SupportedResource(status, value); + } + + public abstract Status status(); + + public abstract String value(); + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Tag.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Tag.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Tag.java index 1b34226..33bc688 100644 --- a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Tag.java +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Tag.java @@ -17,19 +17,25 @@ package org.jclouds.aliyun.ecs.domain; import com.google.auto.value.AutoValue; +import org.jclouds.javax.annotation.Nullable; import org.jclouds.json.SerializedNames; @AutoValue public abstract class Tag { + public static final String DEFAULT_OWNER_KEY = "owner"; + public static final String DEFAULT_OWNER_VALUE = "jclouds"; + public static final String GROUP = "group"; + Tag() {} @SerializedNames({ "TagKey", "TagValue" }) - public static Tag create(String tagKey, String tagValue) { - return new AutoValue_Tag(tagKey, tagValue); + public static Tag create(String key, String value) { + return new AutoValue_Tag(key, value); } - public abstract String tagKey(); + public abstract String key(); - public abstract String tagValue(); + @Nullable + public abstract String value(); } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/UserCidr.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/UserCidr.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/UserCidr.java new file mode 100644 index 0000000..ff91eae --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/UserCidr.java @@ -0,0 +1,27 @@ +/* + * 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.aliyun.ecs.domain; + +import com.google.auto.value.AutoValue; + +// FIXME not possible to find properties from either the API or the doc +@AutoValue +public abstract class UserCidr { + + UserCidr() {} + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/VPC.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/VPC.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/VPC.java new file mode 100644 index 0000000..a1ed1d6 --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/VPC.java @@ -0,0 +1,131 @@ +/* + * 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.aliyun.ecs.domain; + +import com.google.auto.value.AutoValue; +import com.google.common.base.CaseFormat; +import com.google.common.base.Enums; +import com.google.common.base.Joiner; +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableMap; +import org.jclouds.json.SerializedNames; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +import static com.google.common.base.Preconditions.checkArgument; + +@AutoValue +public abstract class VPC { + + public enum Status { + AVAILABLE, UNAVAILABLE, PENDING; + + public static Status fromValue(String value) { + Optional<Status> status = Enums.getIfPresent(Status.class, value.toUpperCase()); + checkArgument(status.isPresent(), "Expected one of %s but was %s", Joiner.on(',').join(Status.values()), value); + return status.get(); + } + + public String value() { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name()); + } + + @Override + public String toString() { + return value(); + } + } + + VPC() {} + + @SerializedNames({"CidrBlock", "CreationTime", "Description", "RegionId", "Status", + "UserCidrs", "VRouterId", "VSwitchIds", "VpcId", "VpcName" }) + public static VPC create(String cidrBlock, Date creationTime, String description, String regionId, Status status, + Map<String, List<UserCidr>> userCidrs, + String vRouterId, + Map<String, List<String>> vSwitchIds, + String id, String name) { + return builder().cidrBlock(cidrBlock).creationTime(creationTime).description(description).regionId(regionId) + .status(status).userCidrs(userCidrs).vRouterId(vRouterId).vSwitchIds(vSwitchIds) + .id(id).name(name).build(); + } + + public abstract String cidrBlock(); + + public abstract Date creationTime(); + + public abstract String description(); + + public abstract String regionId(); + + public abstract Status status(); + + public abstract Map<String, List<UserCidr>> userCidrs(); + + public abstract String vRouterId(); + + public abstract Map<String, List<String>> vSwitchIds(); + + public abstract String id(); + + public abstract String name(); + + public abstract VPC.Builder toBuilder(); + + public static VPC.Builder builder() { + return new AutoValue_VPC.Builder(); + } + + @AutoValue.Builder + public abstract static class Builder { + + public abstract Builder cidrBlock(String cidrBlock); + + public abstract Builder creationTime(Date creationTime); + + public abstract Builder description(String description); + + public abstract Builder regionId(String regionId); + + public abstract Builder status(Status status); + + public abstract Builder userCidrs(Map<String, List<UserCidr>> userCidrs); + + public abstract Builder vRouterId(String vRouterId); + + public abstract Builder vSwitchIds(Map<String, List<String>> vSwitchIds); + + public abstract Builder id(String id); + + public abstract Builder name(String name); + + abstract VPC autoBuild(); + + abstract Map<String, List<UserCidr>> userCidrs(); + + abstract Map<String, List<String>> vSwitchIds(); + + public VPC build() { + userCidrs(userCidrs() == null ? ImmutableMap.<String, List<UserCidr>>of() : ImmutableMap.copyOf(userCidrs())); + vSwitchIds(vSwitchIds() == null ? ImmutableMap.<String, List<String>>of() : ImmutableMap.copyOf(vSwitchIds())); + return autoBuild(); + } + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/VPCRequest.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/VPCRequest.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/VPCRequest.java new file mode 100644 index 0000000..868c550 --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/VPCRequest.java @@ -0,0 +1,74 @@ +/* + * 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.aliyun.ecs.domain; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; + +import java.beans.ConstructorProperties; + +public class VPCRequest extends Request { + + private final String routeTableId; + private final String vRouterId; + private final String vpcId; + + @ConstructorProperties({ "RequestId", "RouteTableId", "VRouterId", "VpcId" }) + public VPCRequest(String requestId, String routeTableId, String vRouterId, String vpcId) { + super(requestId); + this.routeTableId = routeTableId; + this.vRouterId = vRouterId; + this.vpcId = vpcId; + } + + public String getRouteTableId() { + return routeTableId; + } + + public String getvRouterId() { + return vRouterId; + } + + public String getVpcId() { + return vpcId; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + VPCRequest that = (VPCRequest) o; + return Objects.equal(routeTableId, that.routeTableId) && + Objects.equal(vRouterId, that.vRouterId) && + Objects.equal(vpcId, that.vpcId); + } + + @Override + public int hashCode() { + return Objects.hashCode(super.hashCode(), routeTableId, vRouterId, vpcId); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("routeTableId", routeTableId) + .add("vRouterId", vRouterId) + .add("vpcId", vpcId) + .toString(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2c7db7e8/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/VSwitch.java ---------------------------------------------------------------------- diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/VSwitch.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/VSwitch.java new file mode 100644 index 0000000..9f73e30 --- /dev/null +++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/VSwitch.java @@ -0,0 +1,112 @@ +/* + * 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.aliyun.ecs.domain; + +import com.google.auto.value.AutoValue; +import com.google.common.base.CaseFormat; +import com.google.common.base.Enums; +import com.google.common.base.Joiner; +import com.google.common.base.Optional; +import org.jclouds.json.SerializedNames; + +import java.util.Date; + +import static com.google.common.base.Preconditions.checkArgument; + +@AutoValue +public abstract class VSwitch { + + public enum Status { + AVAILABLE, UNAVAILABLE, PENDING; + + public static Status fromValue(String value) { + Optional<Status> status = Enums.getIfPresent(Status.class, value.toUpperCase()); + checkArgument(status.isPresent(), "Expected one of %s but was %s", Joiner.on(',').join(Status.values()), value); + return status.get(); + } + + public String value() { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name()); + } + + @Override + public String toString() { + return value(); + } + } + + VSwitch() {} + + @SerializedNames({"CidrBlock", "CreationTime", "Description", "ZoneId", "Status", + "AvailableIpAddressCount", "VpcId", "VSwitchId", "VSwitchName" }) + public static VSwitch create(String cidrBlock, Date creationTime, String description, String zoneId, Status status, + int availableIpAddressCount, + String vpcId, String id, String name) { + return builder().cidrBlock(cidrBlock).creationTime(creationTime).description(description).zoneId(zoneId).status(status) + .availableIpAddressCount(availableIpAddressCount).vpcId(vpcId).id(id).name(name).build(); + } + + public abstract String cidrBlock(); + + public abstract Date creationTime(); + + public abstract String description(); + + public abstract String zoneId(); + + public abstract Status status(); + + public abstract int availableIpAddressCount(); + + public abstract String vpcId(); + + public abstract String id(); + + public abstract String name(); + + public abstract Builder toBuilder(); + + public static Builder builder() { + return new AutoValue_VSwitch.Builder(); + } + + @AutoValue.Builder + public abstract static class Builder { + + public abstract Builder cidrBlock(String cidrBlock); + + public abstract Builder creationTime(Date creationTime); + + public abstract Builder description(String description); + + public abstract Builder zoneId(String regionId); + + public abstract Builder status(Status status); + + public abstract Builder availableIpAddressCount(int availableIpAddressCount); + + public abstract Builder vpcId(String vpcId); + + public abstract Builder id(String id); + + public abstract Builder name(String name); + + abstract VSwitch build(); + } + + +}
