Commit bd1e7dcb authored by Miha Plesko's avatar Miha Plesko

Provide method to fetch CSV from file stored on Azure

With this commit we provide an automate method that connects to
Azure and grabs a CSV file in there. Then it parses it and stores
resulting hash as a state varibale consumable from other subsequent
automate methods.
Signed-off-by: Miha Plesko's avatarMiha Pleško <[email protected]>
parent 9eadbadf
require 'azure/armrest'
require 'csv'
class CsvImporter
attr :conf, :file_conf
def initialize(client_id:, client_key:, tenant_id:, subscription_id:)
@conf = Azure::Armrest::Configuration.new(
:client_id => client_id,
:client_key => client_key,
:tenant_id => tenant_id,
:subscription_id => subscription_id
)
@file_conf = {}
end
def set_file_conf(storage_account_name:, resource_group:, share_name:, filename:)
@file_conf = {
:storage_account_name => storage_account_name,
:resource_group => resource_group,
:share_name => share_name,
:filename => filename
}
self
end
def fetch_file
azure = Azure::Armrest::StorageAccountService.new(@conf)
storage_account = safe_call('Getting storage account') do
azure.get(@file_conf[:storage_account_name], @file_conf[:resource_group])
end
key = safe_call('Getting account key') do
azure.list_account_keys(storage_account.name, @file_conf[:resource_group]).fetch('key1')
end
safe_call('Getting file content') do
storage_account.file_content(@file_conf[:share_name], @file_conf[:filename], key)
end
end
def parse_file(data)
res = []
CSV.parse(data.to_s, :headers => true).each do |line|
res << {
:first_name => line.fields[0],
:last_name => line.fields[1],
:username => line.fields[2],
:email => line.fields[3],
:project => line.fields[4]
}
end
res
end
def safe_call(msg)
$evm.log(:info, msg)
yield
rescue Azure::Armrest::Exception => err
$evm.log(:error, "Error #{msg}: #{err}")
raise err
end
end
#
# Main
#
# This automate method requires Azure credentials that can be passed by either
# (a) calling from within Azure provider so that `$evm.root.attributes['ext_management_system']` is there
# (b) providing azure_client_id, azure_client_key (encrypted), azure_tenant_id, azure_subscription_id as schema attributes
# This automate method requires following file configuration attributes:
# - azure_storage_account_name
# - azure_resource_group
# - azure_share_name
# - azure_filename
# This automate method assumes there is a file named #{azure_filename} present in share #{azure_share_name}.
# This automate method sets :csv_content state attribute in following format:
# [
# {
# :first_name => String,
# :last_name => String,
# :username => String,
# :email => String,
# :project => String
# },
# ...
# ]
#
if __FILE__ == $PROGRAM_NAME
importer = begin
if $evm.object['azure_client_id'].present?
CsvImporter.new(
:client_id => $evm.object['azure_client_id'],
:client_key => $evm.object.decrypt('azure_client_key'),
:tenant_id => $evm.object['azure_tenant_id'],
:subscription_id => $evm.object['azure_subscription_id']
)
elsif (ems = $evm.root.attributes['ext_management_system'])
$evm.log(:info, "Accessing Azure credentials from Azure EMS #{ems.name} (id: #{ems.id})")
CsvImporter.new(
:client_id => ems.authentication_userid,
:client_key => ems.authentication_password,
:tenant_id => ems.uid_ems,
:subscription_id => ems.subscription
)
else
$evm.log(:error, 'Failed to obtain credentials for Azure provider.')
exit(MIQ_STOP)
end
end
importer.set_file_conf(
:storage_account_name => $evm.object['azure_storage_account_name'],
:resource_group => $evm.object['azure_resource_group'],
:share_name => $evm.object['azure_share_name'],
:filename => $evm.object['azure_filename']
)
content = importer.fetch_file
csv_content = importer.parse_file(content)
$evm.log(:info, "CSV content: #{csv_content}")
$evm.set_state_var(:csv_content, csv_content)
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment