Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encrypt secrets before enqueue Tower CU operations #15084

Merged
merged 2 commits into from
May 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ def provider_params(params)
params
end

def hide_secrets(params)
params.each_with_object({}) do |attr, h|
h[attr.first] = self::API_ATTRIBUTES[attr.first] && self::API_ATTRIBUTES[attr.first][:type] == :password ? '******' : attr.second
def process_secrets(params, decrypt = false)
if decrypt
Vmdb::Settings.decrypt_passwords!(params)
else
Vmdb::Settings.encrypt_passwords!(params)
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module ManageIQ::Providers::AnsibleTower::Shared::AutomationManager::TowerApi
module ClassMethods
def create_in_provider(manager_id, params)
params = provider_params(params) if respond_to?(:provider_params)
process_secrets(params, true) if respond_to?(:process_secrets)
manager = ExtManagementSystem.find(manager_id)
tower_object = provider_collection(manager).create!(params)
if respond_to?(:refresh_in_provider)
Expand All @@ -18,16 +19,17 @@ def create_in_provider(manager_id, params)
end

def create_in_provider_queue(manager_id, params)
process_secrets(params) if respond_to?(:process_secrets)
manager = ExtManagementSystem.find(manager_id)
action = "Creating #{self::FRIENDLY_NAME} (name=#{params[:name]})"
queue(manager.my_zone, nil, "create_in_provider", [manager_id, params], action)
end

private

def notify(op, manager_id, params, success)
params = hide_secrets(params) if respond_to?(:hide_secrets)
_log.info "#{name} in_provider #{op} with parameters: #{params} #{success ? 'succeeded' : 'failed'}"
op_arg = params.each_with_object([]) { |(k, v), l| l.push("#{k}=#{v}") if [:name, :manager_ref].include?(k) }.join(', ')
_log.info "#{name} in_provider #{op} with parameters: #{op_arg} #{success ? 'succeeded' : 'failed'}"
Notification.create(
:type => success ? :tower_op_success : :tower_op_failure,
:options => {
Expand Down Expand Up @@ -64,6 +66,7 @@ def queue(zone, instance_id, method_name, args, action)
end

def update_in_provider(params)
self.class.process_secrets(params, true) if self.class.respond_to?(:process_secrets)
params.delete(:task_id) # in case this is being called through update_in_provider_queue which will stick in a :task_id
params = self.class.provider_params(params) if self.class.respond_to?(:provider_params)
with_provider_object do |provider_object|
Expand All @@ -81,6 +84,7 @@ def update_in_provider(params)
end

def update_in_provider_queue(params)
self.class.process_secrets(params) if self.class.respond_to?(:process_secrets)
action = "Updating #{self.class::FRIENDLY_NAME} (Tower internal reference=#{manager_ref})"
self.class.send('queue', manager.my_zone, id, "update_in_provider", [params], action)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/vmdb/settings/walker.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Vmdb
class Settings
module Walker
PASSWORD_FIELDS = %i(bind_pwd password amazon_secret).to_set.freeze
PASSWORD_FIELDS = %i(bind_pwd password amazon_secret ssh_key_data ssh_key_unlock become_password vault_password security_token).to_set.freeze

# Walks the settings and yields each value along the way
#
Expand Down
10 changes: 8 additions & 2 deletions spec/support/ansible_shared/automation_manager/credential.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@

it ".create_in_provider to succeed and send notification" do
expected_params[:organization] = 1 if described_class.name.include?("::EmbeddedAnsible::")
expect(Vmdb::Settings).to receive(:decrypt_passwords!).with(expected_params)
expect(AnsibleTowerClient::Connection).to receive(:new).and_return(atc)
store_new_credential(credential, manager)
expect(EmsRefresh).to receive(:queue_refresh_task).with(manager).and_return([finished_task])
Expand All @@ -63,6 +64,7 @@

it ".create_in_provider to fail (not found during refresh) and send notification" do
expected_params[:organization] = 1 if described_class.name.include?("::EmbeddedAnsible::")
expect(Vmdb::Settings).to receive(:decrypt_passwords!).with(expected_params)
expect(AnsibleTowerClient::Connection).to receive(:new).and_return(atc)
expect(EmsRefresh).to receive(:queue_refresh_task).and_return([finished_task])
expect(ExtManagementSystem).to receive(:find).with(manager.id).and_return(manager)
Expand All @@ -73,6 +75,7 @@
end

it ".create_in_provider_queue" do
expect(Vmdb::Settings).to receive(:encrypt_passwords!).with(params)
task_id = described_class.create_in_provider_queue(manager.id, params)
expect(MiqTask.find(task_id)).to have_attributes(:name => "Creating #{described_class::FRIENDLY_NAME} (name=#{params[:name]})")
expect(MiqQueue.first).to have_attributes(
Expand Down Expand Up @@ -157,6 +160,7 @@ def store_new_credential(credential, manager)
end

it "#update_in_provider to succeed and send notification" do
expect(Vmdb::Settings).to receive(:decrypt_passwords!).with(params)
expected_params[:organization] = 1 if described_class.name.include?("::EmbeddedAnsible::")
expect(AnsibleTowerClient::Connection).to receive(:new).and_return(atc)
expect(credential).to receive(:update_attributes!).with(expected_params)
Expand All @@ -175,11 +179,13 @@ def store_new_credential(credential, manager)
end

it "#update_in_provider_queue" do
task_id = ansible_cred.update_in_provider_queue({})
expect(Vmdb::Settings).to receive(:encrypt_passwords!).with(params)
task_id = ansible_cred.update_in_provider_queue(params)
expect(MiqTask.find(task_id)).to have_attributes(:name => "Updating #{described_class::FRIENDLY_NAME} (Tower internal reference=#{ansible_cred.manager_ref})")
params[:task_id] = task_id
expect(MiqQueue.first).to have_attributes(
:instance_id => ansible_cred.id,
:args => [{:task_id => task_id}],
:args => [params],
:class_name => described_class.name,
:method_name => "update_in_provider",
:priority => MiqQueue::HIGH_PRIORITY,
Expand Down