diff --git a/lib/fog/azurerm/compute.rb b/lib/fog/azurerm/compute.rb index 873e12215..41231caa9 100644 --- a/lib/fog/azurerm/compute.rb +++ b/lib/fog/azurerm/compute.rb @@ -44,6 +44,11 @@ class AzureRM < Fog::Service request :create_image request :delete_image request :get_image + request :create_or_update_snapshot + request :list_snapshots_by_rg + request :list_snapshots_in_subscription + request :get_snapshot + request :delete_snapshot model_path 'fog/azurerm/models/compute' model :availability_set @@ -54,6 +59,8 @@ class AzureRM < Fog::Service collection :virtual_machine_extensions model :managed_disk collection :managed_disks + model :snapshot + collection :snapshots model :data_disk model :creation_data model :disk_create_option diff --git a/lib/fog/azurerm/constants.rb b/lib/fog/azurerm/constants.rb index ae3969906..61e8a9867 100755 --- a/lib/fog/azurerm/constants.rb +++ b/lib/fog/azurerm/constants.rb @@ -18,6 +18,7 @@ RESOURCE_NAME = 8 ENDPOINT_PREFIX = 'Microsoft.Network/trafficManagerProfiles'.freeze DISK_PREFIX = 'Microsoft.Compute/disks'.freeze +SNAPSHOT_PREFIX = 'Microsoft.Compute/snapshots'.freeze AZURE_ENDPOINTS = 'azureEndpoints'.freeze EXTERNAL_ENDPOINTS = 'externalEndpoints'.freeze NESTED_ENDPOINTS = 'nestedEndpoints'.freeze diff --git a/lib/fog/azurerm/docs/compute.md b/lib/fog/azurerm/docs/compute.md index 2d6d5e9c8..9a05e9ce7 100644 --- a/lib/fog/azurerm/docs/compute.md +++ b/lib/fog/azurerm/docs/compute.md @@ -2,7 +2,7 @@ This document explains how to get started using Azure Compute Service with Fog. With this gem you can create, update, list or delete availability sets and virtual machines. -## Usage +## Usage First of all, you need to require the Fog library by executing: @@ -50,7 +50,7 @@ fog_compute_service.servers.create( username: '', disable_password_authentication: , network_interface_card_ids: ['/subscriptions//resourceGroups//providers/Microsoft.Network/networkInterfaces/'], - publisher: '', # Not required if custom image is being used + publisher: '', # Not required if custom image is being used offer: '', # Not required if custom image is being used sku: '', # Not required if custom image is being used version: '', # Not required if custom image is being used @@ -116,7 +116,7 @@ fog_compute_service.servers.create( disable_password_authentication: , network_interface_card_ids: ['/subscriptions//resourceGroups//providers/Microsoft.Network/networkInterfaces/'], publisher: '', # Not required if custom image is being used - offer: '', # Not required if custom image is being used + offer: '', # Not required if custom image is being used sku: '', # Not required if custom image is being used version: '', # Not required if custom image is being used platform: '', @@ -142,11 +142,11 @@ async_response = fog_compute_service.servers.create_async( username: '', disable_password_authentication: , network_interface_card_ids: ['/subscriptions//resourceGroups//providers/Microsoft.Network/networkInterfaces/'], - publisher: '', # Not required if custom image is being used + publisher: '', # Not required if custom image is being used offer: '', # Not required if custom image is being used sku: '', # Not required if custom image is being used version: '' , # Not required if custom image is being used - platform: '', + platform: '', availability_set_id: '', # [Optional] password: '', # [Optional], if 'platform' partameter is 'Linux'. vhd_path: '', # [Optional], if you want to create the VM from a custom image. @@ -169,7 +169,7 @@ An example of handling async response is given below: ```ruby while 1 puts async_response.state - + if async_response.pending? sleep(2) end @@ -185,7 +185,7 @@ while 1 end end ``` - + For more information about custom_data, see link: https://msdn.microsoft.com/en-us/library/azure/mt163591.aspx ## List Servers @@ -215,7 +215,7 @@ puts "#{server.name}" Check the status of a Server -```ruby +```ruby status = fog_compute_service .servers .get('', '') @@ -301,7 +301,7 @@ List managed disks in a resource group ```ruby managed_disks = fog_compute_service.managed_disks(resource_group: '') -mnaged_disks.each do |disk| +managed_disks.each do |disk| puts "#{disk.name}" puts "#{disk.location}" end @@ -361,6 +361,47 @@ Get an managed disk object from the get method and then destroy that managed dis managed_disk.destroy ``` +## List Snapshots in a Resource Group + +List Snapshots in a Resource Group + +```ruby +snapshots = fog_compute_service.snapshots(resource_group: '') +snapshots.each do |snap| + puts "#{snap.name}" + puts "#{snap.location}" +end +``` + +## List Snapshots in a Subscription + +List Snapshots in a subscription + +```ruby +snapshots = fog_compute_service.snapshots +snapshots.each do |snap| + puts "#{snap.name}" + puts "#{snap.location} +end +``` + +## Get one Snapshot in a Resource Group + +get one Snapshot in a Resource Group + +```ruby +snap = fog_compute_service.snapshots.get('', 'snapshot-name') +puts "#{snap.name}" +puts "#{snap.location} +``` + +## Destroy a Snapshot +Destroy a Snapshot + +```ruby +snapshot.destroy +``` + ## Check Availability Set Existence ```ruby @@ -381,7 +422,7 @@ fog_compute_service.availability_sets.create( use_managed_disk: true # [Optional] Possible values true or false ) ``` -## List Availability Sets +## List Availability Sets List availability sets in a resource group diff --git a/lib/fog/azurerm/models/compute/snapshot.rb b/lib/fog/azurerm/models/compute/snapshot.rb new file mode 100644 index 000000000..77db3a416 --- /dev/null +++ b/lib/fog/azurerm/models/compute/snapshot.rb @@ -0,0 +1,95 @@ +module Fog + module Compute + class AzureRM + # This class is giving implementation of create/save and + # delete/destroy for snapshot. + class Snapshot < Fog::Model + attribute :id + identity :name + attribute :location + attribute :resource_group_name + attribute :account_type + attribute :disk_size_gb + attribute :tags + attribute :time_created + attribute :creation_data + attribute :encryption_settings + attribute :type + attribute :owner_id + attribute :provisioning_state + attribute :os_type + + def self.parse(snapshot) + snap = get_hash_from_object(snapshot) + + snap['creation_data'] = parse_creation_data(snapshot.creation_data) unless snapshot.creation_data.nil? + + snap['encryption_settings'] = parse_encryption_settings_object(snapshot.encryption_settings) unless snapshot.encryption_settings.nil? + + snap['resource_group_name'] = get_resource_group_from_id(snapshot.id) + + snap + end + + def destroy(async = false) + response = service.delete_snapshot(resource_group_name, name, async) + async ? create_fog_async_response(response) : response + end + + def creation_data=(new_creation_data) + attributes[:creation_data] = + if new_creation_data.is_a?(Hash) + creation_data = Fog::Compute::AzureRM::CreationData.new + creation_data.merge_attributes(new_creation_data) + else + new_creation_data + end + end + + def self.parse_creation_data(azure_sdk_creation_data) + creation_data = Fog::Compute::AzureRM::CreationData.new + creation_data.merge_attributes(Fog::Compute::AzureRM::CreationData.parse(azure_sdk_creation_data)) + end + + def self.parse_encryption_settings_object(azure_sdk_encryption_settings) + encryption_settings = Fog::Compute::AzureRM::EncryptionSettings.new + encryption_settings.merge_attributes(Fog::Compute::AzureRM::EncryptionSettings.parse(azure_sdk_encryption_settings)) + end + + private_class_method :parse_creation_data, :parse_encryption_settings_object + + def save + requires :name, :location, :resource_group_name, :creation_data + validate_creation_data_params(creation_data) + + snapshot = service.create_or_update_snapshot(snapshot_params) + merge_attributes(Fog::Compute::AzureRM::Snapshot.parse(snapshot)) + end + + private + + def validate_creation_data_params(creation_data) + if !creation_data || creation_data.create_option.nil? + raise(ArgumentError, 'creation_data.create_option is required for this operation') + end + end + + def snapshot_params + { + name: name, + location: location, + resource_group_name: resource_group_name, + tags: tags, + creation_data: creation_data.attributes, + encryption_settings: encryption_settings + } + end + + def create_fog_async_response(response, delete_extra_resource = false) + snapshot = Fog::Compute::AzureRM::Snapshot.new(service: service) + Fog::AzureRM::AsyncResponse.new(snapshot, response, delete_extra_resource) + end + end + end + end +end diff --git a/lib/fog/azurerm/models/compute/snapshots.rb b/lib/fog/azurerm/models/compute/snapshots.rb new file mode 100644 index 000000000..f6f6573a7 --- /dev/null +++ b/lib/fog/azurerm/models/compute/snapshots.rb @@ -0,0 +1,30 @@ +module Fog + module Compute + class AzureRM + # This class is giving implementation of all/list, get and + # check existence for snapshots of managed disk. + class Snapshots < Fog::Collection + model Fog::Compute::AzureRM::Snapshot + attribute :resource_group + + def all + snapshots = if resource_group.nil? + service.list_snapshots_in_subscription + else + requires :resource_group + service.list_snapshots_by_rg(resource_group) + end + snapshots = snapshots.map { |snapshot| Fog::Compute::AzureRM::Snapshot.parse snapshot } + + load(snapshots) + end + + def get(resource_group_name, snap_name) + snapshot = service.get_snapshot(resource_group_name, snap_name) + snapshot_fog = Fog::Compute::AzureRM::Snapshot.new(service: service) + snapshot_fog.merge_attributes(Fog::Compute::AzureRM::Snapshot.parse(snapshot)) + end + end + end + end +end diff --git a/lib/fog/azurerm/requests/compute/create_or_update_snapshot.rb b/lib/fog/azurerm/requests/compute/create_or_update_snapshot.rb new file mode 100644 index 000000000..0bdf83f71 --- /dev/null +++ b/lib/fog/azurerm/requests/compute/create_or_update_snapshot.rb @@ -0,0 +1,111 @@ +module Fog + module Compute + class AzureRM + # Real class for Compute Request + class Real + def create_or_update_snapshot(snapshot_params) + msg = "Creating/Updating snapshot: #{snapshot_params[:name]}" + Fog::Logger.debug msg + snapshot = get_snapshot_object(snapshot_params) + begin + snapshot = @compute_mgmt_client.snapshots.create_or_update(snapshot_params[:resource_group_name], snapshot_params[:name], snapshot) + rescue MsRestAzure::AzureOperationError => e + raise_azure_exception(e, msg) + end + Fog::Logger.debug "Snapshot #{snapshot_params[:name]} created/updated successfully." + snapshot + end + + private + + def get_snapshot_object(snapshot_params) + snapshot = Azure::ARM::Compute::Models::Snapshot.new + snapshot.name = snapshot_params[:name] + snapshot.type = SNAPSHOT_PREFIX + snapshot.location = snapshot_params[:location] + snapshot.tags = snapshot_params[:tags] unless snapshot.tags.nil? + + creation_data = snapshot_params[:creation_data] + snapshot.creation_data = get_creation_data_object(creation_data) unless creation_data.nil? + + encryption_settings = snapshot_params[:encryption_settings] + snapshot.encryption_settings = get_encryption_settings_object(encryption_settings) unless encryption_settings.nil? + + snapshot + end + + def get_creation_data_object(data) + creation_data = Azure::ARM::Compute::Models::CreationData.new + creation_data.create_option = data[:create_option] + creation_data.storage_account_id = data[:storage_account_id] + creation_data.source_uri = data[:source_uri] + creation_data.source_resource_id = data[:source_resource_id] + + creation_data + end + + def get_encryption_settings_object(settings) + encryption_settings = Azure::ARM::Compute::Models::EncryptionSettings.new + disk_encryption_key = Azure::ARM::Compute::Models::KeyVaultAndSecretReference.new + disk_encryption_key.secret_url = settings[:secret_url] + disk_encryption_key.source_vault.id = settings[:disk_source_vault_id] + encryption_settings.disk_encryption_key = disk_encryption_key + + encryption_settings.enabled = settings[:enabled] + + key_encryption_key = Azure::ARM::Compute::Models::KeyVaultAndKeyReference.new + key_encryption_key.key_url = settings[:key_uri] + key_encryption_key.source_vault = settings[:key_source_vault_id] + encryption_settings.key_encryption_key = key_encryption_key + + encryption_settings + end + end + + # Mock class for Compute Request + class Mock + def create_or_update_snapshot(*) + snapshot = { + 'accountType' => 'Standard_LRS', + 'properties' => { + 'osType' => 'Windows', + 'creationData' => { + 'createOption' => 'Copy', + 'sourceUri' => '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/disks/myManagedDisk1' + }, + 'diskSizeGB' => 10, + 'encryptionSettings' => { + 'enabled' => true, + 'diskEncryptionKey' => { + 'sourceVault' => { + 'id' => '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault' + }, + 'secretUrl' => 'https://myvmvault.vault-int.azure-int.net/secrets/{secret}' + }, + 'keyEncryptionKey' => { + 'sourceVault' => { + 'id' => '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault' + }, + 'keyUrl' => 'https://myvmvault.vault-int.azure-int.net/keys/{key}' + } + }, + 'timeCreated' => '2016-12-28T02:46:21.3322041+00:00', + 'provisioningState' => 'Succeeded', + 'diskState' => 'Unattached' + }, + 'type' => 'Microsoft.Compute/snapshots', + 'location' => 'westus', + 'tags' => { + 'department' => 'Development', + 'project' => 'Snapshots' + }, + 'id' => '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1', + 'name' => 'mySnapshot' + } + snapshot_mapper = Azure::ARM::Compute::Models::Snapshot.mapper + @compute_mgmt_client.deserialize(snapshot_mapper, snapshot, 'result.body') + end + end + end + end +end diff --git a/lib/fog/azurerm/requests/compute/delete_snapshot.rb b/lib/fog/azurerm/requests/compute/delete_snapshot.rb new file mode 100644 index 000000000..7a3e4d232 --- /dev/null +++ b/lib/fog/azurerm/requests/compute/delete_snapshot.rb @@ -0,0 +1,37 @@ + +module Fog + module Compute + class AzureRM + # Real class for Compute Request + class Real + def delete_snapshot(resource_group_name, snapshot_name, async = false) + msg = "Deleting Snapshot: #{snapshot_name}" + Fog::Logger.debug msg + begin + if async + response = @compute_mgmt_client.snapshots.delete_async(resource_group_name, snapshot_name) + else + @compute_mgmt_client.snapshots.delete(resource_group_name, snapshot_name) + end + rescue MsRestAzure::AzureOperationError => e + raise_azure_exception(e, msg) + end + if async + response + else + Fog::Logger.debug "Snapshot #{snapshot_name} deleted successfully." + true + end + end + end + + # Mock class for Compute Request + class Mock + def delete_snapshot(_resource_group_name, snapshot_name) + Fog::Logger.debug "Snapshot #{snapshot_name} deleted successfully." + true + end + end + end + end +end diff --git a/lib/fog/azurerm/requests/compute/get_snapshot.rb b/lib/fog/azurerm/requests/compute/get_snapshot.rb new file mode 100644 index 000000000..357f1afcb --- /dev/null +++ b/lib/fog/azurerm/requests/compute/get_snapshot.rb @@ -0,0 +1,65 @@ +module Fog + module Compute + class AzureRM + # Real class for Compute Request + class Real + def get_snapshot(resource_group_name, snap_name) + msg = "Getting Snapshot: #{snap_name}" + Fog::Logger.debug msg + begin + snapshot = @compute_mgmt_client.snapshots.get(resource_group_name, snap_name) + rescue MsRestAzure::AzureOperationError => e + raise_azure_exception(e, msg) + end + Fog::Logger.debug "Snapshot #{snap_name} returned successfully." + snapshot + end + end + + # Mock class for Compute Request + class Mock + def get_snapshot(*) + snapshots = { + 'accountType' => 'Standard_LRS', + 'properties' => { + 'osType' => 'Windows', + 'creationData' => { + 'createOption' => 'Copy', + 'sourceUri' => '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/disks/myManagedDisk1' + }, + 'diskSizeGB' => 10, + 'encryptionSettings' => { + 'enabled' => true, + 'diskEncryptionKey' => { + 'sourceVault' => { + 'id' => '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault' + }, + 'secretUrl' => 'https://myvmvault.vault-int.azure-int.net/secrets/{secret}' + }, + 'keyEncryptionKey' => { + 'sourceVault' => { + 'id' => '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault' + }, + 'keyUrl' => 'https://myvmvault.vault-int.azure-int.net/keys/{key}' + } + }, + 'timeCreated' => '2016-12-28T02:46:21.3322041+00:00', + 'provisioningState' => 'Succeeded', + 'diskState' => 'Unattached' + }, + 'type' => 'Microsoft.Compute/snapshots', + 'location' => 'westus', + 'tags' => { + 'department' => 'Development', + 'project' => 'Snapshots' + }, + 'id' => '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1', + 'name' => 'mySnapshot' + } + snapshot_mapper = Azure::ARM::Compute::Models::Snapshot.mapper + @compute_mgmt_client.deserialize(snapshot_mapper, snapshots, 'result.body') + end + end + end + end +end diff --git a/lib/fog/azurerm/requests/compute/list_snapshots_by_rg.rb b/lib/fog/azurerm/requests/compute/list_snapshots_by_rg.rb new file mode 100644 index 000000000..3d1d945d0 --- /dev/null +++ b/lib/fog/azurerm/requests/compute/list_snapshots_by_rg.rb @@ -0,0 +1,67 @@ +module Fog + module Compute + class AzureRM + # Real class for Compute Request + class Real + def list_snapshots_by_rg(resource_group_name) + msg = "Listing all Snapshots in resource group: #{resource_group_name}" + Fog::Logger.debug msg + begin + snapshots = @compute_mgmt_client.snapshots.list_by_resource_group(resource_group_name) + rescue MsRestAzure::AzureOperationError => e + raise_azure_exception(e, msg) + end + Fog::Logger.debug 'Snapshots listed successfully.' + snapshots + end + end + + # Mock class for Compute Request + class Mock + def list_snapshots_by_rg(*) + snapshots = [ + { + 'accountType' => 'Standard_LRS', + 'properties' => { + 'osType' => 'Windows', + 'creationData' => { + 'createOption' => 'Copy', + 'sourceUri' => '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/disks/myManagedDisk1' + }, + 'diskSizeGB' => 10, + 'encryptionSettings' => { + 'enabled' => true, + 'diskEncryptionKey' => { + 'sourceVault' => { + 'id' => '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault' + }, + 'secretUrl' => 'https://myvmvault.vault-int.azure-int.net/secrets/{secret}' + }, + 'keyEncryptionKey' => { + 'sourceVault' => { + 'id' => '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault' + }, + 'keyUrl' => 'https://myvmvault.vault-int.azure-int.net/keys/{key}' + } + }, + 'timeCreated' => '2016-12-28T02:46:21.3322041+00:00', + 'provisioningState' => 'Succeeded', + 'diskState' => 'Unattached' + }, + 'type' => 'Microsoft.Compute/snapshots', + 'location' => 'westus', + 'tags' => { + 'department' => 'Development', + 'project' => 'Snapshots' + }, + 'id' => '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1', + 'name' => 'mySnapshot' + } + ] + snapshot_mapper = Azure::ARM::Compute::Models::SnapshotList.mapper + @compute_mgmt_client.deserialize(snapshot_mapper, snapshots, 'result.body').value + end + end + end + end +end diff --git a/lib/fog/azurerm/requests/compute/list_snapshots_in_subscription.rb b/lib/fog/azurerm/requests/compute/list_snapshots_in_subscription.rb new file mode 100644 index 000000000..72a7546db --- /dev/null +++ b/lib/fog/azurerm/requests/compute/list_snapshots_in_subscription.rb @@ -0,0 +1,67 @@ +module Fog + module Compute + class AzureRM + # Real class for Compute Request + class Real + def list_snapshots_in_subscription + msg = 'Listing all Snapshots' + Fog::Logger.debug msg + begin + snapshots = @compute_mgmt_client.snapshots.list + rescue MsRestAzure::AzureOperationError => e + raise_azure_exception(e, msg) + end + Fog::Logger.debug 'Snapshots listed successfully.' + snapshots + end + end + + # Mock class for Compute Request + class Mock + def list_snapshots_in_subscription + snapshots = [ + { + 'accountType' => 'Standard_LRS', + 'properties' => { + 'osType' => 'Windows', + 'creationData' => { + 'createOption' => 'Copy', + 'sourceUri' => '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/disks/myManagedDisk1' + }, + 'diskSizeGB' => 10, + 'encryptionSettings' => { + 'enabled' => true, + 'diskEncryptionKey' => { + 'sourceVault' => { + 'id' => '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault' + }, + 'secretUrl' => 'https://myvmvault.vault-int.azure-int.net/secrets/{secret}' + }, + 'keyEncryptionKey' => { + 'sourceVault' => { + 'id' => '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault' + }, + 'keyUrl' => 'https://myvmvault.vault-int.azure-int.net/keys/{key}' + } + }, + 'timeCreated' => '2016-12-28T02:46:21.3322041+00:00', + 'provisioningState' => 'Succeeded', + 'diskState' => 'Unattached' + }, + 'type' => 'Microsoft.Compute/snapshots', + 'location' => 'westus', + 'tags' => { + 'department' => 'Development', + 'project' => 'Snapshots' + }, + 'id' => '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1', + 'name' => 'mySnapshot' + } + ] + snapshot_mapper = Azure::ARM::Compute::Models::SnapshotList.mapper + @compute_mgmt_client.deserialize(snapshot_mapper, snapshots, 'result.body').value + end + end + end + end +end diff --git a/test/api_stub.rb b/test/api_stub.rb index 9b02ded1e..45d0c2fc5 100644 --- a/test/api_stub.rb +++ b/test/api_stub.rb @@ -7,6 +7,7 @@ module Compute autoload :AvailabilitySet, File.expand_path('api_stub/models/compute/availability_set', __dir__) autoload :VirtualMachineExtension, File.expand_path('api_stub/models/compute/virtual_machine_extension', __dir__) autoload :ManagedDisk, File.expand_path('api_stub/models/compute/managed_disk', __dir__) + autoload :Snapshot, File.expand_path('api_stub/models/compute/snapshot', __dir__) end # Load test Resources models @@ -79,6 +80,7 @@ module Compute autoload :VirtualMachineExtension, File.expand_path('api_stub/requests/compute/virtual_machine_extension', __dir__) autoload :ManagedDisk, File.expand_path('api_stub/requests/compute/managed_disk', __dir__) autoload :Image, File.expand_path('api_stub/requests/compute/image', __dir__) + autoload :Snapshot, File.expand_path('api_stub/requests/compute/snapshot', __dir__) end # Load test Resources requests diff --git a/test/api_stub/models/compute/snapshot.rb b/test/api_stub/models/compute/snapshot.rb new file mode 100644 index 000000000..f18c05beb --- /dev/null +++ b/test/api_stub/models/compute/snapshot.rb @@ -0,0 +1,50 @@ +module ApiStub + module Models + module Compute + # Mock class for Snapshot Model + class Snapshot + def self.create_snapshot_response(sdk_compute_client) + snap = { + 'accountType' => 'Standard_LRS', + 'properties' => { + 'osType' => 'Windows', + 'creationData' => { + 'createOption' => 'Copy', + 'sourceResourceId' => 'subscriptions/subscriptionId/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot' + }, + 'diskSizeGB' => 200, + 'encryptionSettings' => { + 'enabled' => true, + 'diskEncryptionKey' => { + 'sourceVault' => { + 'id' => '/subscriptions/subscriptionId/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault' + }, + 'secretUrl' => 'https://myvmvault.vault-int.azure-int.net/secrets/secret' + }, + 'keyEncryptionKey' => { + 'sourceVault' => { + 'id' => '/subscriptions/subscriptionId/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault' + }, + 'keyUrl' => 'https://myvmvault.vault-int.azure-int.net/keys/key' + } + }, + 'timeCreated' => '2016-12-28T04:41:35.9278721+00:00', + 'provisioningState' => 'Succeeded', + 'diskState' => 'Unattached' + }, + 'type' => 'Microsoft.Compute/snapshots', + 'location' => 'westus', + 'tags' => { + 'department' => 'Development', + 'project' => 'Snapshots' + }, + 'id' => '/subscriptions/subscriptionId/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot', + 'name' => 'mySnapshot' + } + result_mapper = Azure::ARM::Compute::Models::Snapshot.mapper + sdk_compute_client.deserialize(result_mapper, snap, 'result.body') + end + end + end + end +end diff --git a/test/api_stub/requests/compute/snapshot.rb b/test/api_stub/requests/compute/snapshot.rb new file mode 100644 index 000000000..0eb0fd653 --- /dev/null +++ b/test/api_stub/requests/compute/snapshot.rb @@ -0,0 +1,129 @@ +module ApiStub + module Requests + module Compute + # Mock class for Snapshot Requests + class Snapshot + def self.create_snapshot_response(sdk_compute_client) + body = '{ + "name": "mySnapshot2", + "location": "West US", + "properties": { + "creationData": { + "createOption": "Copy", + "sourceResourceId": "subscriptions/subscriptionId/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1" + } + } + }' + snap_mapper = Azure::ARM::Compute::Models::Snapshot.mapper + sdk_compute_client.deserialize(snap_mapper, Fog::JSON.decode(body), 'result.body') + end + + def self.update_snapshot_response(sdk_compute_client) + body = '{ + "accountType": "Standard_LRS", + "tags": { + "tagName": "tagValue" + }, + "properties": { + "diskSizeGB": "256" + } + }' + snap_mapper = Azure::ARM::Compute::Models::Snapshot.mapper + sdk_compute_client.deserialize(snap_mapper, Fog::JSON.decode(body), 'result.body') + end + + def self.get_snapshot_response(sdk_compute_client) + body = '{"accountType": "Standard_LRS", + "properties": { + "osType": "Windows", + "creationData": { + "createOption": "Copy", + "sourceResourceId": "subscriptions/subscriptionId/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot" + }, + "diskSizeGB": 200, + "encryptionSettings": { + "enabled": true, + "diskEncryptionKey": { + "sourceVault": { + "id": "/subscriptions/subscriptionId/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault" + }, + "secretUrl": "https://myvmvault.vault-int.azure-int.net/secrets/secret" + }, + "keyEncryptionKey": { + "sourceVault": { + "id": "/subscriptions/subscriptionId/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault" + }, + "keyUrl": "https://myvmvault.vault-int.azure-int.net/keys/key" + } + }, + "timeCreated": "2016-12-28T04:41:35.9278721+00:00", + "provisioningState": "Succeeded", + "diskState": "Unattached" + }, + "type": "Microsoft.Compute/snapshots", + "location": "westus", + "tags": { + "department": "Development", + "project": "Snapshots" + }, + "id": "/subscriptions/subscriptionId/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot", + "name": "mySnapshot"}' + snap_mapper = Azure::ARM::Compute::Models::Snapshot.mapper + sdk_compute_client.deserialize(snap_mapper, Fog::JSON.decode(body), 'result.body') + end + + def self.get_snapshots_response(sdk_compute_client) + body = '{"value": [{ + "accountType": "Standard_LRS", + "properties": { + "osType": "Windows", + "creationData": { + "createOption": "Copy", + "sourceResourceId": "subscriptions/subscriptionId/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot" + }, + "diskSizeGB": 200, + "encryptionSettings": { + "enabled": true, + "diskEncryptionKey": { + "sourceVault": { + "id": "/subscriptions/subscriptionId/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault" + }, + "secretUrl": "https://myvmvault.vault-int.azure-int.net/secrets/secret" + }, + "keyEncryptionKey": { + "sourceVault": { + "id": "/subscriptions/subscriptionId/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault" + }, + "keyUrl": "https://myvmvault.vault-int.azure-int.net/keys/key" + } + }, + "timeCreated": "2016-12-28T04:47:30.6630569+00:00", + "provisioningState": "Succeeded", + "diskState": "Unattached" + }, + "type": "Microsoft.Compute/snapshots", + "location": "westus", + "tags": { + "department": "Development", + "project": "Snapshots" + }, + "id": "/subscriptions/subscriptionId/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1", + "name": "mySnapshot1" + }] }' + snap_mapper = Azure::ARM::Compute::Models::Snapshot.mapper + sdk_compute_client.deserialize(snap_mapper, Fog::JSON.decode(body), 'result.body') + end + + def self.operation_status_response(sdk_compute_client) + response = { + 'name' => 'xxxx-xxxxx-xxxx', + 'status' => 'success', + 'error' => 'ERROR' + } + response_mapper = Azure::ARM::Compute::Models::OperationStatusResponse.mapper + sdk_compute_client.deserialize(response_mapper, response, 'result.body') + end + end + end + end +end diff --git a/test/models/compute/test_snapshot.rb b/test/models/compute/test_snapshot.rb new file mode 100644 index 000000000..23f64acf7 --- /dev/null +++ b/test/models/compute/test_snapshot.rb @@ -0,0 +1,96 @@ +require File.expand_path '../../test_helper', __dir__ + +# Test class for Managed Disk Model +class TestSnapshot < Minitest::Test + def setup + @service = Fog::Compute::AzureRM.new(credentials) + @snapshot = snapshot(@service) + compute_client = @service.instance_variable_get(:@compute_mgmt_client) + @response = ApiStub::Requests::Compute::Snapshot.get_snapshot_response(compute_client) + end + + def test_model_attributes + attributes = %i( + id + name + type + location + resource_group_name + account_type + time_created + os_type + disk_size_gb + owner_id + provisioning_state + tags + creation_data + encryption_settings + tags + ) + attributes.each do |attribute| + assert_respond_to @snapshot, attribute + end + end + + def test_model_methods + methods = [ + :destroy + ] + methods.each do |method| + assert_respond_to @snapshot, method + end + end + + def test_parse_method + snap_hash = Fog::Compute::AzureRM::Snapshot.parse(@response) + @response.instance_variables.each do |attribute| + case attribute + when :@creation_data + assert_kind_of Fog::Compute::AzureRM::CreationData, snap_hash['creation_data'] + when :@encryption_settings + assert_kind_of Fog::Compute::AzureRM::EncryptionSettings, snap_hash['encryption_settings'] + else + assert_equal @response.instance_variable_get(attribute), snap_hash[attribute.to_s.delete('@')] + end + end + end + + def test_creation_data_assign_with_objet + snap_hash = Fog::Compute::AzureRM::Snapshot.parse(@response) + fog_snap = Fog::Compute::AzureRM::Snapshot.new + creation_data = snap_hash['creation_data'] + assert_kind_of Fog::Compute::AzureRM::CreationData, creation_data + fog_snap.creation_data = creation_data + # test assign is successsed + assert_equal fog_snap.creation_data.source_resource_id, creation_data.source_resource_id + end + + def test_creation_data_assign_with_hash + snap_hash = Fog::Compute::AzureRM::Snapshot.parse(@response) + fog_snap = Fog::Compute::AzureRM::Snapshot.new + creation_data = snap_hash['creation_data'] + data_hash = get_hash_from_object(creation_data)['attributes'] + fog_snap.creation_data = data_hash + # test assign is successsed + assert_equal fog_snap.creation_data.source_resource_id, creation_data.source_resource_id + end + + def test_destroy_method_true_response + @service.stub :delete_snapshot, true do + assert @snapshot.destroy + end + end + + def test_destroy_async_method_response + async_response = Concurrent::Promise.execute { 10 } + @service.stub :delete_snapshot, async_response do + assert_instance_of Fog::AzureRM::AsyncResponse, @snapshot.destroy(async: true) + end + end + + def test_destroy_method_false_response + @service.stub :delete_snapshot, false do + assert !@snapshot.destroy + end + end +end diff --git a/test/models/compute/test_snapshots.rb b/test/models/compute/test_snapshots.rb new file mode 100644 index 000000000..997fca783 --- /dev/null +++ b/test/models/compute/test_snapshots.rb @@ -0,0 +1,39 @@ +require File.expand_path '../../test_helper', __dir__ + +# Test class for Snapshots Collection +class TestSnapshots < Minitest::Test + def setup + @service = Fog::Compute::AzureRM.new(credentials) + @snapshots = Fog::Compute::AzureRM::Snapshots.new(resource_group: 'fog-test-rg', service: @service) + @client = @service.instance_variable_get(:@compute_mgmt_client) + @snapshot_list = [ApiStub::Models::Compute::Snapshot.create_snapshot_response(@client)] + @snapshot = ApiStub::Models::Compute::Snapshot.create_snapshot_response(@client) + end + + def test_collection_methods + methods = %i(all get) + methods.each do |method| + assert_respond_to @snapshots, method + end + end + + def test_collection_attributes + assert_respond_to @snapshots, :resource_group + end + + def test_all_method_response + @service.stub :list_snapshots_by_rg, @snapshot_list do + assert_instance_of Fog::Compute::AzureRM::Snapshots, @snapshots.all + assert @snapshots.all.size >= 1 + @snapshots.all.each do |disk| + assert_instance_of Fog::Compute::AzureRM::Snapshot, disk + end + end + end + + def test_get_method_response + @service.stub :get_snapshot, @snapshot do + assert_instance_of Fog::Compute::AzureRM::Snapshot, @snapshots.get('fog-test-rg', 'fog-test-snapshot') + end + end +end diff --git a/test/requests/compute/test_delete_snapshot.rb b/test/requests/compute/test_delete_snapshot.rb new file mode 100644 index 000000000..b8028d9f5 --- /dev/null +++ b/test/requests/compute/test_delete_snapshot.rb @@ -0,0 +1,30 @@ +require File.expand_path '../../test_helper', __dir__ + +# Test class for Delete Snapshot Request +class TestDeleteSnapshot < Minitest::Test + def setup + @service = Fog::Compute::AzureRM.new(credentials) + client = @service.instance_variable_get(:@compute_mgmt_client) + @snapshot = client.snapshots + end + + def test_delete_snapshot_success + @snapshot.stub :delete, true do + assert @service.delete_snapshot('fog-test-rg', 'test-disk') + end + end + + def test_delete_snapshot_failure + response = proc { raise MsRestAzure::AzureOperationError.new(nil, nil, 'error' => { 'message' => 'mocked exception' }) } + @snapshot.stub :delete, response do + assert_raises(RuntimeError) { @service.delete_snapshot('fog-test-rg', 'test-disk') } + end + end + + def test_delete_snapshot_async + async_response = Concurrent::Promise.execute { 10 } + @snapshot.stub :delete_async, async_response do + assert_equal async_response, @service.delete_snapshot('fog-test-rg', 'test-disk', true) + end + end +end diff --git a/test/requests/compute/test_get_snapshot.rb b/test/requests/compute/test_get_snapshot.rb new file mode 100644 index 000000000..f78ecec19 --- /dev/null +++ b/test/requests/compute/test_get_snapshot.rb @@ -0,0 +1,24 @@ +require File.expand_path '../../test_helper', __dir__ + +# Test class for Get Snapshot Request +class TestGetSnapshot < Minitest::Test + def setup + @service = Fog::Compute::AzureRM.new(credentials) + @client = @service.instance_variable_get(:@compute_mgmt_client) + @snapshots = @client.snapshots + end + + def test_get_snapshot_success + mocked_response = ApiStub::Requests::Compute::Snapshot.get_snapshot_response(@client) + @snapshots.stub :get, mocked_response do + assert_equal @service.get_snapshot('myrg1', 'snapshot1'), mocked_response + end + end + + def test_get_snapshot_failure + response = proc { raise MsRestAzure::AzureOperationError.new(nil, nil, 'error' => { 'message' => 'mocked exception' }) } + @snapshots.stub :get, response do + assert_raises(RuntimeError) { @service.get_snapshot('myrg1', 'snapshot1') } + end + end +end diff --git a/test/requests/compute/test_list_snapshots_by_rg.rb b/test/requests/compute/test_list_snapshots_by_rg.rb new file mode 100644 index 000000000..b5b285e44 --- /dev/null +++ b/test/requests/compute/test_list_snapshots_by_rg.rb @@ -0,0 +1,24 @@ +require File.expand_path '../../test_helper', __dir__ + +# Test class for List Snapshots by Resource Group Request +class TestListSnapshotsByRG < Minitest::Test + def setup + @service = Fog::Compute::AzureRM.new(credentials) + @client = @service.instance_variable_get(:@compute_mgmt_client) + @snapshots = @client.snapshots + end + + def test_list_snapshots_by_rg_success + mocked_response = [ApiStub::Requests::Compute::Snapshot.create_snapshot_response(@client)] + @snapshots.stub :list_by_resource_group, mocked_response do + assert_equal @service.list_snapshots_by_rg('fog-test-rg'), mocked_response + end + end + + def test_list_snapshots_by_rg_failure + response = proc { raise MsRestAzure::AzureOperationError.new(nil, nil, 'error' => { 'message' => 'mocked exception' }) } + @snapshots.stub :list_by_resource_group, response do + assert_raises(RuntimeError) { @service.list_snapshots_by_rg('fog-test-rg') } + end + end +end diff --git a/test/requests/compute/test_list_snapshots_in_subscription.rb b/test/requests/compute/test_list_snapshots_in_subscription.rb new file mode 100644 index 000000000..bfb40a5a9 --- /dev/null +++ b/test/requests/compute/test_list_snapshots_in_subscription.rb @@ -0,0 +1,24 @@ +require File.expand_path '../../test_helper', __dir__ + +# Test class for List Snapshots Request +class TestListSnapshotsInSubscription < Minitest::Test + def setup + @service = Fog::Compute::AzureRM.new(credentials) + @client = @service.instance_variable_get(:@compute_mgmt_client) + @snapshots = @client.snapshots + end + + def test_list_snapshots_in_subscription_success + mocked_response = [ApiStub::Requests::Compute::Snapshot.create_snapshot_response(@client)] + @snapshots.stub :list, mocked_response do + assert_equal @service.list_snapshots_in_subscription, mocked_response + end + end + + def test_list_snapshots_in_subscription_failure + response = proc { raise MsRestAzure::AzureOperationError.new(nil, nil, 'error' => { 'message' => 'mocked exception' }) } + @snapshots.stub :list, response do + assert_raises(RuntimeError) { @service.list_snapshots_in_subscription } + end + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index d417036ba..55b44ac04 100755 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -804,6 +804,21 @@ def managed_disk(service) ) end +def snapshot(service) + Fog::Compute::AzureRM::Snapshot.new( + name: 'snapshot', + location: 'East US', + resource_group_name: 'fog-test-rg', + account_type: 'Premium_LRS', + disk_size_gb: 1023, + creation_data: { + create_option: 'Copy', + source_uri: 'source uri on azure' + }, + service: service + ) +end + def key_vault(service) Fog::KeyVault::AzureRM::Vault.new( name: 'key-vault',