You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ga...@apache.org on 2021/06/29 23:37:40 UTC
[jclouds] branch master updated: JCLOUDS-1577 - Allow to provide
Azure Plan Information when starting custom image based on Azure
Marketplace image.
This is an automated email from the ASF dual-hosted git repository.
gaul pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jclouds.git
The following commit(s) were added to refs/heads/master by this push:
new 261f9d1 JCLOUDS-1577 - Allow to provide Azure Plan Information when starting custom image based on Azure Marketplace image.
261f9d1 is described below
commit 261f9d1fd5c190e9c11a9d65968693cee3df4008
Author: Miroslav Novak <mn...@redhat.com>
AuthorDate: Fri May 7 15:20:19 2021 +0200
JCLOUDS-1577 - Allow to provide Azure Plan Information when starting custom image based on Azure Marketplace image.
---
.../arm/compute/AzureComputeServiceAdapter.java | 4 +-
.../arm/compute/functions/VMImageToImage.java | 43 +++++++++++--
.../arm/compute/options/AzureTemplateOptions.java | 70 +++++++++++++++++++++-
3 files changed, 109 insertions(+), 8 deletions(-)
diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
index 6a21609..fbb1d74 100644
--- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
+++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
@@ -25,7 +25,7 @@ import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Lists.newArrayList;
import static org.jclouds.azurecompute.arm.compute.domain.LocationAndName.fromSlashEncoded;
import static org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName.fromResourceGroupAndName;
-import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.getMarketplacePlanFromImageMetadata;
+import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.createMarketplacePlanIfPresent;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
import static org.jclouds.azurecompute.arm.domain.IdReference.extractName;
import static org.jclouds.azurecompute.arm.domain.IdReference.extractResourceGroup;
@@ -171,7 +171,7 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
// custom names in the configured group
templateOptions.getUserMetadata().put(GROUP_KEY, group);
Map<String, String> metadataAndTags = metadataAndTagsAsCommaDelimitedValue(templateOptions);
- Plan plan = getMarketplacePlanFromImageMetadata(image);
+ Plan plan = createMarketplacePlanIfPresent(image, templateOptions);
VirtualMachine virtualMachine = api.getVirtualMachineApi(resourceGroupName).createOrUpdate(name, locationName,
virtualMachineProperties, metadataAndTags, plan);
diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java
index 028ad9c..e335c76 100644
--- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java
+++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java
@@ -25,6 +25,7 @@ import java.util.Map;
import java.util.Set;
import org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension;
+import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
import org.jclouds.azurecompute.arm.domain.Plan;
import org.jclouds.azurecompute.arm.domain.VMImage;
import org.jclouds.collect.Memoized;
@@ -39,6 +40,7 @@ import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
+import com.google.common.base.Strings;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Inject;
@@ -101,12 +103,45 @@ public class VMImageToImage implements Function<VMImage, Image> {
plan.product()));
}
}
-
+
+ /**
+ * In case that image is offered from Azure Marketplace then it requires to provide "Plan Information" (publisher/name/product)
+ * when creating VM from such an image. This method first tries to get this information from image but also allows to
+ * override those values by information passed in Azure template options (@see AzureTemplateOptions).
+ *
+ * In case there is used custom image which was created from Marketplace image then plan information is missing as this image
+ * cannot be referenced in format "location/publisher/offer/sku" from which Plan Information is normally parsed.
+ * In this case user can provide plan information (planPublisher/planName/planProduct) in template otherwise VM creation fails with error.
+ * It's allowed to override any of the original "image" plan information but only if those were present.
+ *
+ * @param image image
+ * @param templateOptions Azure template options
+ * @return Plan Information (publisher, plan name, product) or null if any of publisher/name/product not defined
+ */
@Nullable
- public static Plan getMarketplacePlanFromImageMetadata(Image image) {
+ public static Plan createMarketplacePlanIfPresent(Image image, AzureTemplateOptions templateOptions) {
Map<String, String> imageMetadata = image.getUserMetadata();
- return imageMetadata.containsKey("product") ? Plan.create(imageMetadata.get("publisher"),
- imageMetadata.get("name"), imageMetadata.get("product")) : null;
+
+ String planPublisher = getFirstNonEmptyOrReturnNull(templateOptions.getPlanPublisher(), imageMetadata.get("publisher"));
+ String planName = getFirstNonEmptyOrReturnNull(templateOptions.getPlanName(), imageMetadata.get("name"));
+ String planProduct = getFirstNonEmptyOrReturnNull(templateOptions.getPlanProduct(), imageMetadata.get("product"));
+
+ if (Strings.isNullOrEmpty(planPublisher) || Strings.isNullOrEmpty(planName) || Strings.isNullOrEmpty(planProduct)) {
+ return null;
+ } else {
+ return Plan.create(planPublisher, planName, planProduct);
+ }
+ }
+
+ @Nullable
+ private static String getFirstNonEmptyOrReturnNull(String first, String second) {
+ if (!Strings.isNullOrEmpty(first)) {
+ return first;
+ } else if (!Strings.isNullOrEmpty(second)) {
+ return second;
+ } else {
+ return null;
+ }
}
public static Function<VMImage, OperatingSystem.Builder> osFamily() {
diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java
index e6c3a03..ece527c 100644
--- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java
+++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java
@@ -45,6 +45,9 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
private List<Secrets> secrets = ImmutableList.of();
private String customData;
private StorageAccountType osDiskStorageType = StorageAccountType.STANDARD_LRS;
+ private String planPublisher;
+ private String planName;
+ private String planProduct;
/**
* Sets the availability set where the nodes will be configured. If it does
@@ -145,6 +148,21 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
return this;
}
+ public AzureTemplateOptions planPublisher(String planPublisher) {
+ this.planPublisher = planPublisher;
+ return this;
+ }
+
+ public AzureTemplateOptions planName(String planName) {
+ this.planName = planName;
+ return this;
+ }
+
+ public AzureTemplateOptions planProduct(String planProduct) {
+ this.planProduct = planProduct;
+ return this;
+ }
+
public AvailabilitySet getAvailabilitySet() {
return availabilitySet;
}
@@ -181,6 +199,18 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
return osDiskStorageType;
}
+ public String getPlanPublisher() {
+ return planPublisher;
+ }
+
+ public String getPlanName() {
+ return planName;
+ }
+
+ public String getPlanProduct() {
+ return planProduct;
+ }
+
@Override
public AzureTemplateOptions clone() {
AzureTemplateOptions options = new AzureTemplateOptions();
@@ -202,6 +232,9 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
eTo.secrets(secrets);
eTo.customData(customData);
eTo.osDiskStorageType(osDiskStorageType);
+ eTo.planPublisher(planPublisher);
+ eTo.planName(planName);
+ eTo.planProduct(planProduct);
}
}
@@ -220,13 +253,16 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
&& Objects.equal(resourceGroup, that.resourceGroup) && Objects.equal(availabilitySet, that.availabilitySet)
&& Objects.equal(dataDisks, that.dataDisks) && Objects.equal(ipOptions, that.ipOptions)
&& Objects.equal(windowsConfiguration, that.windowsConfiguration) && Objects.equal(secrets, that.secrets)
- && Objects.equal(this.customData, that.customData);
+ && Objects.equal(this.customData, that.customData)
+ && Objects.equal(this.planPublisher, that.planPublisher)
+ && Objects.equal(this.planName, that.planName)
+ && Objects.equal(this.planProduct, that.planProduct);
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), availabilitySet, availabilitySetName, dataDisks, resourceGroup,
- ipOptions, customData);
+ ipOptions, customData, planPublisher, planName, planProduct);
}
@Override
@@ -248,6 +284,12 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
toString.add("secrets", secrets);
if (customData != null)
toString.add("customData", customData);
+ if (planPublisher != null)
+ toString.add("publisher", planPublisher);
+ if (planName != null)
+ toString.add("planName", planName);
+ if (planProduct != null)
+ toString.add("planProduct", planProduct);
return toString;
}
@@ -340,5 +382,29 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
AzureTemplateOptions options = new AzureTemplateOptions();
return options.osDiskStorageType(osDiskStorageType);
}
+
+ /**
+ * @see AzureTemplateOptions#planPublisher(String)
+ */
+ public static AzureTemplateOptions planPublisher(String planPublisher) {
+ AzureTemplateOptions options = new AzureTemplateOptions();
+ return options.planPublisher(planPublisher);
+ }
+
+ /**
+ * @see AzureTemplateOptions#planName(String)
+ */
+ public static AzureTemplateOptions planName(String planName) {
+ AzureTemplateOptions options = new AzureTemplateOptions();
+ return options.planName(planName);
+ }
+
+ /**
+ * @see AzureTemplateOptions#planProduct(String)
+ */
+ public static AzureTemplateOptions planProduct(String planProduct) {
+ AzureTemplateOptions options = new AzureTemplateOptions();
+ return options.planProduct(planProduct);
+ }
}
}