diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/ComputeRoles.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/ComputeRoles.java new file mode 100644 index 000000000000..166bdd1026a0 --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/ComputeRoles.java @@ -0,0 +1,46 @@ +package com.microsoft.azure.management.compute; + + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Defines values for ComputeRoles. + */ +public enum ComputeRoles { + /** Enum value PaaS. */ + PAAS("PaaS"), + + /** Enum value IaaS. */ + IAAS("IaaS"); + + /** The actual serialized value for a ComputeRoles instance. */ + private String value; + + ComputeRoles(String value) { + this.value = value; + } + + /** + * Parses a serialized value to a ComputeRoles instance. + * + * @param value the serialized value to parse. + * @return the parsed ComputeRoles object, or null if unable to parse. + */ + @JsonCreator + public static ComputeRoles fromString(String value) { + ComputeRoles[] items = ComputeRoles.values(); + for (ComputeRoles item : items) { + if (item.toString().equalsIgnoreCase(value)) { + return item; + } + } + return null; + } + + @JsonValue + @Override + public String toString() { + return this.value; + } +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/ExternalChildResource.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/ExternalChildResource.java new file mode 100644 index 000000000000..79cff6570e79 --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/ExternalChildResource.java @@ -0,0 +1,16 @@ +package com.microsoft.azure.management.compute; + +import com.microsoft.azure.management.resources.fluentcore.arm.models.ChildResource; +import com.microsoft.azure.management.resources.fluentcore.model.Refreshable; + +/** + * Represents an external child resource. + * + * @param fluent type of the external child resource + */ +public interface ExternalChildResource extends ChildResource, Refreshable { + /** + * @return the id of the external child resource + */ + String id(); +} diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachine.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachine.java index 9ea70cfc3833..3f3e7e4d7c33 100644 --- a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachine.java +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachine.java @@ -3,7 +3,6 @@ import com.microsoft.azure.CloudException; import com.microsoft.azure.PagedList; import com.microsoft.azure.management.compute.implementation.VirtualMachineInner; -import com.microsoft.azure.management.compute.implementation.VirtualMachineExtensionInner; import com.microsoft.azure.management.network.Network; import com.microsoft.azure.management.network.NetworkInterface; import com.microsoft.azure.management.network.PublicIpAddress; @@ -19,6 +18,7 @@ import java.io.IOException; import java.util.List; +import java.util.Map; /** * An immutable client-side representation of an Azure virtual machine. @@ -192,9 +192,9 @@ public interface VirtualMachine extends String licenseType(); /** - * @return the resources value + * @return the extensions attached to the Azure Virtual Machine */ - List resources(); + Map extensions(); /** * @return the plan value @@ -812,6 +812,19 @@ interface WithSecondaryNetworkInterface { WithCreate withExistingSecondaryNetworkInterface(NetworkInterface networkInterface); } + /** + * The stage of the virtual machine definition allowing to specify extensions. + */ + interface WithExtension { + /** + * Specifies definition of an extension to be attached to the virtual machine. + * + * @param name the reference name for the extension + * @return the stage representing configuration for the extension + */ + VirtualMachineExtension.DefinitionStages.Blank defineNewExtension(String name); + } + /** * The stage of the definition which contains all the minimum required inputs for * the resource to be created (via {@link WithCreate#create()}), but also allows @@ -826,7 +839,8 @@ interface WithCreate extends DefinitionStages.WithStorageAccount, DefinitionStages.WithDataDisk, DefinitionStages.WithAvailabilitySet, - DefinitionStages.WithSecondaryNetworkInterface { + DefinitionStages.WithSecondaryNetworkInterface, + DefinitionStages.WithExtension { } } @@ -936,6 +950,37 @@ interface WithSecondaryNetworkInterface { */ Update withoutSecondaryNetworkInterface(String name); } + + /** + * The stage of the virtual machine definition allowing to specify extensions. + */ + interface WithExtension { + /** + * Specifies definition of an extension to be attached to the virtual machine. + * + * @param name the reference name for the extension + * @return the stage representing configuration for the extension + */ + VirtualMachineExtension + .UpdateDefinitionStages + .Blank defineNewExtension(String name); + + /** + * Begins the description of an update of an existing extension of this virtual machine. + * + * @param name the reference name for the extension + * @return the stage representing updatable VM definition + */ + VirtualMachineExtension.Update updateExtension(String name); + + /** + * Detaches an extension with the given name from the virtual machine. + * + * @param name the reference name for the extension to be removed/uninstalled + * @return the stage representing updatable VM definition + */ + Update withoutExtension(String name); + } } /** @@ -948,7 +993,8 @@ interface Update extends Appliable, Resource.UpdateWithTags, UpdateStages.WithDataDisk, - UpdateStages.WithSecondaryNetworkInterface { + UpdateStages.WithSecondaryNetworkInterface, + UpdateStages.WithExtension { /** * Specifies the caching type for the Operating System disk. * @@ -981,4 +1027,4 @@ interface Update extends */ Update withSize(VirtualMachineSizeTypes size); } -} +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtension.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtension.java new file mode 100644 index 000000000000..785562020270 --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtension.java @@ -0,0 +1,546 @@ +package com.microsoft.azure.management.compute; + +import com.microsoft.azure.management.compute.implementation.VirtualMachineExtensionInner; +import com.microsoft.azure.management.resources.fluentcore.model.Attachable; +import com.microsoft.azure.management.resources.fluentcore.model.Settable; +import com.microsoft.azure.management.resources.fluentcore.model.Wrapper; + +import java.util.HashMap; +import java.util.Map; + +/** + * An immutable client-side representation of an Azure virtual machine extension. + * An extension associated with a virtual machine will be created from a {@link VirtualMachineExtensionImage }. + */ +public interface VirtualMachineExtension extends + ExternalChildResource, + Wrapper { + /** + * @return the publisher name of the virtual machine extension image this extension is created from + */ + String publisherName(); + + /** + * @return the type name of the virtual machine extension image this extension is created from + */ + String typeName(); + + /** + * @return the version name of the virtual machine extension image this extension is created from + */ + String versionName(); + + /** + * @return true if this extension is configured to upgrade automatically when a new minor version of + * virtual machine extension image that this extension based on is published + */ + boolean autoUpgradeMinorVersionEnabled(); + + /** + * @return the public settings of the virtual machine extension as key value pairs + */ + Map publicSettings(); + + /** + * @return the public settings of the virtual machine extension as a json string + */ + String publicSettingsAsJsonString(); + + /** + * @return the instance view of this virtual machine extension + */ + VirtualMachineExtensionInstanceView instanceView(); + + /** + * @return the tags for this virtual machine extension + */ + Map tags(); + + /** + * @return the provisioning state of this virtual machine extension + */ + String provisioningState(); + + /** + * Grouping of virtual machine extension definition stages as a part of parent virtual machine definition. + */ + interface DefinitionStages { + /** + * The first stage of a virtual machine extension definition. + * + * @param the return type of the final {@link WithAttach#attach()} + */ + interface Blank + extends WithImageOrPublisher { + } + + /** + * The stage of the virtual machine extension definition allowing to specify extension image or specify name of + * the virtual machine extension publisher. + * + * @param the return type of {@link WithAttach#attach()} + */ + interface WithImageOrPublisher + extends WithPublisher { + /** + * Specifies the virtual machine extension image to use. + * + * @param image the image + * @return the next stage of the definition + */ + WithAttach withImage(VirtualMachineExtensionImage image); + } + + /** + * The stage of the virtual machine extension definition allowing to specify the publisher of the + * virtual machine extension image this extension is based on. + * + * @param the return type of {@link WithAttach#attach()} + */ + interface WithPublisher { + /** + * Specifies the name of the virtual machine extension image publisher. + * + * @param extensionImagePublisherName the publisher name + * @return the next stage of the definition + */ + WithType withPublisher(String extensionImagePublisherName); + } + + /** + * The stage of the virtual machine extension definition allowing to specify the type of the virtual machine + * extension image this extension is based on. + * + * @param the return type of {@link WithAttach#attach()} + */ + interface WithType { + /** + * Specifies the type of the virtual machine extension image. + * + * @param extensionImageTypeName the image type name + * @return the next stage of the definition + */ + WithVersion withType(String extensionImageTypeName); + } + + /** + * The stage of the virtual machine extension definition allowing to specify the type of the virtual machine + * extension version this extension is based on. + * + * @param the return type of {@link WithAttach#attach()} + */ + interface WithVersion { + /** + * Specifies the version of the virtual machine image extension. + * + * @param extensionImageVersionName the version name + * @return the next stage of the definition + */ + WithAttach withVersion(String extensionImageVersionName); + } + + /** The final stage of the virtual machine extension definition. + *

+ * At this stage, any remaining optional settings can be specified, or the virtual machine extension definition + * can be attached to the parent virtual machine definition using {@link VirtualMachineExtension.DefinitionStages.WithAttach#attach()}. + * @param the return type of {@link VirtualMachineExtension.DefinitionStages.WithAttach#attach()} + */ + interface WithAttach extends + Attachable.InDefinition, + WithAutoUpgradeMinorVersion, + WithSettings, + WithTags { + } + + /** + * The stage of the virtual machine extension definition allowing to enable or disable auto upgrade of the + * extension when when a new minor version of virtual machine extension image gets published. + * + * @param the return type of {@link WithAttach#attach()} + */ + interface WithAutoUpgradeMinorVersion { + /** + * enables auto upgrade of the extension. + * + * @return the next stage of the definition + */ + WithAttach withAutoUpgradeMinorVersionEnabled(); + + /** + * disables auto upgrade of the extension. + * + * @return the next stage of the definition + */ + WithAttach withAutoUpgradeMinorVersionDisabled(); + } + + /** + * The stage of the virtual machine extension definition allowing to specify the public and private settings. + * + * @param the return type of {@link WithAttach#attach()} + */ + interface WithSettings { + /** + * Specifies a public settings entry. + * + * @param key the key of a public settings entry + * @param value the value of the public settings entry + * @return the next stage of the definition + */ + WithAttach withPublicSetting(String key, Object value); + + /** + * Specifies a private settings entry. + * + * @param key the key of a private settings entry + * @param value the value of the private settings entry + * @return the next stage of the definition + */ + WithAttach withProtectedSetting(String key, Object value); + + /** + * Specifies public settings. + * + * @param settings the public settings + * @return the next stage of the definition + */ + WithAttach withPublicSettings(HashMap settings); + + /** + * Specifies private settings. + * + * @param settings the private settings + * @return the next stage of the definition + */ + WithAttach withProtectedSettings(HashMap settings); + } + + /** + * The stage of the virtual machine extension definition allowing to specify the tags. + * + * @param the return type of {@link WithAttach#attach()} + */ + interface WithTags { + /** + * Specifies tags for the virtual machine extension as a {@link Map}. + * @param tags a {@link Map} of tags + * @return the next stage of the definition + */ + WithAttach withTags(Map tags); + + /** + * Adds a tag to the virtual machine extension. + * @param key the key for the tag + * @param value the value for the tag + * @return the next stage of the definition + */ + WithAttach withTag(String key, String value); + } + } + + /** + * The entirety of a virtual machine extension definition as a part of parent definition. + * + * @param the return type of the final {@link Attachable#attach()} + */ + interface Definition extends + DefinitionStages.Blank, + DefinitionStages.WithImageOrPublisher, + DefinitionStages.WithPublisher, + DefinitionStages.WithType, + DefinitionStages.WithVersion, + DefinitionStages.WithAttach { + } + + /** + * Grouping of virtual machine extension definition stages as part of parent virtual machine update. + */ + interface UpdateDefinitionStages { + /** + * The first stage of a virtual machine extension definition. + * + * @param the return type of the final {@link WithAttach#attach()} + */ + interface Blank + extends WithImageOrPublisher { + } + + /** + * The stage of the virtual machine extension allowing to specify extension image or specify name of the + * virtual machine extension publisher. + * + * @param the return type of {@link WithAttach#attach()} + */ + interface WithImageOrPublisher + extends WithPublisher { + /** + * Specifies the virtual machine extension image to use. + * + * @param image the image + * @return the next stage of the definition + */ + WithAttach withImage(VirtualMachineExtensionImage image); + } + + /** + * The stage of the virtual machine extension definition allowing to specify the publisher of the + * virtual machine extension image this extension is based on. + * + * @param the return type of {@link WithAttach#attach()} + */ + interface WithPublisher { + /** + * Specifies the name of the virtual machine extension image publisher. + * + * @param extensionImagePublisherName the publisher name + * @return the next stage of the definition + */ + WithType withPublisher(String extensionImagePublisherName); + } + + /** + * The stage of the virtual machine extension definition allowing to specify the type of the virtual machine + * extension image this extension is based on. + * + * @param the return type of {@link WithAttach#attach()} + */ + interface WithType { + /** + * Specifies the type of the virtual machine extension image. + * + * @param extensionImageTypeName the image type name + * @return the next stage of the definition + */ + WithVersion withType(String extensionImageTypeName); + } + + /** + * The stage of the virtual machine extension definition allowing to specify the type of the virtual machine + * extension version this extension is based on. + * + * @param the return type of {@link WithAttach#attach()} + */ + interface WithVersion { + /** + * Specifies the version of the virtual machine image extension. + * + * @param extensionImageVersionName the version name + * @return the next stage of the definition + */ + WithAttach withVersion(String extensionImageVersionName); + } + + /** The final stage of the virtual machine extension definition. + *

+ * At this stage, any remaining optional settings can be specified, or the virtual machine extension definition + * can be attached to the parent virtual machine definition using {@link VirtualMachineExtension.UpdateDefinitionStages.WithAttach#attach()}. + * @param the return type of {@link VirtualMachineExtension.UpdateDefinitionStages.WithAttach#attach()} + */ + interface WithAttach extends + Attachable.InUpdate, + WithAutoUpgradeMinorVersion, + WithSettings, + WithTags { + } + + /** + * The stage of the virtual machine extension definition allowing to enable or disable auto upgrade of the + * extension when when a new minor version of virtual machine extension image gets published. + * + * @param the return type of {@link WithAttach#attach()} + */ + interface WithAutoUpgradeMinorVersion { + /** + * enables auto upgrade of the extension. + * + * @return the next stage of the definition + */ + WithAttach withAutoUpgradeMinorVersionEnabled(); + + /** + * disables auto upgrade of the extension. + * + * @return the next stage of the definition + */ + WithAttach withAutoUpgradeMinorVersionDisabled(); + } + + /** + * The stage of the virtual machine extension definition allowing to specify the public and private settings. + * + * @param the return type of {@link WithAttach#attach()} + */ + interface WithSettings { + /** + * Specifies a public settings entry. + * + * @param key the key of a public settings entry + * @param value the value of the public settings entry + * @return the next stage of the definition + */ + WithAttach withPublicSetting(String key, Object value); + + /** + * Specifies a private settings entry. + * + * @param key the key of a private settings entry + * @param value the value of the private settings entry + * @return the next stage of the definition + */ + WithAttach withProtectedSetting(String key, Object value); + + /** + * Specifies public settings. + * + * @param settings the public settings + * @return the next stage of the definition + */ + WithAttach withPublicSettings(HashMap settings); + + /** + * Specifies private settings. + * + * @param settings the private settings + * @return the next stage of the definition + */ + WithAttach withProtectedSettings(HashMap settings); + } + + /** + * The stage of the virtual machine extension definition allowing to specify the tags. + * + * @param the return type of {@link WithAttach#attach()} + */ + interface WithTags { + /** + * Specifies tags for the resource as a {@link Map}. + * @param tags a {@link Map} of tags + * @return the next stage of the resource definition + */ + WithAttach withTags(Map tags); + + /** + * Adds a tag to the resource. + * @param key the key for the tag + * @param value the value for the tag + * @return the next stage of the resource definition + */ + WithAttach withTag(String key, String value); + } + } + + /** + * The entirety of a virtual machine extension definition as a part of parent update. + * @param the return type of the final {@link Attachable#attach()} + */ + interface UpdateDefinition extends + UpdateDefinitionStages.Blank, + UpdateDefinitionStages.WithImageOrPublisher, + UpdateDefinitionStages.WithPublisher, + UpdateDefinitionStages.WithType, + UpdateDefinitionStages.WithVersion, + UpdateDefinitionStages.WithAttach { + } + + /** + * Grouping of virtual machine extension update stages. + */ + interface UpdateStages { + /** + * The stage of the virtual machine extension update allowing to enable or disable auto upgrade of the + * extension when when a new minor version of virtual machine extension image gets published. + */ + interface WithAutoUpgradeMinorVersion { + /** + * enables auto upgrade of the extension. + * + * @return the next stage of the update + */ + Update withAutoUpgradeMinorVersionEnabled(); + + /** + * enables auto upgrade of the extension. + * + * @return the next stage of the update + */ + Update withAutoUpgradeMinorVersionDisabled(); + } + + /** + * The stage of the virtual machine extension update allowing to add or update public and private settings. + */ + interface WithSettings { + /** + * Specifies a public settings entry. + * + * @param key the key of a public settings entry + * @param value the value of the public settings entry + * @return the next stage of the update + */ + Update withPublicSetting(String key, Object value); + + /** + * Specifies a private settings entry. + * + * @param key the key of a private settings entry + * @param value the value of the private settings entry + * @return the next stage of the update + */ + Update withProtectedSetting(String key, Object value); + + /** + * Specifies public settings. + * + * @param settings the public settings + * @return the next stage of the update + */ + Update withPublicSettings(HashMap settings); + + /** + * Specifies private settings. + * + * @param settings the private settings + * @return the next stage of the update + */ + Update withProtectedSettings(HashMap settings); + } + + /** + * The stage of the virtual machine extension update allowing to add or update tags. + */ + interface WithTags { + /** + * Specifies tags for the virtual machine extension as a {@link Map}. + * @param tags a {@link Map} of tags + * @return the next stage of the update + */ + Update withTags(Map tags); + + /** + * Adds a tag to the virtual machine extension. + * @param key the key for the tag + * @param value the value for the tag + * @return the next stage of the update + */ + Update withTag(String key, String value); + + /** + * Removes a tag from the virtual machine extension. + * @param key the key of the tag to remove + * @return the next stage of the update + */ + Update withoutTag(String key); + } + } + + /** + * The entirety of virtual machine extension update as a part of parent virtual machine update. + */ + interface Update extends + Settable, + UpdateStages.WithAutoUpgradeMinorVersion, + UpdateStages.WithSettings, + UpdateStages.WithTags { + + } +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImage.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImage.java new file mode 100644 index 000000000000..6cf667ebaaff --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImage.java @@ -0,0 +1,72 @@ +package com.microsoft.azure.management.compute; + +import com.microsoft.azure.management.compute.implementation.VirtualMachineExtensionImageInner; +import com.microsoft.azure.management.resources.fluentcore.model.Wrapper; + +/** + * An immutable client-side representation of an Azure virtual machine extension image. + *

+ * Note: Azure virtual machine extension image is also referred as virtual machine extension handler. + */ +public interface VirtualMachineExtensionImage extends + Wrapper { + /** + * @return the resource ID of the extension image + */ + String id(); + + /** + * @return the region in which virtual machine extension image is available + */ + String regionName(); + + /** + * @return the name of the publisher of the virtual machine extension image + */ + String publisherName(); + + /** + * @return the name of the virtual machine extension image type this image belongs to + */ + String typeName(); + + /** + * @return the name of the virtual machine extension image version this image represents + */ + String versionName(); + + /** + * @return the operating system this virtual machine extension image supports + */ + OperatingSystemTypes osType(); + + /** + * @return the type of role this virtual machine extension image supports + */ + ComputeRoles computeRole(); + + /** + * @return the schema defined by publisher, where extension consumers should provide settings in a matching schema + *

+ * Note this field will be null since server provide null for them + */ + String handlerSchema(); + + /** + * @return true if the extension can be used on xRP Virtual Machine ScaleSets. + *

+ * Note by default existing extensions are usable on scale sets, but there might be cases where a publisher wants to + * explicitly indicate the extension is only enabled for Compute Resource Provider VMs but not Virtual Machine ScaleSets. + */ + boolean vmScaleSetEnabled(); + + /** + * @return true if the handler can support multiple extensions. + */ + boolean supportsMultipleExtensions(); + + /** + * @return the virtual machine extension image version this image belongs to + */ + VirtualMachineExtensionImageVersion version(); +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImageType.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImageType.java new file mode 100644 index 000000000000..6b6544d94e45 --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImageType.java @@ -0,0 +1,36 @@ +package com.microsoft.azure.management.compute; + +import com.microsoft.azure.management.compute.implementation.VirtualMachineExtensionImageInner; +import com.microsoft.azure.management.resources.fluentcore.model.Wrapper; + +/** + * An immutable client-side representation of an Azure virtual machine extension image type. + */ +public interface VirtualMachineExtensionImageType extends + Wrapper { + /** + * @return the resource ID of the virtual machine extension image type + */ + String id(); + + /** + * @return the name of the virtual machine extension image type + */ + String name(); + + /** + * @return the region in which virtual machine extension image type is available + */ + String regionName(); + + /** + * @return the publisher of this virtual machine extension image type + */ + VirtualMachinePublisher publisher(); + + /** + * @return Virtual machine image extension versions available in this type + */ + VirtualMachineExtensionImageVersions versions(); +} + diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImageTypes.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImageTypes.java new file mode 100644 index 000000000000..00b9f10d46af --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImageTypes.java @@ -0,0 +1,9 @@ +package com.microsoft.azure.management.compute; + +import com.microsoft.azure.management.resources.fluentcore.collection.SupportsListing; + +/** + * Entry point to virtual machine image extension types. + */ +public interface VirtualMachineExtensionImageTypes extends SupportsListing { +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImageVersion.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImageVersion.java new file mode 100644 index 000000000000..07f4deba96b7 --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImageVersion.java @@ -0,0 +1,41 @@ +package com.microsoft.azure.management.compute; + +import com.microsoft.azure.CloudException; +import com.microsoft.azure.management.compute.implementation.VirtualMachineExtensionImageInner; +import com.microsoft.azure.management.resources.fluentcore.model.Wrapper; + +import java.io.IOException; + +/** + * An immutable client-side representation of an Azure virtual machine extension image version. + */ +public interface VirtualMachineExtensionImageVersion extends + Wrapper { + /** + * @return the resource ID of the extension image version + */ + String id(); + + /** + * @return the name of the virtual machine extension image version + */ + String name(); + + /** + * @return the region in which virtual machine extension image version is available + */ + String regionName(); + + /** + * @return the virtual machine extension image type this version belongs to + */ + VirtualMachineExtensionImageType type(); + + /** + * @return virtual machine extension image this version represents + * + * @throws CloudException thrown for an invalid response from the service + * @throws IOException exception thrown from serialization/deserialization + */ + VirtualMachineExtensionImage image() throws CloudException, IOException; +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImageVersions.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImageVersions.java new file mode 100644 index 000000000000..ba4c300fcc5d --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImageVersions.java @@ -0,0 +1,9 @@ +package com.microsoft.azure.management.compute; + +import com.microsoft.azure.management.resources.fluentcore.collection.SupportsListing; + +/** + * Entry point to virtual machine image extension versions. + */ +public interface VirtualMachineExtensionImageVersions extends SupportsListing { +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImages.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImages.java new file mode 100644 index 000000000000..a6a80ea663fb --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImages.java @@ -0,0 +1,13 @@ +package com.microsoft.azure.management.compute; + +import com.microsoft.azure.management.resources.fluentcore.collection.SupportsListingByRegion; + +/** + * Entry point to virtual machine extension image management API. + */ +public interface VirtualMachineExtensionImages extends SupportsListingByRegion { + /** + * @return entry point to virtual machine extension image publishers + */ + VirtualMachinePublishers publishers(); +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineImages.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineImages.java index 660065907b66..7f0fd764c314 100644 --- a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineImages.java +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachineImages.java @@ -5,10 +5,6 @@ */ package com.microsoft.azure.management.compute; -import java.io.IOException; -import com.microsoft.azure.CloudException; -import com.microsoft.azure.PagedList; -import com.microsoft.azure.management.resources.fluentcore.arm.Region; import com.microsoft.azure.management.resources.fluentcore.collection.SupportsListingByRegion; /** @@ -20,26 +16,4 @@ public interface VirtualMachineImages extends * @return entry point to virtual machine image publishers */ VirtualMachinePublishers publishers(); - - /** - * Lists all the virtual machine images available in a given region. - *

- * Note this is a very long running call, as it enumerates through all publishers, offers and skus. - * @return list of virtual machine images - * @param regionName the name of the region as used internally by Azure - * @throws CloudException exceptions thrown from the cloud - * @throws IOException exceptions thrown from serialization/deserialization - */ - PagedList listByRegion(String regionName) throws CloudException, IOException; - - /** - * Lists all the virtual machine images available in a given region. - *

- * Note this is a very long running call, as it enumerates through all publishers, offers and skus. - * @return list of virtual machine images - * @param region the region to list the images from - * @throws CloudException exceptions thrown from the cloud - * @throws IOException exceptions thrown from serialization/deserialization - */ - PagedList listByRegion(Region region) throws CloudException, IOException; } diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachinePublisher.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachinePublisher.java index 99addcb673d8..f9d84263e672 100644 --- a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachinePublisher.java +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/VirtualMachinePublisher.java @@ -25,4 +25,9 @@ public interface VirtualMachinePublisher { * @return the offers from this publisher */ VirtualMachineOffers offers(); + + /** + * @return the virtual machine image extensions from this publisher. + */ + VirtualMachineExtensionImageTypes extensionTypes(); } \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/ComputeManager.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/ComputeManager.java index 312aa8c9d05e..50744531ae9a 100644 --- a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/ComputeManager.java +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/ComputeManager.java @@ -2,6 +2,7 @@ import com.microsoft.azure.AzureEnvironment; import com.microsoft.azure.management.compute.AvailabilitySets; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImages; import com.microsoft.azure.management.compute.VirtualMachineImages; import com.microsoft.azure.management.compute.VirtualMachines; import com.microsoft.azure.management.network.implementation.NetworkManager; @@ -23,6 +24,7 @@ public final class ComputeManager extends Manager the fluent model type of the child resource + * @param Azure inner resource class type representing the child resource + * @param the parent Azure resource class type of the child resource + */ +public abstract class ExternalChildResourceImpl< + FluentModelT extends ExternalChildResource, + InnerModelT, + ParentImplT> + extends + IndexableRefreshableWrapperImpl { + /** + * State representing any pending action that needs to be performed on this child resource. + */ + private State state = State.None; + /** + * The child resource name. + */ + private final String name; + /** + * Reference to the parent of the child resource. + */ + protected final ParentImplT parent; + + /** + * Creates an instance of external child resource in-memory. + * + * @param name the name of this external child resource + * @param parent reference to the parent of this external child resource + * @param innerObject reference to the inner object representing this external child resource + */ + protected ExternalChildResourceImpl(String name, ParentImplT parent, InnerModelT innerObject) { + super(innerObject); + this.name = name; + this.parent = parent; + } + + /** + * @return the resource name + */ + public String name() { + return this.name; + } + + /** + * @return the in-memory state of this child resource and state represents any pending action on the + * child resource. + */ + public State state() { + return this.state; + } + + /** + * Update the in-memory state. + * + * @param newState the new state of this child resource + */ + public void setState(State newState) { + this.state = newState; + } + + /** + * Creates this external child resource. + * + * @return the observable to track the create action + */ + public abstract Observable createAsync(); + + /** + * Update this external child resource. + * + * @return the observable to track the update action + */ + public abstract Observable updateAsync(); + + /** + * Delete this external child resource. + * + * @return the observable to track the delete action. + */ + public abstract Observable deleteAsync(); + + /** + * The possible states of a child resource in-memory. + */ + public enum State { + /** + * No action needs to be taken on resource. + */ + None, + /** + * Child resource required to be created. + */ + ToBeCreated, + /** + * Child resource required to be updated. + */ + ToBeUpdated, + /** + * Child resource required to be deleted. + */ + ToBeRemoved + } +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/ExternalChildResourcesImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/ExternalChildResourcesImpl.java new file mode 100644 index 000000000000..4db79da7e8f5 --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/ExternalChildResourcesImpl.java @@ -0,0 +1,331 @@ +package com.microsoft.azure.management.compute.implementation; + +import com.microsoft.azure.management.compute.ExternalChildResource; +import rx.Observable; +import rx.exceptions.CompositeException; +import rx.functions.Action0; +import rx.functions.Action1; +import rx.functions.Action2; +import rx.functions.Func0; +import rx.functions.Func1; +import rx.subjects.PublishSubject; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * Externalized child resource collection abstract implementation. + * (Internal use only) + * + * @param the implementation of {@param FluentModelT} + * @param the fluent model type of the child resource + * @param Azure inner resource class type representing the child resource + * @param the parent Azure resource class type of the child resources + */ +public abstract class ExternalChildResourcesImpl< + FluentModelTImpl extends ExternalChildResourceImpl, + FluentModelT extends ExternalChildResource, + InnerModelT, + ParentImplT> { + /** + * The parent resource of this collection of child resources. + */ + private final ParentImplT parent; + /** + * Used to construct error string, this is user friendly name of the child resource (e.g. Subnet, Extension). + */ + private final String childResourceName; + /** + * The child resource instances that this collection contains. + */ + private ConcurrentMap collection = new ConcurrentHashMap<>(); + + /** + * Creates a new ExternalChildResourcesImpl. + * + * @param parent the parent Azure resource + * @param childResourceName the child resource name + */ + protected ExternalChildResourcesImpl(ParentImplT parent, String childResourceName) { + this.parent = parent; + this.childResourceName = childResourceName; + } + + /** + * Refresh the collection. + */ + public void refresh() { + initializeCollection(); + } + + /** + * Commits the changes in the external child resource collection. + *

+ * This method returns an observable stream, its observer's onNext will be called for each successfully + * committed resource followed by 'one call to onCompleted' or one call to onError with a + * {@link CompositeException } containing the list of exceptions where each exception describes the reason + * for failure of a resource commit. + * + * @return the observable stream + */ + public Observable commitAsync() { + final ExternalChildResourcesImpl self = this; + List items = new ArrayList<>(); + for (FluentModelTImpl item : this.collection.values()) { + items.add(item); + } + + final List exceptionsList = Collections.synchronizedList(new ArrayList()); + Observable deleteStream = Observable.from(items) + .filter(new Func1() { + @Override + public Boolean call(FluentModelTImpl childResource) { + return childResource.state() == ExternalChildResourceImpl.State.ToBeRemoved; + } + }).flatMap(new Func1>() { + @Override + public Observable call(final FluentModelTImpl childResource) { + return childResource.deleteAsync() + .map(new Func1() { + @Override + public FluentModelTImpl call(Void response) { + return childResource; + } + }).doOnNext(new Action1() { + @Override + public void call(FluentModelTImpl childResource) { + childResource.setState(ExternalChildResourceImpl.State.None); + self.collection.remove(childResource.name()); + } + }) + .onErrorResumeNext(new Func1>() { + @Override + public Observable call(Throwable throwable) { + exceptionsList.add(throwable); + return Observable.empty(); + } + }); + } + }); + + Observable createStream = Observable.from(items) + .filter(new Func1() { + @Override + public Boolean call(FluentModelTImpl childResource) { + return childResource.state() == ExternalChildResourceImpl.State.ToBeCreated; + } + }).flatMap(new Func1>() { + @Override + public Observable call(final FluentModelTImpl childResource) { + return childResource.createAsync() + .map(new Func1() { + @Override + public FluentModelTImpl call(FluentModelT fluentModelT) { + return childResource; + } + }) + .doOnNext(new Action1() { + @Override + public void call(FluentModelTImpl fluentModelT) { + childResource.setState(ExternalChildResourceImpl.State.None); + } + }) + .onErrorResumeNext(new Func1>() { + @Override + public Observable call(Throwable throwable) { + self.collection.remove(childResource.name()); + exceptionsList.add(throwable); + return Observable.empty(); + } + }); + } + }); + + Observable updateStream = Observable.from(items) + .filter(new Func1() { + @Override + public Boolean call(FluentModelTImpl childResource) { + return childResource.state() == ExternalChildResourceImpl.State.ToBeUpdated; + } + }).flatMap(new Func1>() { + @Override + public Observable call(final FluentModelTImpl childResource) { + return childResource.updateAsync() + .map(new Func1() { + @Override + public FluentModelTImpl call(FluentModelT e) { + return childResource; + } + }) + .doOnNext(new Action1() { + @Override + public void call(FluentModelTImpl childResource) { + childResource.setState(ExternalChildResourceImpl.State.None); + } + }) + .onErrorResumeNext(new Func1>() { + @Override + public Observable call(Throwable throwable) { + exceptionsList.add(throwable); + return Observable.empty(); + } + }); + } + }); + + final PublishSubject aggregatedErrorStream = PublishSubject.create(); + Observable operationsStream = Observable.merge(deleteStream, + createStream, + updateStream).doOnTerminate(new Action0() { + @Override + public void call() { + if (exceptionsList.isEmpty()) { + aggregatedErrorStream.onCompleted(); + } else { + aggregatedErrorStream.onError(new CompositeException(exceptionsList)); + } + } + }); + + Observable stream = Observable.concat(operationsStream, aggregatedErrorStream); + return stream; + } + + /** + * Commits the changes in the external child resource collection. + *

+ * This method returns a observable stream, either its observer's onError will be called with + * {@link CompositeException} if some resources failed to commit or onNext will be called if all resources + * committed successfully. + * + * @return the observable stream + */ + public Observable> commitAndGetAllAsync() { + return commitAsync().collect( + new Func0>() { + public List call() { + return new ArrayList<>(); + } + }, + new Action2, FluentModelTImpl>() { + public void call(List state, FluentModelTImpl item) { + state.add(item); + } + }); + } + + /** + * @return the parent Azure resource of the external child resource + */ + protected ParentImplT parent() { + return parent; + } + + /** + * @return the collection of external child resources. + */ + protected Map collection() { + return this.collection; + } + + /** + * Prepare for definition of a new external child resource. + * + * @param name the name for the new external child resource + * @return the child resource + */ + protected FluentModelTImpl prepareDefine(String name) { + if (find(name) != null) { + throw new IllegalArgumentException("A child resource ('" + childResourceName + "') with name '" + name + "' already exists"); + } + FluentModelTImpl childResource = newChildResource(name); + childResource.setState(ExternalChildResourceImpl.State.ToBeCreated); + return childResource; + } + + /** + * Prepare for an external child resource update. + * + * @param name the name of the external child resource + * @return the external child resource to be updated + */ + protected FluentModelTImpl prepareUpdate(String name) { + FluentModelTImpl childResource = find(name); + if (childResource == null + || childResource.state() == ExternalChildResourceImpl.State.ToBeCreated) { + throw new IllegalArgumentException("A child resource ('" + childResourceName + "') with name '" + name + "' not found"); + } + if (childResource.state() == ExternalChildResourceImpl.State.ToBeRemoved) { + throw new IllegalArgumentException("A child resource ('" + childResourceName + "') with name '" + name + "' is marked for deletion"); + } + childResource.setState(ExternalChildResourceImpl.State.ToBeUpdated); + return childResource; + } + + /** + * Mark an external child resource with given name as to be removed. + * + * @param name the name of the external child resource + */ + protected void prepareRemove(String name) { + FluentModelTImpl childResource = find(name); + if (childResource == null + || childResource.state() == ExternalChildResourceImpl.State.ToBeCreated) { + throw new IllegalArgumentException("A child resource ('" + childResourceName + "') with name '" + name + "' not found"); + } + childResource.setState(ExternalChildResourceImpl.State.ToBeRemoved); + } + + /** + * Adds an external child resource to the collection. + * + * @param childResource the external child resource + */ + protected void addChildResource(FluentModelTImpl childResource) { + this.collection.put(childResource.name(), childResource); + } + + /** + * Initializes the external child resource collection. + */ + protected void initializeCollection() { + this.collection.clear(); + for (FluentModelTImpl childResource : this.listChildResources()) { + this.collection.put(childResource.name(), childResource); + } + } + + /** + * Gets the list of external child resources. + * + * @return the list of external child resources + */ + protected abstract List listChildResources(); + + /** + * Gets a new external child resource model instance. + * + * @param name the name for the new child resource + * @return the new child resource + */ + protected abstract FluentModelTImpl newChildResource(String name); + + /** + * Finds a child resource with the given name. + * + * @param name the child resource name + * @return null if no child resource exists with the given name else the child resource + */ + private FluentModelTImpl find(String name) { + for (Map.Entry entry : this.collection.entrySet()) { + if (entry.getKey().equalsIgnoreCase(name)) { + return entry.getValue(); + } + } + return null; + } +} diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImageImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImageImpl.java new file mode 100644 index 000000000000..d08165aec8f3 --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImageImpl.java @@ -0,0 +1,76 @@ +package com.microsoft.azure.management.compute.implementation; + +import com.microsoft.azure.management.compute.ComputeRoles; +import com.microsoft.azure.management.compute.OperatingSystemTypes; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImage; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImageVersion; +import com.microsoft.azure.management.resources.fluentcore.model.implementation.WrapperImpl; + +/** + * The implementation for {@link VirtualMachineExtensionImage}. + */ +public class VirtualMachineExtensionImageImpl + extends WrapperImpl + implements VirtualMachineExtensionImage { + private final VirtualMachineExtensionImageVersion version; + + VirtualMachineExtensionImageImpl(VirtualMachineExtensionImageVersion version, VirtualMachineExtensionImageInner inner) { + super(inner); + this.version = version; + } + + @Override + public String id() { + return this.inner().id(); + } + + @Override + public String regionName() { + return this.inner().location(); + } + + @Override + public String publisherName() { + return this.version().type().publisher().name(); + } + + @Override + public String typeName() { + return this.version().type().name(); + } + + @Override + public String versionName() { + return this.version().name(); + } + + @Override + public OperatingSystemTypes osType() { + return OperatingSystemTypes.fromString(this.inner().operatingSystem()); + } + + @Override + public ComputeRoles computeRole() { + return ComputeRoles.fromString(this.inner().computeRole()); + } + + @Override + public String handlerSchema() { + return this.inner().handlerSchema(); + } + + @Override + public boolean vmScaleSetEnabled() { + return this.inner().vmScaleSetEnabled(); + } + + @Override + public boolean supportsMultipleExtensions() { + return this.inner().supportsMultipleExtensions(); + } + + @Override + public VirtualMachineExtensionImageVersion version() { + return this.version; + } +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImageTypeImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImageTypeImpl.java new file mode 100644 index 000000000000..ad9f5bd43ff2 --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImageTypeImpl.java @@ -0,0 +1,49 @@ +package com.microsoft.azure.management.compute.implementation; + +import com.microsoft.azure.management.compute.VirtualMachineExtensionImageType; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImageVersions; +import com.microsoft.azure.management.compute.VirtualMachinePublisher; +import com.microsoft.azure.management.resources.fluentcore.model.implementation.WrapperImpl; + +/** + * The implementation for {@link VirtualMachineExtensionImageType}. + */ +class VirtualMachineExtensionImageTypeImpl + extends WrapperImpl + implements VirtualMachineExtensionImageType { + private final VirtualMachineExtensionImagesInner client; + private final VirtualMachinePublisher publisher; + + VirtualMachineExtensionImageTypeImpl(VirtualMachineExtensionImagesInner client, + VirtualMachinePublisher publisher, + VirtualMachineExtensionImageInner inner) { + super(inner); + this.client = client; + this.publisher = publisher; + } + + @Override + public String id() { + return this.inner().id(); + } + + @Override + public String name() { + return this.inner().name(); + } + + @Override + public String regionName() { + return this.inner().location(); + } + + @Override + public VirtualMachinePublisher publisher() { + return this.publisher; + } + + @Override + public VirtualMachineExtensionImageVersions versions() { + return new VirtualMachineExtensionImageVersionsImpl(this.client, this); + } +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImageTypesImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImageTypesImpl.java new file mode 100644 index 000000000000..a330474a0c99 --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImageTypesImpl.java @@ -0,0 +1,35 @@ +package com.microsoft.azure.management.compute.implementation; + +import com.microsoft.azure.CloudException; +import com.microsoft.azure.PagedList; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImageType; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImageTypes; +import com.microsoft.azure.management.compute.VirtualMachinePublisher; +import com.microsoft.azure.management.resources.fluentcore.arm.collection.implementation.ReadableWrappersImpl; + +import java.io.IOException; + +/** + * The implementation for {@link VirtualMachineExtensionImageTypes}. + */ +class VirtualMachineExtensionImageTypesImpl + extends ReadableWrappersImpl + implements VirtualMachineExtensionImageTypes { + private final VirtualMachineExtensionImagesInner client; + private final VirtualMachinePublisher publisher; + + VirtualMachineExtensionImageTypesImpl(VirtualMachineExtensionImagesInner client, VirtualMachinePublisher publisher) { + this.client = client; + this.publisher = publisher; + } + + @Override + public PagedList list() throws CloudException, IOException { + return wrapList(this.client.listTypes(this.publisher.region().toString(), this.publisher.name())); + } + + @Override + protected VirtualMachineExtensionImageTypeImpl wrapModel(VirtualMachineExtensionImageInner inner) { + return new VirtualMachineExtensionImageTypeImpl(this.client, this.publisher, inner); + } +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImageVersionImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImageVersionImpl.java new file mode 100644 index 000000000000..ffbb64997130 --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImageVersionImpl.java @@ -0,0 +1,56 @@ +package com.microsoft.azure.management.compute.implementation; + +import com.microsoft.azure.CloudException; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImage; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImageType; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImageVersion; +import com.microsoft.azure.management.resources.fluentcore.model.implementation.WrapperImpl; + +import java.io.IOException; + +/** + * The implementation for {@link VirtualMachineExtensionImageVersion}. + */ +class VirtualMachineExtensionImageVersionImpl + extends WrapperImpl + implements VirtualMachineExtensionImageVersion { + private final VirtualMachineExtensionImagesInner client; + private final VirtualMachineExtensionImageType type; + + VirtualMachineExtensionImageVersionImpl(VirtualMachineExtensionImagesInner client, + VirtualMachineExtensionImageType extensionImageType, + VirtualMachineExtensionImageInner inner) { + super(inner); + this.client = client; + this.type = extensionImageType; + } + + @Override + public String id() { + return this.inner().id(); + } + + @Override + public String name() { + return this.inner().name(); + } + + @Override + public String regionName() { + return this.inner().location(); + } + + @Override + public VirtualMachineExtensionImageType type() { + return this.type; + } + + @Override + public VirtualMachineExtensionImage image() throws CloudException, IOException { + VirtualMachineExtensionImageInner inner = this.client.get(this.regionName(), + this.type().publisher().name(), + this.type().name(), + this.name()); + return new VirtualMachineExtensionImageImpl(this, inner); + } +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImageVersionsImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImageVersionsImpl.java new file mode 100644 index 000000000000..764f865ac5df --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImageVersionsImpl.java @@ -0,0 +1,37 @@ +package com.microsoft.azure.management.compute.implementation; + +import com.microsoft.azure.CloudException; +import com.microsoft.azure.PagedList; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImageType; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImageVersion; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImageVersions; +import com.microsoft.azure.management.resources.fluentcore.arm.collection.implementation.ReadableWrappersImpl; + +import java.io.IOException; + +/** + * The implementation for {@link VirtualMachineExtensionImageVersions}. + */ +public class VirtualMachineExtensionImageVersionsImpl + extends ReadableWrappersImpl + implements VirtualMachineExtensionImageVersions { + private final VirtualMachineExtensionImagesInner client; + private final VirtualMachineExtensionImageType type; + + VirtualMachineExtensionImageVersionsImpl(VirtualMachineExtensionImagesInner client, VirtualMachineExtensionImageType type) { + this.client = client; + this.type = type; + } + + @Override + public PagedList list() throws CloudException, IOException { + return wrapList(this.client.listVersions(this.type.regionName(), + this.type.publisher().name(), + this.type.name())); + } + + @Override + protected VirtualMachineExtensionImageVersionImpl wrapModel(VirtualMachineExtensionImageInner inner) { + return new VirtualMachineExtensionImageVersionImpl(this.client, this.type, inner); + } +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImagesImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImagesImpl.java new file mode 100644 index 000000000000..a68205c4b21b --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImagesImpl.java @@ -0,0 +1,73 @@ +package com.microsoft.azure.management.compute.implementation; + +import com.microsoft.azure.CloudException; +import com.microsoft.azure.PagedList; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImage; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImageType; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImageVersion; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImages; +import com.microsoft.azure.management.compute.VirtualMachinePublisher; +import com.microsoft.azure.management.compute.VirtualMachinePublishers; +import com.microsoft.azure.management.resources.fluentcore.arm.Region; +import com.microsoft.azure.management.resources.fluentcore.utils.PagedListConverter; + +import java.io.IOException; + +/** + * The implementation for {@link VirtualMachineExtensionImages}. + */ +class VirtualMachineExtensionImagesImpl + implements VirtualMachineExtensionImages { + private final VirtualMachinePublishers publishers; + + VirtualMachineExtensionImagesImpl(VirtualMachinePublishers publishers) { + this.publishers = publishers; + } + + @Override + public PagedList listByRegion(Region region) throws CloudException, IOException { + return listByRegion(region.toString()); + } + + @Override + public PagedList listByRegion(String regionName) throws CloudException, IOException { + PagedList publishers = this.publishers().listByRegion(regionName); + + PagedList extensionTypes = + new ChildListFlattener<>(publishers, new ChildListFlattener.ChildListLoader() { + @Override + public PagedList loadList(VirtualMachinePublisher publisher) throws CloudException, IOException { + return publisher.extensionTypes().list(); + } + }).flatten(); + + PagedList extensionTypeVersions = + new ChildListFlattener<>(extensionTypes, new ChildListFlattener.ChildListLoader() { + @Override + public PagedList loadList(VirtualMachineExtensionImageType type) throws CloudException, IOException { + return type.versions().list(); + } + }).flatten(); + + PagedListConverter converter = + new PagedListConverter() { + @Override + public VirtualMachineExtensionImage typeConvert(VirtualMachineExtensionImageVersion virtualMachineExtensionImageVersion) { + try { + return virtualMachineExtensionImageVersion.image(); + } catch (CloudException cloudException) { + throw new RuntimeException(cloudException); + } catch (IOException ioException) { + throw new RuntimeException(ioException); + } + } + }; + + return converter.convert(extensionTypeVersions); + } + + @Override + public VirtualMachinePublishers publishers() { + return this.publishers; + } +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImpl.java new file mode 100644 index 000000000000..cd77a06ad65e --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionImpl.java @@ -0,0 +1,270 @@ +package com.microsoft.azure.management.compute.implementation; + +import com.microsoft.azure.management.compute.VirtualMachine; +import com.microsoft.azure.management.compute.VirtualMachineExtension; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImage; +import com.microsoft.azure.management.compute.VirtualMachineExtensionInstanceView; +import rx.Observable; +import rx.functions.Func1; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.TreeMap; + +/** + * Implementation of {@link VirtualMachineExtension}. + */ +class VirtualMachineExtensionImpl + extends ExternalChildResourceImpl + implements VirtualMachineExtension, + VirtualMachineExtension.Definition, + VirtualMachineExtension.UpdateDefinition, + VirtualMachineExtension.Update { + private final VirtualMachineExtensionsInner client; + private HashMap publicSettings; + private HashMap protectedSettings; + + VirtualMachineExtensionImpl(String name, + VirtualMachineImpl parent, + VirtualMachineExtensionInner inner, + VirtualMachineExtensionsInner client) { + super(name, parent, inner); + this.client = client; + initializeSettings(); + } + + protected static VirtualMachineExtensionImpl newVirtualMachineExtension(String name, + VirtualMachineImpl parent, + VirtualMachineExtensionsInner client) { + VirtualMachineExtensionInner inner = new VirtualMachineExtensionInner(); + inner.withLocation(parent.regionName()); + VirtualMachineExtensionImpl extension = new VirtualMachineExtensionImpl(name, + parent, + inner, + client); + return extension; + } + + @Override + public String id() { + return this.inner().id(); + } + + @Override + public String publisherName() { + return this.inner().publisher(); + } + + @Override + public String typeName() { + return this.inner().virtualMachineExtensionType(); + } + + @Override + public String versionName() { + return this.inner().typeHandlerVersion(); + } + + @Override + public boolean autoUpgradeMinorVersionEnabled() { + return this.inner().autoUpgradeMinorVersion(); + } + + @Override + public Map publicSettings() { + return Collections.unmodifiableMap(this.publicSettings); + } + + @Override + public String publicSettingsAsJsonString() { + return null; + } + + @Override + public VirtualMachineExtensionInstanceView instanceView() { + return this.inner().instanceView(); + } + + @Override + public Map tags() { + Map tags = this.inner().getTags(); + if (tags == null) { + tags = new TreeMap<>(); + } + return Collections.unmodifiableMap(tags); + } + + @Override + public String provisioningState() { + return this.inner().provisioningState(); + } + + @Override + public VirtualMachineExtensionImpl withAutoUpgradeMinorVersionEnabled() { + this.inner().withAutoUpgradeMinorVersion(true); + return this; + } + + @Override + public VirtualMachineExtensionImpl withAutoUpgradeMinorVersionDisabled() { + this.inner().withAutoUpgradeMinorVersion(false); + return this; + } + + @Override + public VirtualMachineExtensionImpl withImage(VirtualMachineExtensionImage image) { + this.inner().withPublisher(image.publisherName()) + .withVirtualMachineExtensionType(image.typeName()) + .withTypeHandlerVersion(image.versionName()); + return this; + } + + @Override + public VirtualMachineExtensionImpl withPublisher(String extensionImagePublisherName) { + this.inner().withPublisher(extensionImagePublisherName); + return this; + } + + @Override + public VirtualMachineExtensionImpl withPublicSetting(String key, Object value) { + this.publicSettings.put(key, value); + return this; + } + + @Override + public VirtualMachineExtensionImpl withProtectedSetting(String key, Object value) { + this.protectedSettings.put(key, value); + return this; + } + + @Override + public VirtualMachineExtensionImpl withPublicSettings(HashMap settings) { + this.publicSettings.clear(); + this.publicSettings.putAll(settings); + return this; + } + + @Override + public VirtualMachineExtensionImpl withProtectedSettings(HashMap settings) { + this.protectedSettings.clear(); + this.protectedSettings.putAll(settings); + return this; + } + + @Override + public VirtualMachineExtensionImpl withType(String extensionImageTypeName) { + this.inner().withVirtualMachineExtensionType(extensionImageTypeName); + return this; + } + + @Override + public VirtualMachineExtensionImpl withVersion(String extensionImageVersionName) { + this.inner().withTypeHandlerVersion(extensionImageVersionName); + return this; + } + + @Override + public final VirtualMachineExtensionImpl withTags(Map tags) { + this.inner().withTags(new HashMap<>(tags)); + return this; + } + + @Override + public final VirtualMachineExtensionImpl withTag(String key, String value) { + this.inner().getTags().put(key, value); + return this; + } + + @Override + public final VirtualMachineExtensionImpl withoutTag(String key) { + this.inner().getTags().remove(key); + return this; + } + + @Override + public VirtualMachineImpl parent() { + this.nullifySettingsIfEmpty(); + return this.parent; + } + + @Override + public VirtualMachineImpl attach() { + this.nullifySettingsIfEmpty(); + return this.parent.withExtension(this); + } + + @Override + public VirtualMachineExtensionImpl refresh() throws Exception { + VirtualMachineExtensionInner inner = + this.client.get(this.parent.resourceGroupName(), this.parent.name(), this.name()); + this.setInner(inner); + return this; + } + + // Implementation of ExternalChildResourceImpl createAsync, updateAsync and deleteAsync + // + @Override + public Observable createAsync() { + final VirtualMachineExtensionImpl self = this; + return this.client.createOrUpdateAsync(this.parent.resourceGroupName(), + this.parent.name(), + this.name(), + this.inner()) + .map(new Func1() { + @Override + public VirtualMachineExtension call(VirtualMachineExtensionInner inner) { + self.setInner(inner); + self.initializeSettings(); + return self; + } + }); + } + + @Override + public Observable updateAsync() { + return this.createAsync(); + } + + @Override + public Observable deleteAsync() { + return this.client.deleteAsync(this.parent.resourceGroupName(), + this.parent.name(), + this.name()).map(new Func1() { + @Override + public Void call(Void result) { + return result; + } + }); + } + + // Helper methods + // + private void nullifySettingsIfEmpty() { + if (this.publicSettings.size() == 0) { + this.inner().withSettings(null); + } + if (this.protectedSettings.size() == 0) { + this.inner().withProtectedSettings(null); + } + } + + private void initializeSettings() { + if (this.inner().settings() == null) { + this.publicSettings = new LinkedHashMap<>(); + this.inner().withSettings(this.publicSettings); + } else { + this.publicSettings = (LinkedHashMap) this.inner().settings(); + } + + if (this.inner().protectedSettings() == null) { + this.protectedSettings = new LinkedHashMap<>(); + this.inner().withProtectedSettings(this.protectedSettings); + } else { + this.protectedSettings = (LinkedHashMap) this.inner().protectedSettings(); + } + } +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionsImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionsImpl.java new file mode 100644 index 000000000000..42d8c0a7f7db --- /dev/null +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineExtensionsImpl.java @@ -0,0 +1,100 @@ +package com.microsoft.azure.management.compute.implementation; +import com.microsoft.azure.management.compute.VirtualMachineExtension; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Represents a extension collection associated with a virtual machine. + */ +class VirtualMachineExtensionsImpl extends + ExternalChildResourcesImpl { + private final VirtualMachineExtensionsInner client; + + /** + * Creates new VirtualMachineExtensionsImpl. + * + * @param client the client to perform REST calls on extensions + * @param parent the parent virtual machine of the extensions + */ + VirtualMachineExtensionsImpl(VirtualMachineExtensionsInner client, VirtualMachineImpl parent) { + super(parent, "VirtualMachineExtension"); + this.client = client; + this.initializeCollection(); + } + + /** + * @return the extension as a map indexed by name. + */ + public Map asMap() { + Map result = new HashMap<>(); + for (Map.Entry entry : this.collection().entrySet()) { + result.put(entry.getKey(), entry.getValue()); + } + return Collections.unmodifiableMap(result); + } + + /** + * Starts an extension definition chain. + * + * @param name the reference name of the extension to be added + * @return the extension + */ + public VirtualMachineExtensionImpl define(String name) { + return this.prepareDefine(name); + } + + /** + * Starts an extension update chain. + * + * @param name the reference name of the extension to be updated + * @return the extension + */ + public VirtualMachineExtensionImpl update(String name) { + return this.prepareUpdate(name); + } + + /** + * Mark the extension with given name as to be removed. + * + * @param name the reference name of the extension to be removed + */ + public void remove(String name) { + this.prepareRemove(name); + } + + /** + * Adds the extension to the collection. + * + * @param extension the extension + */ + public void addExtension(VirtualMachineExtensionImpl extension) { + this.addChildResource(extension); + } + + @Override + protected List listChildResources() { + List childResources = new ArrayList<>(); + if (parent().inner().resources() != null) { + for (VirtualMachineExtensionInner inner : parent().inner().resources()) { + childResources.add(new VirtualMachineExtensionImpl(inner.name(), + this.parent(), + inner, + this.client)); + } + } + return childResources; + } + + @Override + protected VirtualMachineExtensionImpl newChildResource(String name) { + VirtualMachineExtensionImpl extension = VirtualMachineExtensionImpl + .newVirtualMachineExtension(name, this.parent(), this.client); + return extension; + } +} diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImagesImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImagesImpl.java index 37f59899c4d0..48ee88179860 100644 --- a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImagesImpl.java +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImagesImpl.java @@ -18,8 +18,8 @@ class VirtualMachineImagesImpl implements VirtualMachineImages { private final VirtualMachinePublishers publishers; - VirtualMachineImagesImpl(VirtualMachineImagesInner client) { - this.publishers = new VirtualMachinePublishersImpl(client); + VirtualMachineImagesImpl(VirtualMachinePublishers publishers) { + this.publishers = publishers; } @Override @@ -63,4 +63,4 @@ public VirtualMachinePublishers publishers() { return this.publishers; } -} +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImpl.java index 8923a51e9b37..3979d78faf83 100644 --- a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImpl.java +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImpl.java @@ -29,6 +29,7 @@ import com.microsoft.azure.management.compute.VirtualHardDisk; import com.microsoft.azure.management.compute.VirtualMachine; import com.microsoft.azure.management.compute.VirtualMachineDataDisk; +import com.microsoft.azure.management.compute.VirtualMachineExtension; import com.microsoft.azure.management.compute.VirtualMachineInstanceView; import com.microsoft.azure.management.compute.VirtualMachineSize; import com.microsoft.azure.management.compute.VirtualMachineSizeTypes; @@ -54,6 +55,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.UUID; /** @@ -110,10 +112,13 @@ class VirtualMachineImpl private NetworkInterface.DefinitionStages.WithCreate nicDefinitionWithCreate; // Virtual machine size converter private final PagedListConverter virtualMachineSizeConverter; + // The entry point to manage extensions associated with the virtual machine + private VirtualMachineExtensionsImpl virtualMachineExtensions; VirtualMachineImpl(String name, VirtualMachineInner innerModel, VirtualMachinesInner client, + VirtualMachineExtensionsInner extensionsClient, final ComputeManager computeManager, final StorageManager storageManager, final NetworkManager networkManager) { @@ -132,6 +137,7 @@ public VirtualMachineSize typeConvert(VirtualMachineSizeInner inner) { return new VirtualMachineSizeImpl(inner); } }; + this.virtualMachineExtensions = new VirtualMachineExtensionsImpl(extensionsClient, this); initializeDataDisks(); } @@ -144,6 +150,7 @@ public VirtualMachine refresh() throws Exception { this.setInner(response); clearCachedRelatedResources(); initializeDataDisks(); + this.virtualMachineExtensions.refresh(); return this; } @@ -624,6 +631,13 @@ public VirtualMachineImpl withExistingSecondaryNetworkInterface(NetworkInterface return this; } + // Virtual machine optional extension settings + + @Override + public VirtualMachineExtensionImpl defineNewExtension(String name) { + return this.virtualMachineExtensions.define(name); + } + // Virtual machine update only settings @Override @@ -681,6 +695,17 @@ public VirtualMachineImpl withoutSecondaryNetworkInterface(String name) { return this; } + @Override + public VirtualMachineExtensionImpl updateExtension(String name) { + return this.virtualMachineExtensions.update(name); + } + + @Override + public VirtualMachineImpl withoutExtension(String name) { + this.virtualMachineExtensions.remove(name); + return this; + } + /************************************************** * . * Getters @@ -800,8 +825,8 @@ public String licenseType() { } @Override - public List resources() { - return inner().resources(); + public Map extensions() { + return this.virtualMachineExtensions.asMap(); } @Override @@ -872,10 +897,25 @@ public VirtualMachine call(VirtualMachineInner virtualMachineInner) { } }); } + }).flatMap(new Func1>() { + @Override + public Observable call(VirtualMachine virtualMachine) { + return self.virtualMachineExtensions.commitAndGetAllAsync() + .map(new Func1, VirtualMachine>() { + @Override + public VirtualMachine call(List virtualMachineExtensions) { + return self; + } + }); + } }); } // Helpers + VirtualMachineImpl withExtension(VirtualMachineExtensionImpl extension) { + this.virtualMachineExtensions.addExtension(extension); + return this; + } VirtualMachineImpl withDataDisk(DataDiskImpl dataDisk) { this.inner() diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachinePublisherImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachinePublisherImpl.java index 3bf6212231f7..0c8cceada269 100644 --- a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachinePublisherImpl.java +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachinePublisherImpl.java @@ -5,6 +5,7 @@ */ package com.microsoft.azure.management.compute.implementation; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImageTypes; import com.microsoft.azure.management.compute.VirtualMachineOffers; import com.microsoft.azure.management.compute.VirtualMachinePublisher; import com.microsoft.azure.management.resources.fluentcore.arm.Region; @@ -17,11 +18,13 @@ class VirtualMachinePublisherImpl private final Region location; private final String publisher; private final VirtualMachineOffers offers; + private final VirtualMachineExtensionImageTypes types; - VirtualMachinePublisherImpl(Region location, String publisher, VirtualMachineImagesInner client) { + VirtualMachinePublisherImpl(Region location, String publisher, VirtualMachineImagesInner imagesClient, VirtualMachineExtensionImagesInner extensionsClient) { this.location = location; this.publisher = publisher; - this.offers = new VirtualMachineOffersImpl(client, this); + this.offers = new VirtualMachineOffersImpl(imagesClient, this); + this.types = new VirtualMachineExtensionImageTypesImpl(extensionsClient, this); } @Override @@ -38,4 +41,10 @@ public String name() { public VirtualMachineOffers offers() { return this.offers; } -} + + @Override + public VirtualMachineExtensionImageTypes extensionTypes() { + return this.types; + } + +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachinePublishersImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachinePublishersImpl.java index 14155079ae99..96da04818e75 100644 --- a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachinePublishersImpl.java +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachinePublishersImpl.java @@ -21,10 +21,12 @@ class VirtualMachinePublishersImpl extends ReadableWrappersImpl implements VirtualMachinePublishers { - private final VirtualMachineImagesInner innerCollection; + private final VirtualMachineImagesInner imagesInnerCollection; + private final VirtualMachineExtensionImagesInner extensionsInnerCollection; - VirtualMachinePublishersImpl(VirtualMachineImagesInner innerCollection) { - this.innerCollection = innerCollection; + VirtualMachinePublishersImpl(VirtualMachineImagesInner imagesInnerCollection, VirtualMachineExtensionImagesInner extensionsInnerCollection) { + this.imagesInnerCollection = imagesInnerCollection; + this.extensionsInnerCollection = extensionsInnerCollection; } @Override @@ -34,11 +36,14 @@ public PagedList listByRegion(Region region) throws Clo @Override protected VirtualMachinePublisherImpl wrapModel(VirtualMachineImageResourceInner inner) { - return new VirtualMachinePublisherImpl(Region.fromName(inner.location()), inner.name(), this.innerCollection); + return new VirtualMachinePublisherImpl(Region.fromName(inner.location()), + inner.name(), + this.imagesInnerCollection, + this.extensionsInnerCollection); } @Override public PagedList listByRegion(String regionName) throws CloudException, IOException { - return wrapList(innerCollection.listPublishers(regionName)); + return wrapList(imagesInnerCollection.listPublishers(regionName)); } -} +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachinesImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachinesImpl.java index 29d8b0f494b9..59d54f31347e 100644 --- a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachinesImpl.java +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachinesImpl.java @@ -30,22 +30,25 @@ */ class VirtualMachinesImpl extends GroupableResourcesImpl< - VirtualMachine, - VirtualMachineImpl, - VirtualMachineInner, - VirtualMachinesInner, - ComputeManager> + VirtualMachine, + VirtualMachineImpl, + VirtualMachineInner, + VirtualMachinesInner, + ComputeManager> implements VirtualMachines { private final StorageManager storageManager; private final NetworkManager networkManager; private final VirtualMachineSizesImpl vmSizes; + private final VirtualMachineExtensionsInner virtualMachineExtensionsClient; VirtualMachinesImpl(VirtualMachinesInner client, + VirtualMachineExtensionsInner virtualMachineExtensionsClient, VirtualMachineSizesInner virtualMachineSizesClient, ComputeManager computeManager, StorageManager storageManager, NetworkManager networkManager) { super(client, computeManager); + this.virtualMachineExtensionsClient = virtualMachineExtensionsClient; this.storageManager = storageManager; this.networkManager = networkManager; this.vmSizes = new VirtualMachineSizesImpl(virtualMachineSizesClient); @@ -140,18 +143,19 @@ public VirtualMachineSizes sizes() { protected VirtualMachineImpl wrapModel(String name) { VirtualMachineInner inner = new VirtualMachineInner(); inner.withStorageProfile(new StorageProfile() - .withOsDisk(new OSDisk()) - .withDataDisks(new ArrayList())); + .withOsDisk(new OSDisk()) + .withDataDisks(new ArrayList())); inner.withOsProfile(new OSProfile()); inner.withHardwareProfile(new HardwareProfile()); inner.withNetworkProfile(new NetworkProfile() .withNetworkInterfaces(new ArrayList())); return new VirtualMachineImpl(name, - inner, - this.innerCollection, - super.myManager, - this.storageManager, - this.networkManager); + inner, + this.innerCollection, + this.virtualMachineExtensionsClient, + super.myManager, + this.storageManager, + this.networkManager); } @Override @@ -159,8 +163,9 @@ protected VirtualMachineImpl wrapModel(VirtualMachineInner virtualMachineInner) return new VirtualMachineImpl(virtualMachineInner.name(), virtualMachineInner, this.innerCollection, + this.virtualMachineExtensionsClient, super.myManager, this.storageManager, this.networkManager); } -} +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/ComputeManagementTestBase.java b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/ComputeManagementTestBase.java index 4c3b5d98bd8d..d592d2da2a92 100644 --- a/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/ComputeManagementTestBase.java +++ b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/ComputeManagementTestBase.java @@ -5,6 +5,7 @@ import com.microsoft.azure.management.compute.implementation.ComputeManager; import com.microsoft.azure.management.resources.implementation.ResourceManager; import com.microsoft.azure.RestClient; +import okhttp3.logging.HttpLoggingInterceptor; public abstract class ComputeManagementTestBase { protected static ResourceManager resourceManager; @@ -19,7 +20,7 @@ public static void createClients() { RestClient restClient = AzureEnvironment.AZURE.newRestClientBuilder() .withCredentials(credentials) - //.withLogLevel(HttpLoggingInterceptor.Level.BASIC) + .withLogLevel(HttpLoggingInterceptor.Level.BODY) .build(); resourceManager = ResourceManager diff --git a/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImageOperationsTests.java b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImageOperationsTests.java new file mode 100644 index 000000000000..6ab088b32956 --- /dev/null +++ b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/VirtualMachineExtensionImageOperationsTests.java @@ -0,0 +1,115 @@ +package com.microsoft.azure.management.compute; + +import com.microsoft.azure.management.resources.fluentcore.arm.Region; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.List; + +public class VirtualMachineExtensionImageOperationsTests extends ComputeManagementTestBase { + @BeforeClass + public static void setup() throws Exception { + createClients(); + } + + @AfterClass + public static void cleanup() throws Exception { + } + + @Test + public void canListExtensionImages() throws Exception { + final int maxListing = 20; + int count = 0; + List extensionImages = + computeManager.virtualMachineExtensionImages() + .listByRegion(Region.US_EAST); + // Lazy listing + for (VirtualMachineExtensionImage extensionImage : extensionImages) { + Assert.assertNotNull(extensionImage); + count++; + if (count >= maxListing) { + break; + } + } + Assert.assertTrue(count == maxListing); + } + + @Test + public void canGetExtensionTypeVersionAndImage() throws Exception { + List extensionImages = + computeManager.virtualMachineExtensionImages() + .listByRegion(Region.US_EAST); + + final String dockerExtensionPublisherName = "Microsoft.Azure.Extensions"; + final String dockerExtensionImageTypeName = "DockerExtension"; + + // Lookup Azure docker extension publisher + // + List publishers = + computeManager.virtualMachineExtensionImages() + .publishers() + .listByRegion(Region.US_EAST); + + VirtualMachinePublisher azureDockerExtensionPublisher = null; + for (VirtualMachinePublisher publisher : publishers) { + if (publisher.name().equalsIgnoreCase(dockerExtensionPublisherName)) { + azureDockerExtensionPublisher = publisher; + break; + } + } + Assert.assertNotNull(azureDockerExtensionPublisher); + + // Lookup Azure docker extension type + // + VirtualMachineExtensionImageTypes extensionImageTypes = azureDockerExtensionPublisher.extensionTypes(); + Assert.assertTrue(extensionImageTypes.list().size() > 0); + + VirtualMachineExtensionImageType dockerExtensionImageType = null; + for (VirtualMachineExtensionImageType extensionImageType : extensionImageTypes.list()) { + if (extensionImageType.name().equalsIgnoreCase(dockerExtensionImageTypeName)) { + dockerExtensionImageType = extensionImageType; + break; + } + } + Assert.assertNotNull(dockerExtensionImageType); + + Assert.assertNotNull(dockerExtensionImageType.id()); + Assert.assertTrue(dockerExtensionImageType.name().equalsIgnoreCase(dockerExtensionImageTypeName)); + Assert.assertTrue(dockerExtensionImageType.regionName().equalsIgnoreCase(Region.US_EAST.toString())); + Assert.assertTrue(dockerExtensionImageType.id() + .toLowerCase() + .endsWith("/Providers/Microsoft.Compute/Locations/eastus/Publishers/Microsoft.Azure.Extensions/ArtifactTypes/VMExtension/Types/DockerExtension".toLowerCase())); + Assert.assertNotNull(dockerExtensionImageType.publisher()); + Assert.assertTrue(dockerExtensionImageType.publisher().name().equalsIgnoreCase(dockerExtensionPublisherName)); + + // Fetch Azure docker extension versions + // + VirtualMachineExtensionImageVersions extensionImageVersions = dockerExtensionImageType.versions(); + Assert.assertTrue(extensionImageVersions.list().size() > 0); + + VirtualMachineExtensionImageVersion extensionImageFirstVersion = null; + for (VirtualMachineExtensionImageVersion extensionImageVersion : extensionImageVersions.list()) { + extensionImageFirstVersion = extensionImageVersion; + break; + } + + Assert.assertNotNull(extensionImageFirstVersion); + String versionName = extensionImageFirstVersion.name(); + Assert.assertTrue(extensionImageFirstVersion.id() + .toLowerCase() + .endsWith(("/Providers/Microsoft.Compute/Locations/eastus/Publishers/Microsoft.Azure.Extensions/ArtifactTypes/VMExtension/Types/DockerExtension/Versions/" + versionName).toLowerCase())); + Assert.assertNotNull(extensionImageFirstVersion.type()); + + // Fetch the Azure docker extension image + // + VirtualMachineExtensionImage dockerExtensionImage = extensionImageFirstVersion.image(); + + Assert.assertTrue(dockerExtensionImage.regionName().equalsIgnoreCase(Region.US_EAST.toString())); + Assert.assertTrue(dockerExtensionImage.publisherName().equalsIgnoreCase(dockerExtensionPublisherName)); + Assert.assertTrue(dockerExtensionImage.typeName().equalsIgnoreCase(dockerExtensionImageTypeName)); + Assert.assertTrue(dockerExtensionImage.versionName().equalsIgnoreCase(versionName)); + Assert.assertTrue(dockerExtensionImage.osType() == OperatingSystemTypes.LINUX || dockerExtensionImage.osType() == OperatingSystemTypes.WINDOWS); + } +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/VirtualMachineExtensionOperationsTests.java b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/VirtualMachineExtensionOperationsTests.java new file mode 100644 index 000000000000..914157c496db --- /dev/null +++ b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/VirtualMachineExtensionOperationsTests.java @@ -0,0 +1,119 @@ +package com.microsoft.azure.management.compute; + +import com.microsoft.azure.management.resources.fluentcore.utils.ResourceNamer; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import java.util.ArrayList; +import java.util.List; + +public class VirtualMachineExtensionOperationsTests extends ComputeManagementTestBase { + @BeforeClass + public static void setup() throws Exception { + createClients(); + } + + @AfterClass + public static void cleanup() throws Exception { + } + + @Test + public void canResetPasswordUsingVMAccessExtension() throws Exception { + final String RG_NAME = ResourceNamer.randomResourceName("vmexttest", 15); + final String LOCATION = "eastus"; + final String VMNAME = "javavm"; + + // Create a Linux VM + // + VirtualMachine vm = computeManager.virtualMachines() + .define(VMNAME) + .withRegion(LOCATION) + .withNewResourceGroup(RG_NAME) + .withNewPrimaryNetwork("10.0.0.0/28") + .withPrimaryPrivateIpAddressDynamic() + .withoutPrimaryPublicIpAddress() + .withPopularLinuxImage(KnownLinuxVirtualMachineImage.UBUNTU_SERVER_14_04_LTS) + .withRootUserName("Foo12") + .withPassword("BaR@12abc!") + .withSize(VirtualMachineSizeTypes.STANDARD_D3) + .create(); + + // Using VMAccess Linux extension to reset the password for the existing user 'Foo12' + // https://github.com/Azure/azure-linux-extensions/blob/master/VMAccess/README.md + // + vm.update() + .defineNewExtension("VMAccessForLinux") + .withPublisher("Microsoft.OSTCExtensions") + .withType("VMAccessForLinux") + .withVersion("1.4") + .withProtectedSetting("username", "Foo12") + .withProtectedSetting("password", "B12a6@12xyz!") + .withProtectedSetting("reset_ssh", "true") + .attach() + .apply(); + + Assert.assertTrue(vm.extensions().size() > 0); + Assert.assertTrue(vm.extensions().containsKey("VMAccessForLinux")); + + // Update the VMAccess Linux extension to reset password again for the user 'Foo12' + // + vm.update() + .updateExtension("VMAccessForLinux") + .withProtectedSetting("username", "Foo12") + .withProtectedSetting("password", "muy!234OR") + .withProtectedSetting("reset_ssh", "true") + .parent() + .apply(); + } + + @Test + public void canInstallUninstallCustomExtension() throws Exception { + final String RG_NAME = ResourceNamer.randomResourceName("vmexttest", 15); + final String LOCATION = "eastus"; + final String VMNAME = "javavm"; + + final String mySqlInstallScript = "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/4397e808d07df60ff3cdfd1ae40999f0130eb1b3/mysql-standalone-server-ubuntu/scripts/install_mysql_server_5.6.sh"; + final String installCommand = "bash install_mysql_server_5.6.sh Abc.123x("; + List fileUris = new ArrayList<>(); + fileUris.add(mySqlInstallScript); + + // Create Linux VM with a custom extension to install MySQL + // + VirtualMachine vm = computeManager.virtualMachines() + .define(VMNAME) + .withRegion(LOCATION) + .withNewResourceGroup(RG_NAME) + .withNewPrimaryNetwork("10.0.0.0/28") + .withPrimaryPrivateIpAddressDynamic() + .withoutPrimaryPublicIpAddress() + .withPopularLinuxImage(KnownLinuxVirtualMachineImage.UBUNTU_SERVER_14_04_LTS) + .withRootUserName("Foo12") + .withPassword("BaR@12abc!") + .withSize(VirtualMachineSizeTypes.STANDARD_D3) + .defineNewExtension("CustomScriptForLinux") + .withPublisher("Microsoft.OSTCExtensions") + .withType("CustomScriptForLinux") + .withVersion("1.4") + .withAutoUpgradeMinorVersionEnabled() + .withPublicSetting("fileUris",fileUris) + .withPublicSetting("commandToExecute", installCommand) + .attach() + .create(); + + Assert.assertTrue(vm.extensions().size() > 0); + Assert.assertTrue(vm.extensions().containsKey("CustomScriptForLinux")); + VirtualMachineExtension customScriptExtension = vm.extensions().get("CustomScriptForLinux"); + Assert.assertEquals(customScriptExtension.publisherName(), "Microsoft.OSTCExtensions"); + Assert.assertEquals(customScriptExtension.typeName(), "CustomScriptForLinux"); + Assert.assertEquals(customScriptExtension.autoUpgradeMinorVersionEnabled(), true); + + // Remove the custom extension + // + vm.update() + .withoutExtension("CustomScriptForLinux") + .apply(); + + Assert.assertTrue(vm.extensions().size() == 0); + } +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/VirtualMachineImageOperationsTests.java b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/VirtualMachineImageOperationsTests.java index 1d6d8d758d56..42763a33d7bf 100644 --- a/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/VirtualMachineImageOperationsTests.java +++ b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/VirtualMachineImageOperationsTests.java @@ -21,7 +21,7 @@ public static void cleanup() throws Exception { @Test public void canListVirtualMachineImages() throws Exception { - int maxListing = 20; + final int maxListing = 20; int count = 0; PagedList images = computeManager.virtualMachineImages() .listByRegion(Region.US_EAST); @@ -31,7 +31,6 @@ public void canListVirtualMachineImages() throws Exception { if (count >= maxListing) { break; } - System.out.println(count + ":" + image.publisherName() + ":" + image.offer() + ":" + image.version()); } Assert.assertTrue(count == maxListing); @@ -69,4 +68,4 @@ public void canListVirtualMachineImages() throws Exception { Assert.assertNotNull(diskImage.lun()); } } -} +} \ No newline at end of file diff --git a/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/childresource/ChickenImpl.java b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/childresource/ChickenImpl.java new file mode 100644 index 000000000000..65a7b7cab15d --- /dev/null +++ b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/childresource/ChickenImpl.java @@ -0,0 +1,43 @@ +package com.microsoft.azure.management.compute.childresource; + +import rx.Observable; +import rx.functions.Func1; + +class ChickenImpl { + private PulletsImpl pullets; + ChickenImpl() { + this.pullets = new PulletsImpl(this); + } + + PulletsImpl pullets() { + return this.pullets; + } + + ChickenImpl withPullet(PulletImpl pullet) { + this.pullets.addPullet(pullet); + return this; + } + + PulletImpl defineNewPullet(String name) { + return this.pullets.define(name); + } + + PulletImpl updatePullet(String name) { + return this.pullets.update(name); + } + + ChickenImpl withoutPullet(String name) { + this.pullets.remove(name); + return this; + } + + Observable applyAsync() { + final ChickenImpl self = this; + return this.pullets.commitAsync() + .map(new Func1() { + public ChickenImpl call(PulletImpl p) { + return self; + } + }); + } +} diff --git a/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/childresource/ExternalChildResourceTests.java b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/childresource/ExternalChildResourceTests.java new file mode 100644 index 000000000000..92eb380f0d09 --- /dev/null +++ b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/childresource/ExternalChildResourceTests.java @@ -0,0 +1,179 @@ +package com.microsoft.azure.management.compute.childresource; + +import com.microsoft.azure.management.compute.implementation.ExternalChildResourceImpl; +import org.junit.Assert; +import org.junit.Test; +import rx.Observer; +import rx.Subscriber; +import rx.exceptions.CompositeException; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CountDownLatch; + +public class ExternalChildResourceTests { + @Test + public void noCommitIfNoChange() throws InterruptedException { + ChickenImpl chicken = new ChickenImpl(); // Parent resource + PulletsImpl pullets = chicken.pullets(); // Child resource collection + final CountDownLatch monitor = new CountDownLatch(1); + // Note that commitAsync() won't be exposed to the end-user as it's a part of child resource impl + // pullets.commitAsync will be called from (Applicable)chicken.applyAsync() or (Creatable)chicken.createAsync(). + // + // Observable Chicken::ApplyAsync() { + // [1] update chicken + // [2] update pullets by calling pullets.commitAsync() + // } + // + // In the unit test cases we call it directly as we testing external child resource here. + // + pullets.commitAsync() + .subscribe(new Subscriber() { + @Override + public void onCompleted() { + monitor.countDown(); + } + + @Override + public void onError(Throwable throwable) { + monitor.countDown(); + Assert.assertTrue("nothing to commit onError should not be invoked", false); + } + + @Override + public void onNext(PulletImpl pullet) { + Assert.assertTrue("nothing to commit onNext should not be invoked", false); + } + }); + monitor.await(); + } + + @Test + public void shouldCommitCreateUpdateAndDelete() throws InterruptedException { + ChickenImpl chicken = new ChickenImpl(); // Parent resource + chicken + .defineNewPullet("alice") + .withAge(1) + .attach() + .updatePullet("Clover") + .withAge(2) + .parent() + .withoutPullet("Pinky"); + + final List changedPuppets = new ArrayList<>(); + final CountDownLatch monitor = new CountDownLatch(1); + + PulletsImpl pullets = chicken.pullets(); + pullets.commitAsync() + .subscribe(new Observer() { + @Override + public void onCompleted() { + monitor.countDown(); + } + + @Override + public void onError(Throwable throwable) { + monitor.countDown(); + Assert.assertTrue("onError should not be invoked", false); + } + + @Override + public void onNext(PulletImpl pullet) { + changedPuppets.add(pullet); + } + }); + monitor.await(); + Assert.assertTrue(changedPuppets.size() == 3); + for (PulletImpl pullet : changedPuppets) { + Assert.assertTrue(pullet.state() == ExternalChildResourceImpl.State.None); + } + } + + @Test + public void shouldEmitErrorAfterAllSuccessfulCommit() throws InterruptedException { + ChickenImpl chicken = new ChickenImpl(); // Parent resource + chicken + .defineNewPullet("alice") + .withAge(1) + .withFailFlag(PulletImpl.FailFlag.OnCreate) + .attach() + .updatePullet("Clover") + .withAge(2) + .parent() + .updatePullet("Goldilocks") + .withAge(2) + .withFailFlag(PulletImpl.FailFlag.OnUpdate) + .parent() + .withoutPullet("Pinky"); + + final List changedPuppets = new ArrayList<>(); + final List throwables = new ArrayList<>(); + final CountDownLatch monitor = new CountDownLatch(1); + PulletsImpl pullets = chicken.pullets(); + pullets.commitAsync() + .subscribe(new Observer() { + @Override + public void onCompleted() { + monitor.countDown(); + Assert.assertTrue("onCompleted should not be invoked", false); + } + + @Override + public void onError(Throwable throwable) { + try { + CompositeException exception = (CompositeException) throwable; + Assert.assertNotNull(exception); + for (Throwable innerThrowable : exception.getExceptions()) { + throwables.add(innerThrowable); + } + } finally { + monitor.countDown(); + } + } + + @Override + public void onNext(PulletImpl pullet) { + changedPuppets.add(pullet); + } + }); + + monitor.await(); + Assert.assertTrue(throwables.size() == 2); + Assert.assertTrue(changedPuppets.size() == 2); + } + + @Test + public void canStreamAccumulatedResult() throws InterruptedException { + ChickenImpl chicken = new ChickenImpl(); + chicken + .defineNewPullet("alice") + .withAge(1) + .attach() + .updatePullet("Clover") + .withAge(2) + .attach() + .withoutPullet("Pinky"); + + PulletsImpl pullets = chicken.pullets(); + final CountDownLatch monitor = new CountDownLatch(1); + pullets.commitAndGetAllAsync() + .subscribe(new Subscriber>() { + @Override + public void onCompleted() { + monitor.countDown(); + } + + @Override + public void onError(Throwable throwable) { + monitor.countDown(); + Assert.assertTrue("onError should not be invoked", false); + } + + @Override + public void onNext(List pullets) { + Assert.assertTrue(pullets.size() == 3); + } + }); + monitor.await(); + } +} diff --git a/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/childresource/Pullet.java b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/childresource/Pullet.java new file mode 100644 index 000000000000..b0ea9f4a1686 --- /dev/null +++ b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/childresource/Pullet.java @@ -0,0 +1,6 @@ +package com.microsoft.azure.management.compute.childresource; + +import com.microsoft.azure.management.compute.ExternalChildResource; + +interface Pullet extends ExternalChildResource { +} diff --git a/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/childresource/PulletImpl.java b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/childresource/PulletImpl.java new file mode 100644 index 000000000000..9730dd90269e --- /dev/null +++ b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/childresource/PulletImpl.java @@ -0,0 +1,99 @@ +package com.microsoft.azure.management.compute.childresource; + +import com.microsoft.azure.management.compute.implementation.ExternalChildResourceImpl; +import rx.Observable; +import rx.schedulers.Schedulers; + +class PulletImpl extends ExternalChildResourceImpl + implements Pullet { + Integer age; + private FailFlag failFlag = FailFlag.None; + + PulletImpl(String name, ChickenImpl parent) { + super(name, parent, new Object()); + } + + public PulletImpl withAge(Integer age) { + this.age = age; + return this; + } + + public PulletImpl withFailFlag(FailFlag failFlag) { + this.failFlag = failFlag; + return this; + } + + public ChickenImpl parent() { + return this.parent; + } + + public ChickenImpl attach() { + return this.parent.withPullet(this); + } + + @Override + public Observable createAsync() { + try { + Thread.sleep(2000); + } catch (InterruptedException ex) { + } + + if (this.failFlag == FailFlag.OnCreate) { + return Observable.error(new Exception("Creation of " + this.name() + " failed")); + } + + Pullet self = this; + return Observable + .just(self) + .observeOn(Schedulers.computation()); + } + + @Override + public Observable updateAsync() { + try { + Thread.sleep(2000); + } catch (InterruptedException ex) { + } + + if (this.failFlag == FailFlag.OnUpdate) { + return Observable.error(new Exception("Update of " + this.name() + " failed")); + } + + Pullet self = this; + return Observable + .just(self) + .observeOn(Schedulers.computation()); + } + + @Override + public Observable deleteAsync() { + try { + Thread.sleep(2000); + } catch (InterruptedException ex) { + } + + if (this.failFlag == FailFlag.OnDelete) { + return Observable.error(new Exception("Deletion of " + this.name() + " failed")); + } + + return Observable + .just(null); + } + + @Override + public PulletImpl refresh() throws Exception { + return null; + } + + @Override + public String id() { + return null; + } + + enum FailFlag { + None, + OnCreate, + OnUpdate, + OnDelete + } +} diff --git a/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/childresource/PulletsImpl.java b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/childresource/PulletsImpl.java new file mode 100644 index 000000000000..118263c3a064 --- /dev/null +++ b/azure-mgmt-compute/src/test/java/com/microsoft/azure/management/compute/childresource/PulletsImpl.java @@ -0,0 +1,44 @@ +package com.microsoft.azure.management.compute.childresource; + +import com.microsoft.azure.management.compute.implementation.ExternalChildResourcesImpl; +import java.util.ArrayList; +import java.util.List; + +class PulletsImpl extends ExternalChildResourcesImpl { + PulletsImpl(ChickenImpl parent) { + super(parent, "Pullet"); + initializeCollection(); + } + + public PulletImpl define(String name) { + return super.prepareDefine(name); + } + + public PulletImpl update(String name) { + return super.prepareUpdate(name); + } + + public void remove(String name) { + super.prepareRemove(name); + } + + public void addPullet(PulletImpl pullet) { + this.addChildResource(pullet); + } + + @Override + protected List listChildResources() { + List resources = new ArrayList<>(); + resources.add(new PulletImpl("Tilly", this.parent())); + resources.add(new PulletImpl("Clover", this.parent())); + resources.add(new PulletImpl("Savvy", this.parent())); + resources.add(new PulletImpl("Pinky", this.parent())); + resources.add(new PulletImpl("Goldilocks", this.parent())); + return resources; + } + + @Override + protected PulletImpl newChildResource(String name) { + return new PulletImpl(name, this.parent()); + } +} diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskItem.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskItem.java index 2a1a5f7f270d..ae26ea92e260 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskItem.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskItem.java @@ -31,12 +31,12 @@ public ResourceT result() { @Override public Observable executeAsync() { return this.resourceCreator.createResourceAsync() - .subscribeOn(Schedulers.io()) - .doOnNext(new Action1() { - @Override - public void call(ResourceT resourceT) { - created = resourceT; - } - }); + .subscribeOn(Schedulers.io()) + .doOnNext(new Action1() { + @Override + public void call(ResourceT resourceT) { + created = resourceT; + } + }); } } diff --git a/azure-samples/src/main/java/com/microsoft/azure/management/compute/samples/ListVirtualMachineExtensionImages.java b/azure-samples/src/main/java/com/microsoft/azure/management/compute/samples/ListVirtualMachineExtensionImages.java new file mode 100644 index 000000000000..5a4ab510fd6d --- /dev/null +++ b/azure-samples/src/main/java/com/microsoft/azure/management/compute/samples/ListVirtualMachineExtensionImages.java @@ -0,0 +1,94 @@ +package com.microsoft.azure.management.compute.samples; + +import com.microsoft.azure.Azure; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImage; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImageType; +import com.microsoft.azure.management.compute.VirtualMachineExtensionImageVersion; +import com.microsoft.azure.management.compute.VirtualMachinePublisher; +import com.microsoft.azure.management.resources.fluentcore.arm.Region; +import okhttp3.logging.HttpLoggingInterceptor; + +import java.io.File; +import java.util.List; + +/** + * List all virtual machine extension image publishers and + * list all virtual machine extension images published by Microsoft.OSTCExtensions, Microsoft.Azure.Extensions + * by browsing through extension image publishers, types, and versions. + */ +public final class ListVirtualMachineExtensionImages { + /** + * The main entry point. + * + * @param args the parameters + */ + public static void main(String[] args) { + try { + + + //================================================================= + // Authenticate + + final File credFile = new File(System.getenv("AZURE_AUTH_LOCATION")); + + Azure azure = Azure + .configure() + .withLogLevel(HttpLoggingInterceptor.Level.NONE) + .authenticate(credFile) + .withDefaultSubscription(); + + //================================================================= + // List all virtual machine extension image publishers and + // list all virtual machine extension images + // published by Microsoft.OSTCExtensions and Microsoft.Azure.Extensions + // by browsing through extension image publishers, types, and versions + + List publishers = azure + .virtualMachineImages() + .publishers() + .listByRegion(Region.US_EAST); + + VirtualMachinePublisher chosenPublisher; + + System.out.println("US East data center: printing list of \n" + + "a) Publishers and\n" + + "b) virtual machine images published by Microsoft.OSTCExtensions and Microsoft.Azure.Extensions"); + System.out.println("======================================================="); + System.out.println("\n"); + + for (VirtualMachinePublisher publisher : publishers) { + + System.out.println("Publisher - " + publisher.name()); + + if (publisher.name().equalsIgnoreCase("Microsoft.OSTCExtensions") + | publisher.name().equalsIgnoreCase("Microsoft.Azure.Extensions")) { + + chosenPublisher = publisher; + System.out.print("\n\n"); + System.out.println("======================================================="); + System.out.println("Located " + chosenPublisher.name()); + System.out.println("======================================================="); + System.out.println("Printing entries as publisher/type/version"); + + for (VirtualMachineExtensionImageType imageType : chosenPublisher.extensionTypes().list()) { + for (VirtualMachineExtensionImageVersion version: imageType.versions().list()) { + VirtualMachineExtensionImage image = version.image(); + System.out.println("Image - " + chosenPublisher.name() + "/" + + image.typeName() + "/" + + image.versionName()); + } + } + + System.out.print("\n\n"); + + } + } + } catch (Exception e) { + System.out.println(e.getMessage()); + e.printStackTrace(); + } + } + + private ListVirtualMachineExtensionImages() { + } +} diff --git a/azure-samples/src/main/java/com/microsoft/azure/management/compute/samples/ManageVirtualMachineExtension.java b/azure-samples/src/main/java/com/microsoft/azure/management/compute/samples/ManageVirtualMachineExtension.java new file mode 100644 index 000000000000..14bdea327ecb --- /dev/null +++ b/azure-samples/src/main/java/com/microsoft/azure/management/compute/samples/ManageVirtualMachineExtension.java @@ -0,0 +1,296 @@ +package com.microsoft.azure.management.compute.samples; + +import com.microsoft.azure.Azure; +import com.microsoft.azure.management.compute.KnownLinuxVirtualMachineImage; +import com.microsoft.azure.management.compute.KnownWindowsVirtualMachineImage; +import com.microsoft.azure.management.compute.VirtualMachine; +import com.microsoft.azure.management.compute.VirtualMachineSizeTypes; +import com.microsoft.azure.management.resources.fluentcore.arm.Region; +import com.microsoft.azure.management.resources.fluentcore.utils.ResourceNamer; +import com.microsoft.azure.management.samples.Utils; +import okhttp3.logging.HttpLoggingInterceptor; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * Azure Compute sample for managing virtual machine extensions. - + * - Create a Linux and Windows virtual machine + * - Add three users (user names and passwords for windows, SSH keys for Linux) + * - Resets user credentials + * - Remove a user + * - Install MySQL on Linux | something significant on Windows + * - Remove extensions + */ +public final class ManageVirtualMachineExtension { + /** + * Main entry point. + * @param args the parameters + */ + public static void main(String[] args) { + + final String linuxVmName = ResourceNamer.randomResourceName("lVM", 10); + final String windowsVmName = ResourceNamer.randomResourceName("wVM", 10); + final String rgName = ResourceNamer.randomResourceName("rgCOMV", 15); + final String pipDnsLabelLinuxVM = ResourceNamer.randomResourceName("rgPip1", 25); + final String pipDnsLabelWindowsVM = ResourceNamer.randomResourceName("rgPip2", 25); + + // Linux configurations + // + final String firstLinuxUserName = "tirekicker"; + final String firstLinuxUserPassword = "12NewPA$$w0rd!"; + final String firstLinuxUserNewPassword = "muy!234OR"; + + final String secondLinuxUserName = "seconduser"; + final String secondLinuxUserPassword = "B12a6@12xyz!"; + final String secondLinuxUserExpiration = "2020-12-31"; + + final String thirdLinuxUserName = "thirduser"; + final String thirdLinuxUserPassword = "12xyz!B12a6@"; + final String thirdLinuxUserExpiration = "2020-12-31"; + + final String linuxCustomScriptExtensionName = "CustomScriptForLinux"; + final String linuxCustomScriptExtensionPublisherName = "Microsoft.OSTCExtensions"; + final String linuxCustomScriptExtensionTypeName = "CustomScriptForLinux"; + final String linuxCustomScriptExtensionVersionName = "1.4"; + + final String mySqlLinuxInstallScript = "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/4397e808d07df60ff3cdfd1ae40999f0130eb1b3/mysql-standalone-server-ubuntu/scripts/install_mysql_server_5.6.sh"; + final String mySqlScriptInstallCommand = "bash install_mysql_server_5.6.sh Abc.123x("; + final List fileUris = new ArrayList<>(); + fileUris.add(mySqlLinuxInstallScript); + + final String linuxVmAccessExtensionName = "VMAccessForLinux"; + final String linuxVmAccessExtensionPublisherName = "Microsoft.OSTCExtensions"; + final String linuxVmAccessExtensionTypeName = "VMAccessForLinux"; + final String linuxVmAccessExtensionVersionName = "1.4"; + + // Windows configurations + // + final String firstWindowsUserName = "tirekicker"; + final String firstWindowsUserPassword = "12NewPA$$w0rd!"; + final String firstWindowsUserNewPassword = "muy!234OR"; + + final String secondWindowsUserName = "seconduser"; + final String secondWindowsUserPassword = "B12a6@12xyz!"; + + final String thirdWindowsUserName = "thirduser"; + final String thirdWindowsUserPassword = "12xyz!B12a6@"; + + final String windowsVmAccessExtensionName = "VMAccessAgent"; + final String windowsVmAccessExtensionPublisherName = "Microsoft.Compute"; + final String windowsVmAccessExtensionTypeName = "VMAccessAgent"; + final String windowsVmAccessExtensionVersionName = "2.3"; + + try { + + //============================================================= + // Authenticate + + final File credFile = new File(System.getenv("AZURE_AUTH_LOCATION")); + + Azure azure = Azure + .configure() + .withLogLevel(HttpLoggingInterceptor.Level.BASIC) + .authenticate(credFile) + .withDefaultSubscription(); + + // Print selected subscription + System.out.println("Selected subscription: " + azure.subscriptionId()); + + + try { + + + //============================================================= + // Create a Linux VM with root (sudo) user + + System.out.println("Creating a Linux VM"); + + VirtualMachine linuxVM = azure.virtualMachines().define(linuxVmName) + .withRegion(Region.US_EAST) + .withNewResourceGroup(rgName) + .withNewPrimaryNetwork("10.0.0.0/28") + .withPrimaryPrivateIpAddressDynamic() + .withNewPrimaryPublicIpAddress(pipDnsLabelLinuxVM) + .withPopularLinuxImage(KnownLinuxVirtualMachineImage.UBUNTU_SERVER_14_04_LTS) + .withRootUserName(firstLinuxUserName) + .withPassword(firstLinuxUserPassword) + .withSize(VirtualMachineSizeTypes.STANDARD_D3_V2) + .create(); + + System.out.println("Created a Linux VM with" + linuxVM.id()); + Utils.print(linuxVM); + + //============================================================= + // Add a second sudo user to Linux VM using VMAccess extension + + linuxVM.update() + .defineNewExtension(linuxVmAccessExtensionName) + .withPublisher(linuxVmAccessExtensionPublisherName) + .withType(linuxVmAccessExtensionTypeName) + .withVersion(linuxVmAccessExtensionVersionName) + .withProtectedSetting("username", secondLinuxUserName) + .withProtectedSetting("password", secondLinuxUserPassword) + .withProtectedSetting("expiration", secondLinuxUserExpiration) + .attach() + .apply(); + + System.out.println("Added a second sudo user to the Linux VM"); + + //============================================================= + // Add a third sudo user to Linux VM by updating VMAccess extension + + linuxVM.update() + .updateExtension(linuxVmAccessExtensionName) + .withProtectedSetting("username", thirdLinuxUserName) + .withProtectedSetting("password", thirdLinuxUserPassword) + .withProtectedSetting("expiration", thirdLinuxUserExpiration) + .parent() + .apply(); + + System.out.println("Added a third sudo user to the Linux VM"); + + //============================================================= + // Reset ssh password of first user of Linux VM by updating VMAccess extension + + linuxVM.update() + .updateExtension(linuxVmAccessExtensionName) + .withProtectedSetting("username", firstLinuxUserName) + .withProtectedSetting("password", firstLinuxUserNewPassword) + .withProtectedSetting("reset_ssh", "true") + .parent() + .apply(); + + System.out.println("Password of first user of Linux VM has been updated"); + + //============================================================= + // Removes the second sudo user from Linux VM using VMAccess extension + + linuxVM.update() + .updateExtension(linuxVmAccessExtensionName) + .withProtectedSetting("remove_user", secondLinuxUserName) + .parent() + .apply(); + + //============================================================= + // Install MySQL in Linux VM using CustomScript extension + + linuxVM.update() + .defineNewExtension(linuxCustomScriptExtensionName) + .withPublisher(linuxCustomScriptExtensionPublisherName) + .withType(linuxCustomScriptExtensionTypeName) + .withVersion(linuxCustomScriptExtensionVersionName) + .withAutoUpgradeMinorVersionEnabled() + .withPublicSetting("fileUris", fileUris) + .withPublicSetting("commandToExecute", mySqlScriptInstallCommand) + .attach() + .apply(); + + System.out.println("Installed MySql using custom script extension"); + Utils.print(linuxVM); + + //============================================================= + // Removes the extensions from Linux VM + + linuxVM.update() + .withoutExtension(linuxCustomScriptExtensionName) + .withoutExtension(linuxVmAccessExtensionName) + .apply(); + System.out.println("Removed the custom script and VM Access extensions from Linux VM"); + Utils.print(linuxVM); + + //============================================================= + // Create a Windows VM with admin user + + System.out.println("Creating a Windows VM"); + + VirtualMachine windowsVM = azure.virtualMachines().define(windowsVmName) + .withRegion(Region.US_EAST) + .withExistingResourceGroup(rgName) + .withNewPrimaryNetwork("10.0.0.0/28") + .withPrimaryPrivateIpAddressDynamic() + .withNewPrimaryPublicIpAddress(pipDnsLabelWindowsVM) + .withPopularWindowsImage(KnownWindowsVirtualMachineImage.WINDOWS_SERVER_2012_R2_DATACENTER) + .withAdminUserName(firstWindowsUserName) + .withPassword(firstWindowsUserPassword) + .withSize(VirtualMachineSizeTypes.STANDARD_D3_V2) + .create(); + + System.out.println("Created a Windows VM" + windowsVM.id()); + Utils.print(windowsVM); + + //============================================================= + // Add a second admin user to Windows VM using VMAccess extension + + windowsVM.update() + .defineNewExtension(windowsVmAccessExtensionName) + .withPublisher(windowsVmAccessExtensionPublisherName) + .withType(windowsVmAccessExtensionTypeName) + .withVersion(windowsVmAccessExtensionVersionName) + .withProtectedSetting("username", secondWindowsUserName) + .withProtectedSetting("password", secondWindowsUserPassword) + .attach() + .apply(); + + System.out.println("Added a second admin user to the Windows VM"); + + //============================================================= + // Add a third admin user to Windows VM by updating VMAccess extension + + windowsVM.update() + .updateExtension(windowsVmAccessExtensionName) + .withProtectedSetting("username", thirdWindowsUserName) + .withProtectedSetting("password", thirdWindowsUserPassword) + .parent() + .apply(); + + System.out.println("Added a third admin user to the Windows VM"); + + //============================================================= + // Reset admin password of first user of Windows VM by updating VMAccess extension + + windowsVM.update() + .updateExtension(windowsVmAccessExtensionName) + .withProtectedSetting("username", firstWindowsUserName) + .withProtectedSetting("password", firstWindowsUserNewPassword) + .parent() + .apply(); + + System.out.println("Password of first user of Windows VM has been updated"); + + //============================================================= + // Removes the extensions from Linux VM + + windowsVM.update() + .withoutExtension(windowsVmAccessExtensionName) + .apply(); + System.out.println("Removed the VM Access extensions from Windows VM"); + Utils.print(windowsVM); + + } catch (Exception f) { + + System.out.println(f.getMessage()); + f.printStackTrace(); + + } finally { + try { + System.out.println("Deleting Resource Group: " + rgName); + azure.resourceGroups().delete(rgName); + System.out.println("Deleted Resource Group: " + rgName); + } catch (NullPointerException npe) { + System.out.println("Did not create any resources in Azure. No clean up is necessary"); + } catch (Exception g) { + g.printStackTrace(); + } + } + } catch (Exception e) { + System.out.println(e.getMessage()); + e.printStackTrace(); + } + } + + private ManageVirtualMachineExtension() { + + } +} diff --git a/azure-samples/src/main/java/com/microsoft/azure/management/samples/Utils.java b/azure-samples/src/main/java/com/microsoft/azure/management/samples/Utils.java index 8ecf6daf320c..b1881647ca9b 100644 --- a/azure-samples/src/main/java/com/microsoft/azure/management/samples/Utils.java +++ b/azure-samples/src/main/java/com/microsoft/azure/management/samples/Utils.java @@ -11,6 +11,7 @@ import com.microsoft.azure.management.compute.AvailabilitySet; import com.microsoft.azure.management.compute.VirtualMachine; import com.microsoft.azure.management.compute.DataDisk; +import com.microsoft.azure.management.compute.VirtualMachineExtension; import com.microsoft.azure.management.network.Network; import com.microsoft.azure.management.network.NetworkInterface; import com.microsoft.azure.management.network.NetworkSecurityGroup; @@ -23,6 +24,7 @@ import java.io.IOException; import java.util.Calendar; import java.util.List; +import java.util.Map; import java.util.UUID; /** @@ -116,6 +118,21 @@ public static void print(VirtualMachine resource) { networkProfile.append("\n\t\tId:").append(networkInterfaceId); } + StringBuilder extensions = new StringBuilder().append("\n\tExtensions: "); + for (Map.Entry extensionEntry : resource.extensions().entrySet()) { + VirtualMachineExtension extension = extensionEntry.getValue(); + extensions.append("\n\t\tExtension: ").append(extension.id()) + .append("\n\t\t\tName: ").append(extension.name()) + .append("\n\t\t\tTags: ").append(extension.tags()) + .append("\n\t\t\tProvisioningState: ").append(extension.provisioningState()) + .append("\n\t\t\tAuto upgrade minor version enabled: ").append(extension.autoUpgradeMinorVersionEnabled()) + .append("\n\t\t\tPublisher: ").append(extension.publisherName()) + .append("\n\t\t\tType: ").append(extension.typeName()) + .append("\n\t\t\tVersion: ").append(extension.versionName()) + .append("\n\t\t\tPublic Settings: ").append(extension.publicSettingsAsJsonString()); + } + + System.out.println(new StringBuilder().append("Virtual Machine: ").append(resource.id()) .append("Name: ").append(resource.name()) .append("\n\tResource group: ").append(resource.resourceGroupName()) @@ -126,6 +143,7 @@ public static void print(VirtualMachine resource) { .append(storageProfile) .append(osProfile) .append(networkProfile) + .append(extensions) .toString()); } @@ -268,14 +286,11 @@ public static void print(StorageAccount storageAccount) { * @param storageAccountKeys a list of storage account keys */ public static void print(List storageAccountKeys) { - StorageAccountKey storageAccountKey; - for (int i = 0; i < storageAccountKeys.size(); i++) { - storageAccountKey = (StorageAccountKey) storageAccountKeys.get(i); + StorageAccountKey storageAccountKey = storageAccountKeys.get(i); System.out.println("Key (" + i + ") " + storageAccountKey.keyName() + "=" + storageAccountKey.value()); } - } /**