diff --git a/lib/puppet/provider/openstack.rb b/lib/puppet/provider/openstack.rb index ec1cffe2..391e327f 100644 --- a/lib/puppet/provider/openstack.rb +++ b/lib/puppet/provider/openstack.rb @@ -106,46 +106,51 @@ class Puppet::Provider::Openstack < Puppet::Provider private def password_credentials_set?(auth_params) - auth_params && auth_params['username'] && auth_params['password'] && auth_params['tenant_name'] && auth_params['auth_url'] + auth_params && auth_params['username'] && auth_params['password'] && auth_params['project_name'] && auth_params['auth_url'] end - def openrc_set?(auth_params) auth_params && auth_params['openrc'] end - def service_credentials_set?(auth_params) - auth_params && auth_params['token'] && auth_params['auth_url'] + auth_params && auth_params['token'] && auth_params['url'] end - def self.env_vars_set? - ENV['OS_USERNAME'] && ENV['OS_PASSWORD'] && ENV['OS_TENANT_NAME'] && ENV['OS_AUTH_URL'] + ENV['OS_USERNAME'] && ENV['OS_PASSWORD'] && ENV['OS_PROJECT_NAME'] && ENV['OS_AUTH_URL'] end - def env_vars_set? self.class.env_vars_set? end - - def self.password_auth_args(credentials) - ['--os-username', credentials['username'], - '--os-password', credentials['password'], - '--os-tenant-name', credentials['tenant_name'], - '--os-auth-url', credentials['auth_url']] + creds = [ '--os-username', credentials['username'], + '--os-password', credentials['password'], + '--os-project-name', credentials['project_name'], + '--os-auth-url', credentials['auth_url'] ] + + if credentials.include?('project_domain_name') + creds << '--os-project-domain-name' + creds << credentials['project_domain_name'] + end + + if credentials.include?('user_domain_name') + creds << '--os-user-domain-name' + creds << credentials['user_domain_name'] + end + + creds end def password_auth_args(credentials) self.class.password_auth_args(credentials) end - def self.token_auth_args(credentials) - ['--os-token', credentials['token'], - '--os-url', credentials['auth_url']] + [ '--os-token', credentials['token'], + '--os-url', credentials['url'] ] end def token_auth_args(credentials) @@ -163,7 +168,6 @@ class Puppet::Provider::Openstack < Puppet::Provider return creds end - def self.get_credentials_from_env env = ENV.to_hash.dup.delete_if { |key, _| ! (key =~ /^OS_/) } credentials = {} diff --git a/lib/puppet/util/openstack.rb b/lib/puppet/util/openstack.rb index 867964af..916aa8e1 100644 --- a/lib/puppet/util/openstack.rb +++ b/lib/puppet/util/openstack.rb @@ -5,27 +5,46 @@ module Puppet::Util::Openstack type.newparam(:auth) do desc < { - 'username' => 'test', - 'password' => 'passw0rd', - 'tenant_name' => 'test', - 'auth_url' => 'http://localhost:35357/v2.0', + 'username' => 'test', + 'password' => 'changeme', + 'project_name' => 'test', + 'auth_url' => 'http://localhost:35357/v2.0' } -or a path to an openrc file containing these credentials, e.g.: - +or altenatively for Keystone API V3: auth => { - 'openrc' => '/root/openrc', + 'username' => 'test', + 'password' => 'changeme', + 'project_name' => 'test', + 'project_domain_name' => 'domain1', + 'user_domain_name' => 'domain1', + 'auth_url' => 'http://localhost:35357/v3' } -or a service token and host, e.g.: +2. Using a path to an openrc file containing these credentials auth => { - 'service_token' => 'ADMIN', - 'auth_url' => 'http://localhost:35357/v2.0', + 'openrc' => '/root/openrc' +} + +3. Using a service token + +For Keystone API V2: +auth => { + 'token' => 'example', + 'url' => 'http://localhost:35357/v2.0' +} + +Alternatively for Keystone API V3: +auth => { + 'token' => 'example', + 'url' => 'http://localhost:35357/v3.0' } If not present, the provider will look for environment variables for diff --git a/spec/unit/provider/openstack_spec.rb b/spec/unit/provider/openstack_spec.rb index c5f5efe1..558c4908 100644 --- a/spec/unit/provider/openstack_spec.rb +++ b/spec/unit/provider/openstack_spec.rb @@ -8,10 +8,10 @@ require 'puppet/provider/openstack' describe Puppet::Provider::Openstack do before(:each) do - ENV['OS_USERNAME'] = nil - ENV['OS_PASSWORD'] = nil - ENV['OS_TENANT_NAME'] = nil - ENV['OS_AUTH_URL'] = nil + ENV['OS_USERNAME'] = nil + ENV['OS_PASSWORD'] = nil + ENV['OS_PROJECT_NAME'] = nil + ENV['OS_AUTH_URL'] = nil end let(:type) do @@ -22,12 +22,36 @@ describe Puppet::Provider::Openstack do end end - shared_examples 'authenticating with environment variables' do + shared_examples 'authenticating with environment variables using API v2' do it 'makes a successful request' do - ENV['OS_USERNAME'] = 'test' - ENV['OS_PASSWORD'] = 'abc123' - ENV['OS_TENANT_NAME'] = 'test' - ENV['OS_AUTH_URL'] = 'http://127.0.0.1:35357/v2.0' + ENV['OS_USERNAME'] = 'test' + ENV['OS_PASSWORD'] = 'abc123' + ENV['OS_PROJECT_NAME'] = 'test' + ENV['OS_AUTH_URL'] = 'http://127.0.0.1:35357/v2.0' + if provider.class == Class + provider.stubs(:openstack) + .with('project', 'list', '--quiet', '--format', 'csv', [[ '--long' ]]) + .returns('"ID","Name","Description","Enabled" +"1cb05cfed7c24279be884ba4f6520262","test","Test tenant",True +') + else + provider.class.stubs(:openstack) + .with('project', 'list', '--quiet', '--format', 'csv', [[ '--long' ]]) + .returns('"ID","Name","Description","Enabled" +"1cb05cfed7c24279be884ba4f6520262","test","Test tenant",True +') + end + response = provider.request('project', 'list', nil, nil, '--long' ) + expect(response.first[:description]).to match /Test tenant/ + end + end + + shared_examples 'authenticating with environment variables using API v3' do + it 'makes a successful request' do + ENV['OS_USERNAME'] = 'test' + ENV['OS_PASSWORD'] = 'abc123' + ENV['OS_PROJECT_NAME'] = 'test' + ENV['OS_AUTH_URL'] = 'http://127.0.0.1:35357/v3' if provider.class == Class provider.stubs(:openstack) .with('project', 'list', '--quiet', '--format', 'csv', [[ '--long' ]]) @@ -59,10 +83,10 @@ describe Puppet::Provider::Openstack do { :name => 'stubresource', :auth => { - 'username' => 'test', - 'password' => 'abc123', - 'tenant_name' => 'test', - 'auth_url' => 'http://127.0.0.1:5000/v2.0', + 'username' => 'test', + 'password' => 'abc123', + 'project_name' => 'test', + 'auth_url' => 'http://127.0.0.1:5000/v2.0', } } end @@ -72,7 +96,7 @@ describe Puppet::Provider::Openstack do it 'makes a successful request' do provider.class.stubs(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'test', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'test', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Description","Enabled" "1cb05cfed7c24279be884ba4f6520262","test","Test tenant",True ') @@ -82,7 +106,7 @@ describe Puppet::Provider::Openstack do end context 'with valid openrc file in parameters' do - mock = "export OS_USERNAME='test'\nexport OS_PASSWORD='abc123'\nexport OS_TENANT_NAME='test'\nexport OS_AUTH_URL='http://127.0.0.1:5000/v2.0'" + mock = "export OS_USERNAME='test'\nexport OS_PASSWORD='abc123'\nexport OS_PROJECT_NAME='test'\nexport OS_AUTH_URL='http://127.0.0.1:5000/v2.0'" let(:resource_attrs) do { :name => 'stubresource', @@ -98,7 +122,7 @@ describe Puppet::Provider::Openstack do it 'makes a successful request' do File.expects(:open).with('/root/openrc').returns(StringIO.new(mock)) provider.class.stubs(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'test', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'test', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .returns('"ID","Name","Description","Enabled" "1cb05cfed7c24279be884ba4f6520262","test","Test tenant",True ') @@ -113,7 +137,7 @@ describe Puppet::Provider::Openstack do :name => 'stubresource', :auth => { 'token' => 'secrettoken', - 'auth_url' => 'http://127.0.0.1:5000/v2.0' + 'url' => 'http://127.0.0.1:5000/v2.0' } } end @@ -149,7 +173,7 @@ Enabled="True" end context 'with valid password credentials in environment variables' do - it_behaves_like 'authenticating with environment variables' do + it_behaves_like 'authenticating with environment variables using API v2' do let(:resource_attrs) do { :name => 'stubresource', @@ -179,10 +203,10 @@ Enabled="True" { :name => 'stubresource', :auth => { - 'username' => 'test', - 'password' => 'abc123', - 'tenant_name' => 'test', - 'auth_url' => 'http://127.0.0.1:5000/v2.0', + 'username' => 'test', + 'password' => 'abc123', + 'project_name' => 'test', + 'auth_url' => 'http://127.0.0.1:5000/v2.0', } } end @@ -191,7 +215,7 @@ Enabled="True" end it 'retries' do provider.class.stubs(:openstack) - .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-tenant-name', 'test', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) + .with('project', 'list', '--quiet', '--format', 'csv', [['--long', '--os-username', 'test', '--os-password', 'abc123', '--os-project-name', 'test', '--os-auth-url', 'http://127.0.0.1:5000/v2.0']]) .raises(Puppet::ExecutionFailure, 'Unable to establish connection') .then .returns('') @@ -205,7 +229,7 @@ Enabled="True" describe '::request' do context 'with valid password credentials in environment variables' do - it_behaves_like 'authenticating with environment variables' do + it_behaves_like 'authenticating with environment variables using API v2' do let(:resource_attrs) do { :name => 'stubresource',