From 039697bb289a62c4295113b73596ddd7f50b0672 Mon Sep 17 00:00:00 2001 From: Adam Grare Date: Mon, 30 Sep 2019 14:18:14 -0400 Subject: [PATCH] Add a verify_credentials_task method This adds a method that takes the options returned by ems.params_for_create and calls a common verify_credentials API call on the provider. This can be called by the API/UI without needing to know anything about the specific provider in a common way. --- app/models/ext_management_system.rb | 1 + app/models/mixins/authentication_mixin.rb | 27 -------- app/models/mixins/provider_mixin.rb | 77 +++++++++++++++++++++++ app/models/provider.rb | 1 + 4 files changed, 79 insertions(+), 27 deletions(-) create mode 100644 app/models/mixins/provider_mixin.rb diff --git a/app/models/ext_management_system.rb b/app/models/ext_management_system.rb index 265d497ae4d2..0d2a624081ab 100644 --- a/app/models/ext_management_system.rb +++ b/app/models/ext_management_system.rb @@ -2,6 +2,7 @@ class ExtManagementSystem < ApplicationRecord include CustomActionsMixin include SupportsFeatureMixin include ExternalUrlMixin + include ProviderMixin def self.with_tenant(tenant_id) tenant = Tenant.find(tenant_id) diff --git a/app/models/mixins/authentication_mixin.rb b/app/models/mixins/authentication_mixin.rb index 37000b41d436..140d2aa0f81c 100644 --- a/app/models/mixins/authentication_mixin.rb +++ b/app/models/mixins/authentication_mixin.rb @@ -22,33 +22,6 @@ def self.authentication_check_schedule assocs = zone.respond_to?(assoc) ? zone.send(assoc) : [] assocs.each { |a| a.authentication_check_types_queue(:attempt => 1) } end - - def self.validate_credentials_task(args, user_id, zone) - task_opts = { - :action => "Validate EMS Provider Credentials", - :userid => user_id - } - - queue_opts = { - :args => [*args], - :class_name => name, - :method_name => "raw_connect?", - :queue_name => "generic", - :role => "ems_operations", - :zone => zone - } - - task_id = MiqTask.generic_action_with_callback(task_opts, queue_opts) - task = MiqTask.wait_for_taskid(task_id, :timeout => 30) - - if task.nil? - error_message = "Task Error" - elsif MiqTask.status_error?(task.status) || MiqTask.status_timeout?(task.status) - error_message = task.message - end - - [error_message.blank?, error_message] - end end def supported_auth_attributes diff --git a/app/models/mixins/provider_mixin.rb b/app/models/mixins/provider_mixin.rb new file mode 100644 index 000000000000..7636fa0ce8c5 --- /dev/null +++ b/app/models/mixins/provider_mixin.rb @@ -0,0 +1,77 @@ +module ProviderMixin + extend ActiveSupport::Concern + + included do + class << self + Vmdb::Deprecation.deprecate_methods self, :validate_credentials_task => :verify_credentials_task + end + end + + module ClassMethods + def validate_credentials_task(args, user_id, zone) + task_opts = { + :action => "Validate EMS Provider Credentials", + :userid => user_id + } + + queue_opts = { + :args => [*args], + :class_name => name, + :method_name => "raw_connect?", + :queue_name => "generic", + :role => "ems_operations", + :zone => zone + } + + task_id = MiqTask.generic_action_with_callback(task_opts, queue_opts) + task = MiqTask.wait_for_taskid(task_id, :timeout => 30) + + if task.nil? + error_message = "Task Error" + elsif MiqTask.status_error?(task.status) || MiqTask.status_timeout?(task.status) + error_message = task.message + end + + [error_message.blank?, error_message] + end + + def verify_credentials_task(userid, zone, options) + task_opts = { + :action => "Verify EMS Provider Credentials", + :userid => userid + } + + encrypt_verify_credential_params!(options) + + queue_opts = { + :args => [options], + :class_name => name, + :method_name => "verify_credentials?", + :queue_name => "generic", + :role => "ems_operations", + :zone => zone + } + + MiqTask.generic_action_with_callback(task_opts, queue_opts) + end + + def verify_credentials?(args) + # Prevent the connection details, including the password, from being leaked into the logs + # and MiqQueue by only returning true/false + !!verify_credentials(args) + end + + private + + # Ensure that any passwords are encrypted before putting them onto the queue for any + # DDF fields which are a password type + def encrypt_verify_credential_params!(options) + params_for_create[:fields].each do |field| + key_path = field[:name].split(".") + if options.key_path?(key_path) + options.store_path(key_path, MiqPassword.try_encrypt(options.fetch_path(key_path))) if field[:type] == "password" + end + end + end + end +end diff --git a/app/models/provider.rb b/app/models/provider.rb index a753d433003c..ab6ff260585b 100644 --- a/app/models/provider.rb +++ b/app/models/provider.rb @@ -3,6 +3,7 @@ class Provider < ApplicationRecord include AuthenticationMixin include AsyncDeleteMixin include EmsRefresh::Manager + include ProviderMixin include SupportsFeatureMixin include TenancyMixin include UuidMixin