Skip to content

Commit

Permalink
Merge pull request #122 from jerryk55/nonmanaged_disk_snapshot_support
Browse files Browse the repository at this point in the history
Snapshot Blob Disks for SSA
(cherry picked from commit 29116cc)

https://bugzilla.redhat.com/show_bug.cgi?id=1491310
  • Loading branch information
Bronagh Sorota authored and simaishi committed Sep 13, 2017
1 parent b75fb9b commit 8d71d0a
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 40 deletions.
87 changes: 61 additions & 26 deletions app/models/manageiq/providers/azure/cloud_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ class ManageIQ::Providers::Azure::CloudManager < ManageIQ::Providers::CloudManag
before_create :ensure_managers
before_update :ensure_managers_zone_and_provider_region

SSA_SNAPSHOT_SUFFIX = "__EVM__SSA__SNAPSHOT".freeze

# If the Microsoft.Insights Azure provider is not registered, then neither
# events nor metrics are supported for that EMS.
#
Expand Down Expand Up @@ -118,51 +116,88 @@ def vm_reboot_guest(vm, _options = {})
end

def vm_create_evm_snapshot(vm, options = {})
conf = connect(options)
vm_svc = vm.provider_service(conf)
snap_svc = snapshot_service(conf)
vm_obj = vm_svc.get(vm.name, vm.resource_group)
return unless vm_obj.managed_disk?
os_disk = vm_obj.properties.storage_profile.os_disk
@connection = connect(options)
vm.provider_service(@connection)
if vm.managed_disk?
vm_create_evm_managed_snapshot(vm)
else
vm_create_evm_blob_snapshot(vm)
end
end

def vm_create_evm_managed_snapshot(vm)
snap_svc = snapshot_service(@connection)
snap_options = { :location => vm.location,
:properties => {
:creationData => {
:createOption => "Copy",
:sourceResourceId => os_disk.managed_disk.id
:sourceResourceId => vm.os_disk.managed_disk.id
}
} }
snap_name = "#{os_disk.name}#{SSA_SNAPSHOT_SUFFIX}"
_log.debug("vm=[#{vm.name}] creating SSA snapshot #{snap_name}")
_log.debug("vm=[#{vm.name}] creating SSA snapshot #{vm.ssa_snap_name}")
begin
snap_svc.get(snap_name, vm.resource_group)
ssa_snap_name = vm.ssa_snap_name
resource_group = vm.resource_group.name
snap_svc.get(ssa_snap_name, resource_group)
rescue ::Azure::Armrest::NotFoundException, ::Azure::Armrest::ResourceNotFoundException => err
begin
snap_svc.create(snap_name, vm.resource_group, snap_options)
return snap_name
snap_svc.create(ssa_snap_name, resource_group, snap_options)
return ssa_snap_name
rescue => err
_log.error("vm=[#{vm.name}], error: #{err}")
_log.debug { err.backtrace.join("\n") }
raise "Error #{err} creating SSA Snapshot #{snap_name}"
raise "Error #{err} creating SSA Snapshot #{ssa_snap_name}"
end
end
_log.error("SSA Snapshot #{snap_name} already exists.")
raise "Snapshot #{snap_name} already exists. Another SSA request for this VM is in progress or a previous one failed to clean up properly."
_log.error("SSA Snapshot #{ssa_snap_name} already exists.")
raise "Snapshot #{ssa_snap_name} already exists. Another SSA request for this VM is in progress or a previous one failed to clean up properly."
end

def vm_create_evm_blob_snapshot(vm)
_log.debug("vm=[#{vm.name}] creating SSA snapshot for #{vm.blob_uri}")
begin
snapshot_info = vm.storage_acct.create_blob_snapshot(vm.container, vm.blob, vm.key)
return snapshot_info[:x_ms_snapshot]
rescue => err
_log.error("vm=[#{vm.name}], error:#{err}")
_log.debug { err.backtrace.join("\n") }
raise "Error #{err} creating SSA Snapshot for #{vm.name}"
end
end

def vm_delete_evm_snapshot(vm, options = {})
conf = connect(options)
vm_svc = vm.provider_service(conf)
snap_svc = snapshot_service(conf)
vm_obj = vm_svc.get(vm.name, vm.resource_group)
os_disk = vm_obj.properties.storage_profile.os_disk
snap_name = "#{os_disk.name}#{SSA_SNAPSHOT_SUFFIX}"
_log.debug("vm=[#{vm.name}] deleting SSA snapshot #{snap_name}")
snap_svc.delete(snap_name, vm.resource_group)
@connection = connect(options)
if vm.managed_disk?
vm_delete_managed_snapshot(vm, options)
else
vm_delete_blob_snapshot(vm, options)
end
end

def vm_delete_managed_snapshot(vm, _options = {})
snap_svc = snapshot_service(@connection)
_log.debug("vm=[#{vm.name}] deleting SSA snapshot #{vm.ssa_snap_name}")
snap_svc.delete(vm.ssa_snap_name, vm.resource_group.name)
rescue => err
_log.error("vm=[#{vm.name}], error: #{err}")
_log.error("vm=[#{vm.name}], error: #{err} deleting SSA snapshot #{vm.ssa_snap_name}")
_log.debug { err.backtrace.join("\n") }
end

def vm_delete_blob_snapshot(vm, options = {})
unless options[:snMor]
_log.error("Unable to clean up SSA snapshot: Missing Snapshot Date")
return
end
_log.debug("vm=[#{vm.name}] deleting SSA snapshot for #{vm.blob_uri} with date #{options[:snMor]}")
begin
snap_opts = { :date => options[:snMor] }
vm.storage_acct.delete_blob(vm.container, vm.blob, vm.key, snap_opts)
rescue => err
_log.error("vm=[#{vm.name}], error:#{err} deleting SSA snapshot with date #{options[:snMor]}")
_log.debug { err.backtrace.join("\n") }
end
end

def snapshot_service(connection = nil)
_log.debug("Enter")
connection ||= connect
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,53 @@
module ManageIQ::Providers::Azure::CloudManager::VmOrTemplateShared
extend ActiveSupport::Concern
include_concern 'Scanning'
SSA_SNAPSHOT_SUFFIX = "__EVM__SSA__SNAPSHOT".freeze

def provider_service(connection = nil)
connection ||= ext_management_system.connect
::Azure::Armrest::VirtualMachineService.new(connection)
@connection ||= connection || ext_management_system.connect
@provider_service ||= ::Azure::Armrest::VirtualMachineService.new(@connection)
end

def storage_acct_service(connection = nil)
@connection ||= connection || ext_management_system.connect
@storage_acct_service ||= ::Azure::Armrest::StorageAccountService.new(@connection)
end

def blob_info
@blob_info ||= storage_acct_service.parse_uri(blob_uri)
end

def container
@container ||= blob_info[:container]
end

def blob
@blob ||= blob_info[:blob]
end

def storage_acct
@storage_acct ||= storage_acct_service.accounts_by_name[blob_info[:account_name]]
end

def key
@key ||= storage_acct_service.list_account_keys(storage_acct.name, storage_acct.resource_group).fetch('key1')
end

def vm_object
@vm_object ||= provider_service.get(name, resource_group.name)
end

def os_disk
@os_disk ||= vm_object.properties.storage_profile.os_disk
end

delegate :managed_disk?, to: :vm_object

def ssa_snap_name
@ssa_snap_name ||= "#{os_disk.name}#{SSA_SNAPSHOT_SUFFIX}"
end

def blob_uri
@blob_uri ||= os_disk.vhd.uri
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ def perform_metadata_scan(ost)
_log.debug("image_uri: #{uid_ems}")
vm_args[:image_uri] = uid_ems
else
_log.debug("resource_group: #{resource_group}")
vm_args[:resource_group] = resource_group
vm_args[:snapshot] = ost.scanData["snapshot"]["name"] unless managed_disk?
end

ost.scanTime = Time.now.utc unless ost.scanTime
Expand Down Expand Up @@ -58,16 +58,6 @@ def requires_storage_for_scan?
end

def require_snapshot_for_scan?
begin
vm_obj = provider_service.get(name, resource_group)
if vm_obj.managed_disk?
_log.debug("VM #{name} has a Managed Disk - Snapshot required for Scan")
return true
end
rescue => err
_log.error("Error Class=#{err.class.name}, Message=#{err.message}")
end
_log.debug("VM #{name} does not have a Managed Disk - no Snapshot required for Scan")
false
true
end
end

0 comments on commit 8d71d0a

Please sign in to comment.