diff --git a/app/models/manageiq/providers/vmware/manager_auth_mixin.rb b/app/models/manageiq/providers/vmware/manager_auth_mixin.rb index 0c8506561..9dc08c5ab 100644 --- a/app/models/manageiq/providers/vmware/manager_auth_mixin.rb +++ b/app/models/manageiq/providers/vmware/manager_auth_mixin.rb @@ -8,21 +8,18 @@ def verify_credentials(auth_type = nil, options = {}) raise MiqException::MiqHostError, "No credentials defined" if missing_credentials?(auth_type) options[:auth_type] = auth_type - begin + + self.class.connection_rescue_block do case auth_type.to_s when 'default' then with_provider_connection(options) do |vcd| - vcd.organizations.all + self.class.validate_connection(vcd) end when 'amqp' then verify_amqp_credentials(options) else raise "Invalid Vmware vCloud Authentication Type: #{auth_type.inspect}" end - rescue => err - miq_exception = translate_exception(err) - _log.error("Error Class=#{err.class.name}, Message=#{err.message}") - raise miq_exception end true @@ -39,26 +36,11 @@ def connect(options = {}) self.class.raw_connect(server, port, username, password) end - def translate_exception(err) - case err - when Fog::Compute::VcloudDirector::Unauthorized - MiqException::MiqInvalidCredentialsError.new "Login failed due to a bad username or password." - when Excon::Errors::Timeout - MiqException::MiqUnreachableError.new "Login attempt timed out" - when Excon::Errors::SocketError - MiqException::MiqHostError.new "Socket error: #{err.message}" - when MiqException::MiqInvalidCredentialsError, MiqException::MiqHostError - err - else - MiqException::MiqHostError.new "Unexpected response returned from system: #{err.message}" - end - end - module ClassMethods - def raw_connect(server, port, username, password) + def raw_connect(server, port, username, password, validate = false) params = { :vcloud_director_username => username, - :vcloud_director_password => password, + :vcloud_director_password => MiqPassword.try_decrypt(password), :vcloud_director_host => server, :vcloud_director_show_progress => false, :port => port, @@ -67,7 +49,36 @@ def raw_connect(server, port, username, password) } } - Fog::Compute::VcloudDirector.new(params) + connect = Fog::Compute::VcloudDirector.new(params) + connection_rescue_block { validate_connection(connect) } if validate + connect + end + + def validate_connection(connection) + connection.organizations.all + end + + def connection_rescue_block + yield + rescue => err + miq_exception = translate_exception(err) + _log.error("Error Class=#{err.class.name}, Message=#{err.message}") + raise miq_exception + end + + def translate_exception(err) + case err + when Fog::Compute::VcloudDirector::Unauthorized + MiqException::MiqInvalidCredentialsError.new "Login failed due to a bad username or password." + when Excon::Errors::Timeout + MiqException::MiqUnreachableError.new "Login attempt timed out" + when Excon::Errors::SocketError + MiqException::MiqHostError.new "Socket error: #{err.message}" + when MiqException::MiqInvalidCredentialsError, MiqException::MiqHostError + err + else + MiqException::MiqHostError.new "Unexpected response returned from system: #{err.message}" + end end end end diff --git a/spec/models/manageiq/providers/vmware/cloud_manager_spec.rb b/spec/models/manageiq/providers/vmware/cloud_manager_spec.rb index 2b2db13e1..ac3e2c32b 100644 --- a/spec/models/manageiq/providers/vmware/cloud_manager_spec.rb +++ b/spec/models/manageiq/providers/vmware/cloud_manager_spec.rb @@ -31,6 +31,48 @@ ) end + context ".raw_connect" do + let(:params) do + { + :vcloud_director_username => "username", + :vcloud_director_password => "encrypted", + :vcloud_director_host => "server", + :vcloud_director_show_progress => false, + :port => "port", + :connection_options => { + :ssl_verify_peer => false # for development + } + } + end + + before do + require 'fog/vcloud_director' + end + + it "decrypts the vcloud password" do + encrypted = MiqPassword.encrypt("encrypted") + expect(::Fog::Compute::VcloudDirector).to receive(:new).with(params) + + described_class.raw_connect("server", "port", "username", encrypted) + end + + it "validates the password if validate is true if specified" do + expect(described_class).to receive(:validate_connection).and_raise(Fog::Compute::VcloudDirector::Unauthorized) + expect(::Fog::Compute::VcloudDirector).to receive(:new).with(params) + + expect do + described_class.raw_connect("server", "port", "username", "encrypted", true) + end.to raise_error(MiqException::MiqInvalidCredentialsError, "Login failed due to a bad username or password.") + end + + it "does not validate the password unless specified" do + expect(described_class).to_not receive(:validate_connection) + expect(::Fog::Compute::VcloudDirector).to receive(:new).with(params) + + described_class.raw_connect("server", "port", "username", "encrypted") + end + end + it ".ems_type" do expect(described_class.ems_type).to eq('vmware_cloud') end