mirror of https://github.com/apache/jclouds.git
Create one resource group in each region
This commit is contained in:
parent
cd16826dca
commit
00d9138864
|
@ -25,12 +25,13 @@ import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_P
|
|||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_INITIAL_PERIOD;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_MAX_PERIOD;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.STORAGE_API_VERSION;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_FORMAT;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_REGEXP;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.IMAGE_AUTHENTICATE_SUDO;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.IMAGE_LOGIN_USER;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.RESOURCENAME_DELIMITER;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.RESOURCENAME_PREFIX;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
|
||||
import static org.jclouds.oauth.v2.config.CredentialType.CLIENT_CREDENTIALS_SECRET;
|
||||
|
@ -88,9 +89,10 @@ public class AzureComputeProviderMetadata extends BaseProviderMetadata {
|
|||
properties.setProperty(TCP_RULE_REGEXP, "tcp_\\d{1,5}-\\d{1,5}");
|
||||
properties.put(RESOURCE, "https://management.azure.com/");
|
||||
properties.put(CREDENTIAL_TYPE, CLIENT_CREDENTIALS_SECRET.toString());
|
||||
properties.put(RESOURCE_GROUP_NAME, "jclouds");
|
||||
properties.put(DEFAULT_VNET_ADDRESS_SPACE_PREFIX, "10.0.0.0/16");
|
||||
properties.put(DEFAULT_SUBNET_ADDRESS_PREFIX, "10.0.0.0/24");
|
||||
properties.put(RESOURCENAME_PREFIX, "jclouds");
|
||||
properties.put(RESOURCENAME_DELIMITER, "-");
|
||||
properties.put(DEFAULT_DATADISKSIZE, "100");
|
||||
properties.put(IMAGE_PUBLISHERS, "Canonical,RedHat");
|
||||
// Default credentials for all images
|
||||
|
|
|
@ -30,11 +30,12 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
|
||||
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.PublicIpAvailablePredicateFactory;
|
||||
import org.jclouds.azurecompute.arm.compute.functions.LocationToResourceGroupName;
|
||||
import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
|
||||
import org.jclouds.azurecompute.arm.domain.DataDisk;
|
||||
import org.jclouds.azurecompute.arm.domain.HardwareProfile;
|
||||
|
@ -51,6 +52,8 @@ import org.jclouds.azurecompute.arm.domain.OSProfile;
|
|||
import org.jclouds.azurecompute.arm.domain.Offer;
|
||||
import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
|
||||
import org.jclouds.azurecompute.arm.domain.PublicIPAddressProperties;
|
||||
import org.jclouds.azurecompute.arm.domain.RegionAndId;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceProviderMetaData;
|
||||
import org.jclouds.azurecompute.arm.domain.SKU;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageProfile;
|
||||
|
@ -86,38 +89,40 @@ import com.google.common.collect.Iterables;
|
|||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
* Defines the connection between the {@link AzureComputeApi} implementation and the jclouds
|
||||
* {@link org.jclouds.compute.ComputeService}.
|
||||
* Defines the connection between the {@link AzureComputeApi} implementation and
|
||||
* the jclouds {@link org.jclouds.compute.ComputeService}.
|
||||
*/
|
||||
@Singleton
|
||||
public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VirtualMachine, VMHardware, VMImage, Location> {
|
||||
|
||||
private final String azureGroup;
|
||||
private final CleanupResources cleanupResources;
|
||||
private final AzureComputeApi api;
|
||||
private final AzureComputeConstants azureComputeConstants;
|
||||
private final Supplier<Set<String>> regionIds;
|
||||
private final Predicate<String> publicIpAvailable;
|
||||
private final PublicIpAvailablePredicateFactory publicIpAvailable;
|
||||
private final LocationToResourceGroupName locationToResourceGroupName;
|
||||
|
||||
@Inject
|
||||
AzureComputeServiceAdapter(final AzureComputeApi api, final AzureComputeConstants azureComputeConstants,
|
||||
CleanupResources cleanupResources, @Region Supplier<Set<String>> regionIds,
|
||||
@Named("PublicIpAvailable") Predicate<String> publicIpAvailable) {
|
||||
PublicIpAvailablePredicateFactory publicIpAvailable, LocationToResourceGroupName locationToResourceGroupName) {
|
||||
this.api = api;
|
||||
this.azureComputeConstants = azureComputeConstants;
|
||||
this.azureGroup = azureComputeConstants.azureResourceGroup();
|
||||
this.cleanupResources = cleanupResources;
|
||||
this.regionIds = regionIds;
|
||||
this.publicIpAvailable = publicIpAvailable;
|
||||
this.locationToResourceGroupName = locationToResourceGroupName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeAndInitialCredentials<VirtualMachine> createNodeWithGroupEncodedIntoName(
|
||||
final String group, final String name, final Template template) {
|
||||
public NodeAndInitialCredentials<VirtualMachine> createNodeWithGroupEncodedIntoName(final String group,
|
||||
final String name, final Template template) {
|
||||
|
||||
AzureTemplateOptions templateOptions = template.getOptions().as(AzureTemplateOptions.class);
|
||||
String azureGroup = locationToResourceGroupName.apply(template.getLocation().getId());
|
||||
|
||||
// TODO Store group apart from the name to be able to identify nodes with custom names in the configured group
|
||||
// TODO Store group apart from the name to be able to identify nodes with
|
||||
// custom names in the configured group
|
||||
// TODO ARM specific options
|
||||
// TODO user metadata and tags
|
||||
// TODO network ids => create one nic in each network
|
||||
|
@ -125,24 +130,26 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
|||
|
||||
String locationName = template.getLocation().getId();
|
||||
String subnetId = templateOptions.getSubnetId();
|
||||
NetworkInterfaceCard nic = createNetworkInterfaceCard(subnetId, name, locationName);
|
||||
NetworkInterfaceCard nic = createNetworkInterfaceCard(subnetId, name, locationName, azureGroup);
|
||||
StorageProfile storageProfile = createStorageProfile(name, template.getImage(), templateOptions.getBlob());
|
||||
HardwareProfile hardwareProfile = HardwareProfile.builder().vmSize(template.getHardware().getId()).build();
|
||||
OSProfile osProfile = createOsProfile(name, template);
|
||||
NetworkProfile networkProfile = NetworkProfile.builder().networkInterfaces(ImmutableList.of(IdReference.create(nic.id()))).build();
|
||||
NetworkProfile networkProfile = NetworkProfile.builder()
|
||||
.networkInterfaces(ImmutableList.of(IdReference.create(nic.id()))).build();
|
||||
VirtualMachineProperties virtualMachineProperties = VirtualMachineProperties.builder()
|
||||
.licenseType(null) // TODO
|
||||
.availabilitySet(null) // TODO
|
||||
.hardwareProfile(hardwareProfile)
|
||||
.storageProfile(storageProfile)
|
||||
.osProfile(osProfile)
|
||||
.networkProfile(networkProfile)
|
||||
.build();
|
||||
.hardwareProfile(hardwareProfile).storageProfile(storageProfile).osProfile(osProfile)
|
||||
.networkProfile(networkProfile).build();
|
||||
|
||||
VirtualMachine virtualMachine = api.getVirtualMachineApi(azureGroup).create(name, template.getLocation().getId(), virtualMachineProperties);
|
||||
VirtualMachine virtualMachine = api.getVirtualMachineApi(azureGroup).create(name, template.getLocation().getId(),
|
||||
virtualMachineProperties);
|
||||
|
||||
// Safe to pass null credentials here, as jclouds will default populate the node with the default credentials from the image, or the ones in the options, if provided.
|
||||
return new NodeAndInitialCredentials<VirtualMachine>(virtualMachine, name, null);
|
||||
// Safe to pass null credentials here, as jclouds will default populate
|
||||
// the node with the default credentials from the image, or the ones in
|
||||
// the options, if provided.
|
||||
RegionAndId regionAndId = RegionAndId.fromRegionAndId(template.getLocation().getId(), name);
|
||||
return new NodeAndInitialCredentials<VirtualMachine>(virtualMachine, regionAndId.slashEncode(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -151,14 +158,9 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
|||
for (Location location : listLocations()) {
|
||||
Iterable<VMSize> vmSizes = api.getVMSizeApi(location.name()).list();
|
||||
for (VMSize vmSize : vmSizes) {
|
||||
VMHardware hwProfile = VMHardware.create(
|
||||
vmSize.name(),
|
||||
vmSize.numberOfCores(),
|
||||
vmSize.osDiskSizeInMB(),
|
||||
vmSize.resourceDiskSizeInMB(),
|
||||
vmSize.memoryInMB(),
|
||||
vmSize.maxDataDiskCount(),
|
||||
location.name(),
|
||||
VMHardware hwProfile = VMHardware
|
||||
.create(vmSize.name(), vmSize.numberOfCores(), vmSize.osDiskSizeInMB(),
|
||||
vmSize.resourceDiskSizeInMB(), vmSize.memoryInMB(), vmSize.maxDataDiskCount(), location.name(),
|
||||
false);
|
||||
hwProfiles.add(hwProfile);
|
||||
}
|
||||
|
@ -188,7 +190,8 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
|||
|
||||
private List<VMImage> listImagesByLocation(String location) {
|
||||
final List<VMImage> osImages = Lists.newArrayList();
|
||||
Iterable<String> publishers = Splitter.on(',').trimResults().omitEmptyStrings().split(this.azureComputeConstants.azureImagePublishers());
|
||||
Iterable<String> publishers = Splitter.on(',').trimResults().omitEmptyStrings()
|
||||
.split(this.azureComputeConstants.azureImagePublishers());
|
||||
for (String publisher : publishers) {
|
||||
osImages.addAll(getImagesFromPublisher(publisher, location));
|
||||
}
|
||||
|
@ -202,8 +205,12 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
|||
for (Location location : listLocations()) {
|
||||
osImages.addAll(listImagesByLocation(location.name()));
|
||||
}
|
||||
|
||||
// list custom images
|
||||
for (ResourceGroup resourceGroup : api.getResourceGroupApi().list()) {
|
||||
String azureGroup = resourceGroup.name();
|
||||
List<StorageService> storages = api.getStorageAccountApi(azureGroup).list();
|
||||
|
||||
for (StorageService storage : storages) {
|
||||
String name = storage.name();
|
||||
StorageService storageService = api.getStorageAccountApi(azureGroup).get(name);
|
||||
|
@ -220,6 +227,7 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return osImages;
|
||||
}
|
||||
|
@ -227,11 +235,14 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
|||
@Override
|
||||
public VMImage getImage(final String id) {
|
||||
VMImage image = decodeFieldsFromUniqueId(id);
|
||||
String azureGroup = locationToResourceGroupName.apply(image.location());
|
||||
|
||||
if (image.custom()) {
|
||||
VMImage customImage = null;
|
||||
StorageServiceKeys keys = api.getStorageAccountApi(azureGroup).getKeys(image.storage());
|
||||
if (keys == null) {
|
||||
// If the storage account for the image does not exist, it means the image was deleted
|
||||
// If the storage account for the image does not exist, it means the
|
||||
// image was deleted
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -275,35 +286,33 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
|||
public boolean apply(ResourceProviderMetaData input) {
|
||||
return input.resourceType().equals("virtualMachines");
|
||||
}
|
||||
})
|
||||
.transformAndConcat(new Function<ResourceProviderMetaData, Iterable<String>>() {
|
||||
}).transformAndConcat(new Function<ResourceProviderMetaData, Iterable<String>>() {
|
||||
@Override
|
||||
public Iterable<String> apply(ResourceProviderMetaData resourceProviderMetaData) {
|
||||
return resourceProviderMetaData.locations();
|
||||
}
|
||||
});
|
||||
|
||||
List<Location> locations = FluentIterable.from(api.getLocationApi().list())
|
||||
.filter(new Predicate<Location>() {
|
||||
List<Location> locations = FluentIterable.from(api.getLocationApi().list()).filter(new Predicate<Location>() {
|
||||
@Override
|
||||
public boolean apply(Location location) {
|
||||
return Iterables.contains(vmLocations, location.displayName());
|
||||
}
|
||||
})
|
||||
.filter(new Predicate<Location>() {
|
||||
}).filter(new Predicate<Location>() {
|
||||
@Override
|
||||
public boolean apply(Location location) {
|
||||
return regionIds.get().isEmpty() ? true : regionIds.get().contains(location.name());
|
||||
}
|
||||
})
|
||||
.toList();
|
||||
}).toList();
|
||||
|
||||
return locations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VirtualMachine getNode(final String id) {
|
||||
return api.getVirtualMachineApi(azureGroup).get(id);
|
||||
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
|
||||
String azureGroup = locationToResourceGroupName.apply(regionAndId.region());
|
||||
return api.getVirtualMachineApi(azureGroup).get(regionAndId.id());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -313,22 +322,32 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
|||
|
||||
@Override
|
||||
public void rebootNode(final String id) {
|
||||
api.getVirtualMachineApi(azureGroup).restart(id);
|
||||
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
|
||||
String azureGroup = locationToResourceGroupName.apply(regionAndId.region());
|
||||
api.getVirtualMachineApi(azureGroup).restart(regionAndId.id());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeNode(final String id) {
|
||||
api.getVirtualMachineApi(azureGroup).start(id);
|
||||
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
|
||||
String azureGroup = locationToResourceGroupName.apply(regionAndId.region());
|
||||
api.getVirtualMachineApi(azureGroup).start(regionAndId.id());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suspendNode(final String id) {
|
||||
api.getVirtualMachineApi(azureGroup).stop(id);
|
||||
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
|
||||
String azureGroup = locationToResourceGroupName.apply(regionAndId.region());
|
||||
api.getVirtualMachineApi(azureGroup).stop(regionAndId.id());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<VirtualMachine> listNodes() {
|
||||
return api.getVirtualMachineApi(azureGroup).list();
|
||||
ImmutableList.Builder<VirtualMachine> nodes = ImmutableList.builder();
|
||||
for (ResourceGroup resourceGroup : api.getResourceGroupApi().list()) {
|
||||
nodes.addAll(api.getVirtualMachineApi(resourceGroup.name()).list());
|
||||
}
|
||||
return nodes.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -341,59 +360,54 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
private OSProfile createOsProfile(String computerName, Template template) {
|
||||
String defaultLoginUser = template.getImage().getDefaultCredentials().getUser();
|
||||
String defaultLoginPassword = template.getImage().getDefaultCredentials().getOptionalPassword().get();
|
||||
String adminUsername = Objects.firstNonNull(template.getOptions().getLoginUser(), defaultLoginUser);
|
||||
String adminPassword = Objects.firstNonNull(template.getOptions().getLoginPassword(), defaultLoginPassword);
|
||||
OSProfile.Builder builder = OSProfile.builder().adminUsername(adminUsername).computerName(computerName);
|
||||
// prefer public key over password
|
||||
if (template.getOptions().getPublicKey() != null) {
|
||||
OSProfile.Builder builder = OSProfile.builder().adminUsername(adminUsername).adminPassword(adminPassword)
|
||||
.computerName(computerName);
|
||||
|
||||
if (template.getOptions().getPublicKey() != null
|
||||
&& OsFamily.WINDOWS != template.getImage().getOperatingSystem().getFamily()) {
|
||||
OSProfile.LinuxConfiguration linuxConfiguration = OSProfile.LinuxConfiguration.create("true",
|
||||
OSProfile.LinuxConfiguration.SSH.create(ImmutableList.of(
|
||||
OSProfile.LinuxConfiguration.SSH.SSHPublicKey.create(
|
||||
String.format("/home/%s/.ssh/authorized_keys", adminUsername),
|
||||
template.getOptions().getPublicKey())
|
||||
))
|
||||
);
|
||||
OSProfile.LinuxConfiguration.SSH.create(ImmutableList.of(OSProfile.LinuxConfiguration.SSH.SSHPublicKey
|
||||
.create(String.format("/home/%s/.ssh/authorized_keys", adminUsername), template.getOptions()
|
||||
.getPublicKey()))));
|
||||
builder.linuxConfiguration(linuxConfiguration);
|
||||
} else {
|
||||
builder.adminPassword(adminPassword);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private NetworkInterfaceCard createNetworkInterfaceCard(String subnetId, String name, String locationName) {
|
||||
private NetworkInterfaceCard createNetworkInterfaceCard(String subnetId, String name, String locationName,
|
||||
String azureGroup) {
|
||||
final PublicIPAddressApi ipApi = api.getPublicIPAddressApi(azureGroup);
|
||||
|
||||
PublicIPAddressProperties properties =
|
||||
PublicIPAddressProperties.builder()
|
||||
.publicIPAllocationMethod("Static")
|
||||
.idleTimeoutInMinutes(4)
|
||||
.build();
|
||||
PublicIPAddressProperties properties = PublicIPAddressProperties.builder().publicIPAllocationMethod("Static")
|
||||
.idleTimeoutInMinutes(4).build();
|
||||
|
||||
String publicIpAddressName = "public-address-" + name;
|
||||
PublicIPAddress ip = ipApi.createOrUpdate(publicIpAddressName, locationName, ImmutableMap.of("jclouds", name), properties);
|
||||
PublicIPAddress ip = ipApi.createOrUpdate(publicIpAddressName, locationName, ImmutableMap.of("jclouds", name),
|
||||
properties);
|
||||
|
||||
checkState(publicIpAvailable.apply(publicIpAddressName),
|
||||
checkState(publicIpAvailable.create(azureGroup).apply(publicIpAddressName),
|
||||
"Public IP was not provisioned in the configured timeout");
|
||||
|
||||
final NetworkInterfaceCardProperties networkInterfaceCardProperties =
|
||||
NetworkInterfaceCardProperties.builder()
|
||||
.ipConfigurations(ImmutableList.of(
|
||||
IpConfiguration.builder()
|
||||
final NetworkInterfaceCardProperties networkInterfaceCardProperties = NetworkInterfaceCardProperties
|
||||
.builder()
|
||||
.ipConfigurations(
|
||||
ImmutableList.of(IpConfiguration
|
||||
.builder()
|
||||
.name("ipConfig-" + name)
|
||||
.properties(IpConfigurationProperties.builder()
|
||||
.privateIPAllocationMethod("Dynamic")
|
||||
.publicIPAddress(IdReference.create(ip.id()))
|
||||
.subnet(IdReference.create(subnetId))
|
||||
.build())
|
||||
.build()))
|
||||
.build();
|
||||
.properties(
|
||||
IpConfigurationProperties.builder().privateIPAllocationMethod("Dynamic")
|
||||
.publicIPAddress(IdReference.create(ip.id())).subnet(IdReference.create(subnetId))
|
||||
.build()).build())).build();
|
||||
|
||||
String networkInterfaceCardName = "jc-nic-" + name;
|
||||
return api.getNetworkInterfaceCardApi(azureGroup).createOrUpdate(networkInterfaceCardName, locationName, networkInterfaceCardProperties, ImmutableMap.of("jclouds", name));
|
||||
return api.getNetworkInterfaceCardApi(azureGroup).createOrUpdate(networkInterfaceCardName, locationName,
|
||||
networkInterfaceCardProperties, ImmutableMap.of("jclouds", name));
|
||||
}
|
||||
|
||||
private StorageProfile createStorageProfile(String name, Image image, String blob) {
|
||||
|
@ -403,12 +417,8 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
|||
String osType = null;
|
||||
|
||||
if (!imageRef.custom()) {
|
||||
imageReference = ImageReference.builder()
|
||||
.publisher(image.getProviderId())
|
||||
.offer(image.getName())
|
||||
.sku(image.getVersion())
|
||||
.version("latest")
|
||||
.build();
|
||||
imageReference = ImageReference.builder().publisher(image.getProviderId()).offer(image.getName())
|
||||
.sku(image.getVersion()).version("latest").build();
|
||||
} else {
|
||||
sourceImage = VHD.create(image.getProviderId());
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_P
|
|||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_INITIAL_PERIOD;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_MAX_PERIOD;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_FORMAT;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_REGEXP;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
|
||||
|
@ -137,10 +136,6 @@ public class AzureComputeServiceContextModule
|
|||
@Inject
|
||||
private String tcpRuleRegexpProperty;
|
||||
|
||||
@Named(RESOURCE_GROUP_NAME)
|
||||
@Inject
|
||||
private String azureResourceGroupProperty;
|
||||
|
||||
@Named(IMAGE_PUBLISHERS)
|
||||
@Inject
|
||||
private String azureImagePublishersProperty;
|
||||
|
@ -161,10 +156,6 @@ public class AzureComputeServiceContextModule
|
|||
return Long.parseLong(operationTimeoutProperty);
|
||||
}
|
||||
|
||||
public String azureResourceGroup() {
|
||||
return azureResourceGroupProperty;
|
||||
}
|
||||
|
||||
public String azureImagePublishers() {
|
||||
return azureImagePublishersProperty;
|
||||
}
|
||||
|
@ -199,10 +190,10 @@ public class AzureComputeServiceContextModule
|
|||
}
|
||||
|
||||
@Provides
|
||||
@com.google.inject.name.Named(TIMEOUT_NODE_RUNNING)
|
||||
protected Predicate<String> provideVirtualMachineRunningPredicate(final AzureComputeApi api, final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants, Timeouts timeouts, PollPeriod pollPeriod) {
|
||||
String azureGroup = azureComputeConstants.azureResourceGroup();
|
||||
return retry(new VirtualMachineInStatePredicate(api, azureGroup, PowerState.RUNNING), timeouts.nodeRunning,
|
||||
@Named(TIMEOUT_NODE_RUNNING)
|
||||
protected VirtualMachineInStatePredicateFactory provideVirtualMachineRunningPredicate(final AzureComputeApi api,
|
||||
Timeouts timeouts, PollPeriod pollPeriod) {
|
||||
return new VirtualMachineInStatePredicateFactory(api, PowerState.RUNNING, timeouts.nodeRunning,
|
||||
pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
|
||||
}
|
||||
|
||||
|
@ -229,19 +220,17 @@ public class AzureComputeServiceContextModule
|
|||
|
||||
@Provides
|
||||
@Named(TIMEOUT_NODE_SUSPENDED)
|
||||
protected Predicate<String> provideNodeSuspendedPredicate(final AzureComputeApi api, final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants,
|
||||
protected VirtualMachineInStatePredicateFactory provideNodeSuspendedPredicate(final AzureComputeApi api,
|
||||
Timeouts timeouts, PollPeriod pollPeriod) {
|
||||
String azureGroup = azureComputeConstants.azureResourceGroup();
|
||||
return retry(new VirtualMachineInStatePredicate(api, azureGroup, PowerState.STOPPED), timeouts.nodeTerminated,
|
||||
return new VirtualMachineInStatePredicateFactory(api, PowerState.STOPPED, timeouts.nodeTerminated,
|
||||
pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("PublicIpAvailable")
|
||||
protected Predicate<String> providePublicIpAvailablePredicate(final AzureComputeApi api, final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants,
|
||||
Timeouts timeouts, PollPeriod pollPeriod) {
|
||||
String azureGroup = azureComputeConstants.azureResourceGroup();
|
||||
return retry(new PublicIpAvailablePredicate(api, azureGroup), azureComputeConstants.operationTimeout(),
|
||||
protected PublicIpAvailablePredicateFactory providePublicIpAvailablePredicate(final AzureComputeApi api,
|
||||
final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants, Timeouts timeouts,
|
||||
PollPeriod pollPeriod) {
|
||||
return new PublicIpAvailablePredicateFactory(api, azureComputeConstants.operationTimeout(),
|
||||
azureComputeConstants.operationPollInitialPeriod(), azureComputeConstants.operationPollMaxPeriod());
|
||||
}
|
||||
|
||||
|
@ -280,39 +269,54 @@ public class AzureComputeServiceContextModule
|
|||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class VirtualMachineInStatePredicate implements Predicate<String> {
|
||||
public static class VirtualMachineInStatePredicateFactory {
|
||||
|
||||
private final AzureComputeApi api;
|
||||
private final String azureGroup;
|
||||
private final PowerState powerState;
|
||||
private final long timeout;
|
||||
private final long period;
|
||||
private final long maxPeriod;
|
||||
|
||||
public VirtualMachineInStatePredicate(AzureComputeApi api, String azureGroup, PowerState powerState) {
|
||||
this.api = checkNotNull(api, "api must not be null");
|
||||
this.azureGroup = checkNotNull(azureGroup, "azuregroup must not be null");
|
||||
this.powerState = checkNotNull(powerState, "powerState must not be null");
|
||||
VirtualMachineInStatePredicateFactory(AzureComputeApi api, PowerState powerState, long timeout,
|
||||
long period, long maxPeriod) {
|
||||
this.api = checkNotNull(api, "api cannot be null");
|
||||
this.powerState = checkNotNull(powerState, "powerState cannot be null");
|
||||
this.timeout = timeout;
|
||||
this.period = period;
|
||||
this.maxPeriod = maxPeriod;
|
||||
}
|
||||
|
||||
public Predicate<String> create(final String azureGroup) {
|
||||
return retry(new Predicate<String>() {
|
||||
@Override
|
||||
public boolean apply(String name) {
|
||||
checkNotNull(name, "name cannot be null");
|
||||
VirtualMachineInstance vmInstance = api.getVirtualMachineApi(this.azureGroup).getInstanceDetails(name);
|
||||
if (vmInstance == null) return false;
|
||||
VirtualMachineInstance vmInstance = api.getVirtualMachineApi(azureGroup).getInstanceDetails(name);
|
||||
if (vmInstance == null)
|
||||
return false;
|
||||
return powerState == vmInstance.powerState();
|
||||
}
|
||||
}, timeout, period, maxPeriod);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class PublicIpAvailablePredicate implements Predicate<String> {
|
||||
public static class PublicIpAvailablePredicateFactory {
|
||||
|
||||
private final AzureComputeApi api;
|
||||
private final String azureGroup;
|
||||
private final long timeout;
|
||||
private final long period;
|
||||
private final long maxPeriod;
|
||||
|
||||
public PublicIpAvailablePredicate(AzureComputeApi api, String azureGroup) {
|
||||
this.api = checkNotNull(api, "api must not be null");
|
||||
this.azureGroup = checkNotNull(azureGroup, "azuregroup must not be null");
|
||||
PublicIpAvailablePredicateFactory(AzureComputeApi api, long timeout,
|
||||
long period, long maxPeriod) {
|
||||
this.api = checkNotNull(api, "api cannot be null");
|
||||
this.timeout = timeout;
|
||||
this.period = period;
|
||||
this.maxPeriod = maxPeriod;
|
||||
}
|
||||
|
||||
public Predicate<String> create(final String azureGroup) {
|
||||
return retry(new Predicate<String>() {
|
||||
@Override
|
||||
public boolean apply(String name) {
|
||||
checkNotNull(name, "name cannot be null");
|
||||
|
@ -320,6 +324,8 @@ public class AzureComputeServiceContextModule
|
|||
if (publicIp == null) return false;
|
||||
return publicIp.properties().provisioningState().equalsIgnoreCase("Succeeded");
|
||||
}
|
||||
}, timeout, period, maxPeriod);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,8 +31,10 @@ import javax.annotation.Resource;
|
|||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
|
||||
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.VirtualMachineInStatePredicateFactory;
|
||||
import org.jclouds.azurecompute.arm.compute.functions.LocationToResourceGroupName;
|
||||
import org.jclouds.azurecompute.arm.compute.functions.ResourceDefinitionToCustomImage;
|
||||
import org.jclouds.azurecompute.arm.domain.RegionAndId;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
|
||||
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||
|
@ -61,27 +63,27 @@ public class AzureComputeImageExtension implements ImageExtension {
|
|||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final AzureComputeApi api;
|
||||
private final String group;
|
||||
private final ListeningExecutorService userExecutor;
|
||||
private final Predicate<URI> imageAvailablePredicate;
|
||||
private final Predicate<String> nodeSuspendedPredicate;
|
||||
private final VirtualMachineInStatePredicateFactory nodeSuspendedPredicate;
|
||||
private final ResourceDefinitionToCustomImage.Factory resourceDefinitionToImage;
|
||||
private final CleanupResources cleanupResources;
|
||||
private final LocationToResourceGroupName locationToResourceGroupName;
|
||||
|
||||
@Inject
|
||||
AzureComputeImageExtension(AzureComputeApi api,
|
||||
@Named(TIMEOUT_IMAGE_AVAILABLE) Predicate<URI> imageAvailablePredicate,
|
||||
@Named(TIMEOUT_NODE_SUSPENDED) Predicate<String> nodeSuspendedPredicate,
|
||||
AzureComputeConstants azureComputeConstants,
|
||||
@Named(TIMEOUT_NODE_SUSPENDED) VirtualMachineInStatePredicateFactory nodeSuspendedPredicate,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
|
||||
ResourceDefinitionToCustomImage.Factory resourceDefinitionToImage, CleanupResources cleanupResources) {
|
||||
ResourceDefinitionToCustomImage.Factory resourceDefinitionToImage, CleanupResources cleanupResources,
|
||||
LocationToResourceGroupName locationToResourceGroupName) {
|
||||
this.api = api;
|
||||
this.imageAvailablePredicate = imageAvailablePredicate;
|
||||
this.nodeSuspendedPredicate = nodeSuspendedPredicate;
|
||||
this.group = azureComputeConstants.azureResourceGroup();
|
||||
this.userExecutor = userExecutor;
|
||||
this.resourceDefinitionToImage = resourceDefinitionToImage;
|
||||
this.cleanupResources = cleanupResources;
|
||||
this.locationToResourceGroupName = locationToResourceGroupName;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -92,21 +94,23 @@ public class AzureComputeImageExtension implements ImageExtension {
|
|||
@Override
|
||||
public ListenableFuture<Image> createImage(ImageTemplate template) {
|
||||
final CloneImageTemplate cloneTemplate = (CloneImageTemplate) template;
|
||||
final String id = cloneTemplate.getSourceNodeId();
|
||||
final String name = cloneTemplate.getName();
|
||||
|
||||
logger.debug(">> stopping node %s...", id);
|
||||
api.getVirtualMachineApi(group).stop(id);
|
||||
checkState(nodeSuspendedPredicate.apply(id), "Node %s was not suspended within the configured time limit", id);
|
||||
final RegionAndId regionAndId = RegionAndId.fromSlashEncoded(cloneTemplate.getSourceNodeId());
|
||||
final String group = locationToResourceGroupName.apply(regionAndId.region());
|
||||
|
||||
logger.debug(">> stopping node %s...", regionAndId.slashEncode());
|
||||
api.getVirtualMachineApi(group).stop(regionAndId.id());
|
||||
checkState(nodeSuspendedPredicate.create(group).apply(regionAndId.id()),
|
||||
"Node %s was not suspended within the configured time limit", regionAndId.slashEncode());
|
||||
|
||||
return userExecutor.submit(new Callable<Image>() {
|
||||
@Override
|
||||
public Image call() throws Exception {
|
||||
logger.debug(">> generalizing virtal machine %s...", id);
|
||||
api.getVirtualMachineApi(group).generalize(id);
|
||||
logger.debug(">> generalizing virtal machine %s...", regionAndId.id());
|
||||
api.getVirtualMachineApi(group).generalize(regionAndId.id());
|
||||
|
||||
logger.debug(">> capturing virtual machine %s to container %s...", id, CONTAINER_NAME);
|
||||
URI uri = api.getVirtualMachineApi(group).capture(id, cloneTemplate.getName(), CONTAINER_NAME);
|
||||
logger.debug(">> capturing virtual machine %s to container %s...", regionAndId.id(), CONTAINER_NAME);
|
||||
URI uri = api.getVirtualMachineApi(group).capture(regionAndId.id(), cloneTemplate.getName(), CONTAINER_NAME);
|
||||
checkState(uri != null && imageAvailablePredicate.apply(uri),
|
||||
"Image %s was not created within the configured time limit", cloneTemplate.getName());
|
||||
|
||||
|
@ -114,7 +118,8 @@ public class AzureComputeImageExtension implements ImageExtension {
|
|||
checkState(definitions.size() == 1,
|
||||
"Expected one resource definition after creating the image but %s were returned", definitions.size());
|
||||
|
||||
Image image = resourceDefinitionToImage.create(id, name).apply(definitions.get(0));
|
||||
Image image = resourceDefinitionToImage.create(cloneTemplate.getSourceNodeId(), cloneTemplate.getName())
|
||||
.apply(definitions.get(0));
|
||||
logger.debug(">> created %s", image);
|
||||
return image;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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.azurecompute.arm.compute.functions;
|
||||
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.RESOURCENAME_DELIMITER;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.RESOURCENAME_PREFIX;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* Returns the name of the resource group for the current location.
|
||||
*/
|
||||
public class LocationToResourceGroupName implements Function<String, String> {
|
||||
|
||||
private final String prefix;
|
||||
private final char delimiter;
|
||||
|
||||
@Inject
|
||||
LocationToResourceGroupName(@Named(RESOURCENAME_PREFIX) String prefix, @Named(RESOURCENAME_DELIMITER) char delimiter) {
|
||||
this.prefix = prefix;
|
||||
this.delimiter = delimiter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apply(String input) {
|
||||
return String.format("%s%s%s", prefix, delimiter, input);
|
||||
}
|
||||
|
||||
}
|
|
@ -23,7 +23,7 @@ import java.util.Map;
|
|||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
|
||||
import org.jclouds.azurecompute.arm.domain.RegionAndId;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
|
||||
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||
|
@ -39,21 +39,24 @@ public class ResourceDefinitionToCustomImage implements Function<ResourceDefinit
|
|||
ResourceDefinitionToCustomImage create(@Assisted("nodeId") String nodeId, @Assisted("imageName") String imageName);
|
||||
}
|
||||
|
||||
private final String resourceGroup;
|
||||
private final Function<VMImage, Image> vmImageToImage;
|
||||
private final String imageName;
|
||||
private final String storageAccountName;
|
||||
private final VirtualMachine vm;
|
||||
private final String resourceGroup;
|
||||
|
||||
@Inject
|
||||
ResourceDefinitionToCustomImage(AzureComputeApi api, AzureComputeConstants azureComputeConstants,
|
||||
ResourceDefinitionToCustomImage(AzureComputeApi api,
|
||||
StorageProfileToStorageAccountName storageProfileToStorageAccountName,
|
||||
Function<VMImage, Image> vmImageToImage, @Assisted("nodeId") String nodeId,
|
||||
Function<VMImage, Image> vmImageToImage, LocationToResourceGroupName locationToResourceGroupName,
|
||||
@Assisted("nodeId") String nodeId,
|
||||
@Assisted("imageName") String imageName) {
|
||||
this.vmImageToImage = vmImageToImage;
|
||||
this.resourceGroup = azureComputeConstants.azureResourceGroup();
|
||||
this.imageName = imageName;
|
||||
this.vm = api.getVirtualMachineApi(resourceGroup).get(nodeId);
|
||||
|
||||
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(nodeId);
|
||||
this.resourceGroup = locationToResourceGroupName.apply(regionAndId.region());
|
||||
this.vm = api.getVirtualMachineApi(this.resourceGroup).get(regionAndId.id());
|
||||
this.storageAccountName = storageProfileToStorageAccountName.apply(vm.properties().storageProfile());
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextMod
|
|||
import org.jclouds.azurecompute.arm.domain.IdReference;
|
||||
import org.jclouds.azurecompute.arm.domain.IpConfiguration;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
|
||||
import org.jclouds.azurecompute.arm.domain.RegionAndId;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageProfile;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
|
||||
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||
|
@ -110,7 +111,6 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
|
|||
.put(PowerState.UNRECOGNIZED, NodeMetadata.Status.UNRECOGNIZED).build(),
|
||||
NodeMetadata.Status.UNRECOGNIZED);
|
||||
|
||||
private final String azureGroup;
|
||||
private final AzureComputeApi api;
|
||||
private final GroupNamingConvention nodeNamingConvention;
|
||||
private final Supplier<Map<String, ? extends Image>> images;
|
||||
|
@ -119,28 +119,32 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
|
|||
private final Map<String, Credentials> credentialStore;
|
||||
private final Function<VMImage, Image> vmImageToImge;
|
||||
private final StorageProfileToStorageAccountName storageProfileToStorageAccountName;
|
||||
private final LocationToResourceGroupName locationToResourceGroupName;
|
||||
|
||||
@Inject
|
||||
VirtualMachineToNodeMetadata(AzureComputeApi api, GroupNamingConvention.Factory namingConvention,
|
||||
Supplier<Map<String, ? extends Image>> images, Supplier<Map<String, ? extends Hardware>> hardwares,
|
||||
@Memoized Supplier<Set<? extends Location>> locations, Map<String, Credentials> credentialStore,
|
||||
final AzureComputeConstants azureComputeConstants, Function<VMImage, Image> vmImageToImge,
|
||||
StorageProfileToStorageAccountName storageProfileToStorageAccountName) {
|
||||
StorageProfileToStorageAccountName storageProfileToStorageAccountName,
|
||||
LocationToResourceGroupName locationToResourceGroupName) {
|
||||
this.api = api;
|
||||
this.nodeNamingConvention = namingConvention.createWithoutPrefix();
|
||||
this.images = checkNotNull(images, "images cannot be null");
|
||||
this.locations = checkNotNull(locations, "locations cannot be null");
|
||||
this.hardwares = checkNotNull(hardwares, "hardwares cannot be null");
|
||||
this.credentialStore = credentialStore;
|
||||
this.azureGroup = azureComputeConstants.azureResourceGroup();
|
||||
this.vmImageToImge = vmImageToImge;
|
||||
this.storageProfileToStorageAccountName = storageProfileToStorageAccountName;
|
||||
this.locationToResourceGroupName = locationToResourceGroupName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata apply(VirtualMachine virtualMachine) {
|
||||
String azureGroup = locationToResourceGroupName.apply(virtualMachine.location());
|
||||
|
||||
NodeMetadataBuilder builder = new NodeMetadataBuilder();
|
||||
builder.id(virtualMachine.name());
|
||||
builder.id(RegionAndId.fromRegionAndId(virtualMachine.location(), virtualMachine.name()).slashEncode());
|
||||
builder.providerId(virtualMachine.id());
|
||||
builder.name(virtualMachine.name());
|
||||
builder.hostname(virtualMachine.name());
|
||||
|
@ -180,7 +184,7 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
|
|||
String locationName = virtualMachine.location();
|
||||
builder.location(getLocation(locationName));
|
||||
|
||||
Optional<? extends Image> image = findImage(virtualMachine.properties().storageProfile(), locationName);
|
||||
Optional<? extends Image> image = findImage(virtualMachine.properties().storageProfile(), locationName, azureGroup);
|
||||
if (image.isPresent()) {
|
||||
builder.imageId(image.get().getId());
|
||||
builder.operatingSystem(image.get().getOperatingSystem());
|
||||
|
@ -239,7 +243,7 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
|
|||
}, null);
|
||||
}
|
||||
|
||||
protected Optional<? extends Image> findImage(final StorageProfile storageProfile, String locatioName) {
|
||||
protected Optional<? extends Image> findImage(final StorageProfile storageProfile, String locatioName, String azureGroup) {
|
||||
if (storageProfile.imageReference() != null) {
|
||||
return Optional.fromNullable(images.get().get(
|
||||
encodeFieldsToUniqueId(false, locatioName, storageProfile.imageReference())));
|
||||
|
|
|
@ -35,6 +35,7 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.Constants;
|
||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule;
|
||||
import org.jclouds.azurecompute.arm.compute.functions.LocationToResourceGroupName;
|
||||
import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageService;
|
||||
|
@ -73,6 +74,7 @@ public class CreateResourceGroupThenCreateNodes extends CreateNodesWithGroupEnco
|
|||
|
||||
private final AzureComputeApi api;
|
||||
private final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants;
|
||||
private final LocationToResourceGroupName locationToResourceGroupName;
|
||||
|
||||
@Inject
|
||||
protected CreateResourceGroupThenCreateNodes(
|
||||
|
@ -81,12 +83,14 @@ public class CreateResourceGroupThenCreateNodes extends CreateNodesWithGroupEnco
|
|||
GroupNamingConvention.Factory namingConvention,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
|
||||
CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
|
||||
AzureComputeApi api, AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants) {
|
||||
AzureComputeApi api, AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants,
|
||||
LocationToResourceGroupName locationToResourceGroupName) {
|
||||
super(addNodeWithGroupStrategy, listNodesStrategy, namingConvention, userExecutor,
|
||||
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
|
||||
this.api = checkNotNull(api, "api cannot be null");
|
||||
checkNotNull(userExecutor, "userExecutor cannot be null");
|
||||
this.azureComputeConstants = azureComputeConstants;
|
||||
this.locationToResourceGroupName = locationToResourceGroupName;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -100,7 +104,7 @@ public class CreateResourceGroupThenCreateNodes extends CreateNodesWithGroupEnco
|
|||
logger.warn(">> a runScript was configured but no SSH key has been provided. " +
|
||||
"Authentication will delegate to the ssh-agent");
|
||||
}
|
||||
String azureGroupName = this.azureComputeConstants.azureResourceGroup();
|
||||
String azureGroupName = locationToResourceGroupName.apply(template.getLocation().getId());
|
||||
|
||||
AzureTemplateOptions options = template.getOptions().as(AzureTemplateOptions.class);
|
||||
// create resource group for jclouds group if it does not already exist
|
||||
|
|
|
@ -34,8 +34,6 @@ public class AzureComputeProperties {
|
|||
|
||||
public static final String TCP_RULE_REGEXP = "jclouds.azurecompute.arm.tcp.rule.regexp";
|
||||
|
||||
public static final String RESOURCE_GROUP_NAME = "jclouds.azurecompute.arm.operation.resourcegroup";
|
||||
|
||||
public static final String IMAGE_PUBLISHERS = "jclouds.azurecompute.arm.publishers";
|
||||
|
||||
public static final String DEFAULT_IMAGE_LOGIN = "jclouds.azurecompute.arm.defaultimagelogin";
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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.azurecompute.arm.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
@AutoValue
|
||||
public abstract class RegionAndId {
|
||||
|
||||
public abstract String region();
|
||||
public abstract String id();
|
||||
|
||||
RegionAndId() {
|
||||
|
||||
}
|
||||
|
||||
public static RegionAndId fromSlashEncoded(String id) {
|
||||
Iterable<String> parts = Splitter.on('/').split(checkNotNull(id, "id"));
|
||||
checkArgument(Iterables.size(parts) == 2, "id must be in format regionId/id");
|
||||
return new AutoValue_RegionAndId(Iterables.get(parts, 0), Iterables.get(parts, 1));
|
||||
}
|
||||
|
||||
public static RegionAndId fromRegionAndId(String region, String id) {
|
||||
return new AutoValue_RegionAndId(region, id);
|
||||
}
|
||||
|
||||
public String slashEncode() {
|
||||
return region() + "/" + id();
|
||||
}
|
||||
|
||||
}
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
package org.jclouds.azurecompute.arm.functions;
|
||||
|
||||
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.transform;
|
||||
|
@ -25,7 +24,6 @@ import static org.jclouds.util.Closeables2.closeQuietly;
|
|||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
@ -33,10 +31,11 @@ import javax.inject.Named;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||
import org.jclouds.azurecompute.arm.compute.functions.LocationToResourceGroupName;
|
||||
import org.jclouds.azurecompute.arm.domain.IdReference;
|
||||
import org.jclouds.azurecompute.arm.domain.IpConfiguration;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
|
||||
import org.jclouds.azurecompute.arm.domain.RegionAndId;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
|
||||
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||
import org.jclouds.azurecompute.arm.util.BlobHelper;
|
||||
|
@ -46,10 +45,8 @@ import org.jclouds.logging.Logger;
|
|||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
@Singleton
|
||||
public class CleanupResources implements Function<String, Boolean> {
|
||||
|
@ -61,28 +58,29 @@ public class CleanupResources implements Function<String, Boolean> {
|
|||
protected final AzureComputeApi api;
|
||||
private final Predicate<URI> resourceDeleted;
|
||||
private final StorageProfileToStorageAccountName storageProfileToStorageAccountName;
|
||||
private final LocationToResourceGroupName locationToResourceGroupName;
|
||||
|
||||
@Inject
|
||||
CleanupResources(AzureComputeApi azureComputeApi, @Named(TIMEOUT_RESOURCE_DELETED) Predicate<URI> resourceDeleted,
|
||||
StorageProfileToStorageAccountName storageProfileToStorageAccountName) {
|
||||
StorageProfileToStorageAccountName storageProfileToStorageAccountName,
|
||||
LocationToResourceGroupName locationToResourceGroupName) {
|
||||
this.api = azureComputeApi;
|
||||
this.resourceDeleted = resourceDeleted;
|
||||
this.storageProfileToStorageAccountName = storageProfileToStorageAccountName;
|
||||
this.locationToResourceGroupName = locationToResourceGroupName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean apply(final String id) {
|
||||
logger.debug(">> destroying %s ...", id);
|
||||
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
|
||||
String group = locationToResourceGroupName.apply(regionAndId.region());
|
||||
|
||||
Map<String, VirtualMachine> resourceGroupNamesAndVirtualMachines = getResourceGroupNamesAndVirtualMachines(id);
|
||||
if (resourceGroupNamesAndVirtualMachines.isEmpty())
|
||||
VirtualMachine virtualMachine = api.getVirtualMachineApi(group).get(regionAndId.id());
|
||||
if (virtualMachine == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String group = checkNotNull(resourceGroupNamesAndVirtualMachines.entrySet().iterator().next().getKey(),
|
||||
"resourceGroup name must not be null");
|
||||
VirtualMachine virtualMachine = checkNotNull(resourceGroupNamesAndVirtualMachines.get(group),
|
||||
"virtualMachine must not be null");
|
||||
|
||||
logger.debug(">> destroying %s ...", regionAndId.slashEncode());
|
||||
boolean vmDeleted = deleteVirtualMachine(group, virtualMachine);
|
||||
|
||||
// We don't delete the network here, as it is global to the resource
|
||||
|
@ -163,14 +161,4 @@ public class CleanupResources implements Function<String, Boolean> {
|
|||
return resourceDeleted.apply(api.getVirtualMachineApi(group).delete(virtualMachine.name()));
|
||||
}
|
||||
|
||||
private Map<String, VirtualMachine> getResourceGroupNamesAndVirtualMachines(String id) {
|
||||
for (ResourceGroup resourceGroup : api.getResourceGroupApi().list()) {
|
||||
String group = resourceGroup.name();
|
||||
VirtualMachine virtualMachine = api.getVirtualMachineApi(group).get(id);
|
||||
if (virtualMachine != null) {
|
||||
return ImmutableMap.of(group, virtualMachine);
|
||||
}
|
||||
}
|
||||
return Maps.newHashMap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,19 +16,9 @@
|
|||
*/
|
||||
package org.jclouds.azurecompute.arm.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_PORT_OPEN;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE;
|
||||
import static org.jclouds.compute.options.TemplateOptions.Builder.authorizePublicKey;
|
||||
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata;
|
||||
import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils;
|
||||
|
@ -78,19 +68,8 @@ public class AzureComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
@Override
|
||||
protected Properties setupProperties() {
|
||||
Properties properties = super.setupProperties();
|
||||
String defaultTimeout = String.valueOf(TimeUnit.MILLISECONDS.convert(60, TimeUnit.MINUTES));
|
||||
properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, defaultTimeout);
|
||||
properties.setProperty(TIMEOUT_NODE_RUNNING, defaultTimeout);
|
||||
properties.setProperty(TIMEOUT_PORT_OPEN, defaultTimeout);
|
||||
properties.setProperty(TIMEOUT_NODE_TERMINATED, defaultTimeout);
|
||||
properties.setProperty(TIMEOUT_NODE_SUSPENDED, defaultTimeout);
|
||||
properties.put(RESOURCE_GROUP_NAME, "jc");
|
||||
properties.put(PROPERTY_REGIONS, "eastus");
|
||||
properties.put(IMAGE_PUBLISHERS, "Canonical");
|
||||
|
||||
AzureLiveTestUtils.defaultProperties(properties);
|
||||
checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint");
|
||||
|
||||
setIfTestSystemPropertyPresent(properties, "oauth.endpoint");
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
*/
|
||||
package org.jclouds.azurecompute.arm.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
@ -58,11 +56,8 @@ public class AzureTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
|
|||
@Override
|
||||
protected Properties setupProperties() {
|
||||
Properties properties = super.setupProperties();
|
||||
properties.put(RESOURCE_GROUP_NAME, "jc");
|
||||
|
||||
AzureLiveTestUtils.defaultProperties(properties);
|
||||
checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint");
|
||||
|
||||
setIfTestSystemPropertyPresent(properties, "oauth.endpoint");
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
@ -71,7 +66,8 @@ public class AzureTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
|
|||
public void testDefaultTemplateBuilder() throws IOException {
|
||||
Template defaultTemplate = view.getComputeService().templateBuilder().build();
|
||||
assertTrue(defaultTemplate.getImage().getOperatingSystem().getVersion().matches("1[45]\\.[01][04]\\.[0-9]-LTS"),
|
||||
"Version mismatch, expected dd.dd.d-LTS, found: " + defaultTemplate.getImage().getOperatingSystem().getVersion());
|
||||
"Version mismatch, expected dd.dd.d-LTS, found: "
|
||||
+ defaultTemplate.getImage().getOperatingSystem().getVersion());
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
||||
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
||||
|
|
|
@ -16,20 +16,10 @@
|
|||
*/
|
||||
package org.jclouds.azurecompute.arm.compute.extensions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_PORT_OPEN;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE;
|
||||
import static org.jclouds.compute.options.TemplateOptions.Builder.authorizePublicKey;
|
||||
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata;
|
||||
import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils;
|
||||
|
@ -63,19 +53,8 @@ public class AzureComputeImageExtensionLiveTest extends BaseImageExtensionLiveTe
|
|||
@Override
|
||||
protected Properties setupProperties() {
|
||||
Properties properties = super.setupProperties();
|
||||
String defaultTimeout = String.valueOf(TimeUnit.MILLISECONDS.convert(60, TimeUnit.MINUTES));
|
||||
properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, defaultTimeout);
|
||||
properties.setProperty(TIMEOUT_NODE_RUNNING, defaultTimeout);
|
||||
properties.setProperty(TIMEOUT_PORT_OPEN, defaultTimeout);
|
||||
properties.setProperty(TIMEOUT_NODE_TERMINATED, defaultTimeout);
|
||||
properties.setProperty(TIMEOUT_NODE_SUSPENDED, defaultTimeout);
|
||||
properties.put(RESOURCE_GROUP_NAME, "jc");
|
||||
properties.put(PROPERTY_REGIONS, "eastus");
|
||||
properties.put(IMAGE_PUBLISHERS, "Canonical");
|
||||
|
||||
AzureLiveTestUtils.defaultProperties(properties);
|
||||
checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint");
|
||||
|
||||
setIfTestSystemPropertyPresent(properties, "oauth.endpoint");
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,21 +16,34 @@
|
|||
*/
|
||||
package org.jclouds.azurecompute.arm.internal;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_PORT_OPEN;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE;
|
||||
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
|
||||
import static org.jclouds.oauth.v2.config.CredentialType.CLIENT_CREDENTIALS_SECRET;
|
||||
import static org.jclouds.oauth.v2.config.OAuthProperties.CREDENTIAL_TYPE;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class AzureLiveTestUtils {
|
||||
|
||||
public static Properties defaultProperties(Properties properties) {
|
||||
properties = properties == null ? new Properties() : properties;
|
||||
properties.put("oauth.identity", "foo");
|
||||
properties.put("oauth.credential", "password");
|
||||
properties.put("oauth.endpoint", "https://login.microsoftonline.com/oauth2/token");
|
||||
properties.put(CREDENTIAL_TYPE, CLIENT_CREDENTIALS_SECRET.toString());
|
||||
properties.put(PROPERTY_REGIONS, "northeurope");
|
||||
properties.put(PROPERTY_REGIONS, "eastus");
|
||||
properties.put(IMAGE_PUBLISHERS, "Canonical");
|
||||
|
||||
String defaultTimeout = String.valueOf(TimeUnit.MILLISECONDS.convert(60, TimeUnit.MINUTES));
|
||||
properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, defaultTimeout);
|
||||
properties.setProperty(TIMEOUT_NODE_RUNNING, defaultTimeout);
|
||||
properties.setProperty(TIMEOUT_PORT_OPEN, defaultTimeout);
|
||||
properties.setProperty(TIMEOUT_NODE_TERMINATED, defaultTimeout);
|
||||
properties.setProperty(TIMEOUT_NODE_SUSPENDED, defaultTimeout);
|
||||
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue