Merge "Targeting Keystone V3 API support"

This commit is contained in:
Jenkins
2015-04-07 16:00:47 +00:00
committed by Gerrit Code Review
3 changed files with 100 additions and 53 deletions

View File

@@ -106,46 +106,51 @@ class Puppet::Provider::Openstack < Puppet::Provider
private private
def password_credentials_set?(auth_params) 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 end
def openrc_set?(auth_params) def openrc_set?(auth_params)
auth_params && auth_params['openrc'] auth_params && auth_params['openrc']
end end
def service_credentials_set?(auth_params) def service_credentials_set?(auth_params)
auth_params && auth_params['token'] && auth_params['auth_url'] auth_params && auth_params['token'] && auth_params['url']
end end
def self.env_vars_set? 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 end
def env_vars_set? def env_vars_set?
self.class.env_vars_set? self.class.env_vars_set?
end end
def self.password_auth_args(credentials) def self.password_auth_args(credentials)
['--os-username', credentials['username'], creds = [ '--os-username', credentials['username'],
'--os-password', credentials['password'], '--os-password', credentials['password'],
'--os-tenant-name', credentials['tenant_name'], '--os-project-name', credentials['project_name'],
'--os-auth-url', credentials['auth_url']] '--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 end
def password_auth_args(credentials) def password_auth_args(credentials)
self.class.password_auth_args(credentials) self.class.password_auth_args(credentials)
end end
def self.token_auth_args(credentials) def self.token_auth_args(credentials)
['--os-token', credentials['token'], [ '--os-token', credentials['token'],
'--os-url', credentials['auth_url']] '--os-url', credentials['url'] ]
end end
def token_auth_args(credentials) def token_auth_args(credentials)
@@ -163,7 +168,6 @@ class Puppet::Provider::Openstack < Puppet::Provider
return creds return creds
end end
def self.get_credentials_from_env def self.get_credentials_from_env
env = ENV.to_hash.dup.delete_if { |key, _| ! (key =~ /^OS_/) } env = ENV.to_hash.dup.delete_if { |key, _| ! (key =~ /^OS_/) }
credentials = {} credentials = {}

View File

@@ -5,27 +5,46 @@ module Puppet::Util::Openstack
type.newparam(:auth) do type.newparam(:auth) do
desc <<EOT desc <<EOT
Hash of authentication credentials. Credentials can be specified as Hash of authentication credentials. Credentials can be specified as either :
password credentials, e.g.:
1. Using a project/user with a password
For Keystone API V2:
auth => { auth => {
'username' => 'test', 'username' => 'test',
'password' => 'passw0rd', 'password' => 'changeme',
'tenant_name' => 'test', 'project_name' => 'test',
'auth_url' => 'http://localhost:35357/v2.0', '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 => { 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 => { auth => {
'service_token' => 'ADMIN', 'openrc' => '/root/openrc'
'auth_url' => 'http://localhost:35357/v2.0', }
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 If not present, the provider will look for environment variables for

View File

@@ -8,10 +8,10 @@ require 'puppet/provider/openstack'
describe Puppet::Provider::Openstack do describe Puppet::Provider::Openstack do
before(:each) do before(:each) do
ENV['OS_USERNAME'] = nil ENV['OS_USERNAME'] = nil
ENV['OS_PASSWORD'] = nil ENV['OS_PASSWORD'] = nil
ENV['OS_TENANT_NAME'] = nil ENV['OS_PROJECT_NAME'] = nil
ENV['OS_AUTH_URL'] = nil ENV['OS_AUTH_URL'] = nil
end end
let(:type) do let(:type) do
@@ -22,12 +22,36 @@ describe Puppet::Provider::Openstack do
end end
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 it 'makes a successful request' do
ENV['OS_USERNAME'] = 'test' ENV['OS_USERNAME'] = 'test'
ENV['OS_PASSWORD'] = 'abc123' ENV['OS_PASSWORD'] = 'abc123'
ENV['OS_TENANT_NAME'] = 'test' ENV['OS_PROJECT_NAME'] = 'test'
ENV['OS_AUTH_URL'] = 'http://127.0.0.1:35357/v2.0' 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 if provider.class == Class
provider.stubs(:openstack) provider.stubs(:openstack)
.with('project', 'list', '--quiet', '--format', 'csv', [[ '--long' ]]) .with('project', 'list', '--quiet', '--format', 'csv', [[ '--long' ]])
@@ -59,10 +83,10 @@ describe Puppet::Provider::Openstack do
{ {
:name => 'stubresource', :name => 'stubresource',
:auth => { :auth => {
'username' => 'test', 'username' => 'test',
'password' => 'abc123', 'password' => 'abc123',
'tenant_name' => 'test', 'project_name' => 'test',
'auth_url' => 'http://127.0.0.1:5000/v2.0', 'auth_url' => 'http://127.0.0.1:5000/v2.0',
} }
} }
end end
@@ -72,7 +96,7 @@ describe Puppet::Provider::Openstack do
it 'makes a successful request' do it 'makes a successful request' do
provider.class.stubs(:openstack) 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" .returns('"ID","Name","Description","Enabled"
"1cb05cfed7c24279be884ba4f6520262","test","Test tenant",True "1cb05cfed7c24279be884ba4f6520262","test","Test tenant",True
') ')
@@ -82,7 +106,7 @@ describe Puppet::Provider::Openstack do
end end
context 'with valid openrc file in parameters' do 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 let(:resource_attrs) do
{ {
:name => 'stubresource', :name => 'stubresource',
@@ -98,7 +122,7 @@ describe Puppet::Provider::Openstack do
it 'makes a successful request' do it 'makes a successful request' do
File.expects(:open).with('/root/openrc').returns(StringIO.new(mock)) File.expects(:open).with('/root/openrc').returns(StringIO.new(mock))
provider.class.stubs(:openstack) 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" .returns('"ID","Name","Description","Enabled"
"1cb05cfed7c24279be884ba4f6520262","test","Test tenant",True "1cb05cfed7c24279be884ba4f6520262","test","Test tenant",True
') ')
@@ -113,7 +137,7 @@ describe Puppet::Provider::Openstack do
:name => 'stubresource', :name => 'stubresource',
:auth => { :auth => {
'token' => 'secrettoken', 'token' => 'secrettoken',
'auth_url' => 'http://127.0.0.1:5000/v2.0' 'url' => 'http://127.0.0.1:5000/v2.0'
} }
} }
end end
@@ -149,7 +173,7 @@ Enabled="True"
end end
context 'with valid password credentials in environment variables' 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 let(:resource_attrs) do
{ {
:name => 'stubresource', :name => 'stubresource',
@@ -179,10 +203,10 @@ Enabled="True"
{ {
:name => 'stubresource', :name => 'stubresource',
:auth => { :auth => {
'username' => 'test', 'username' => 'test',
'password' => 'abc123', 'password' => 'abc123',
'tenant_name' => 'test', 'project_name' => 'test',
'auth_url' => 'http://127.0.0.1:5000/v2.0', 'auth_url' => 'http://127.0.0.1:5000/v2.0',
} }
} }
end end
@@ -191,7 +215,7 @@ Enabled="True"
end end
it 'retries' do it 'retries' do
provider.class.stubs(:openstack) 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') .raises(Puppet::ExecutionFailure, 'Unable to establish connection')
.then .then
.returns('') .returns('')
@@ -205,7 +229,7 @@ Enabled="True"
describe '::request' do describe '::request' do
context 'with valid password credentials in environment variables' 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 let(:resource_attrs) do
{ {
:name => 'stubresource', :name => 'stubresource',