Merge "Targeting Keystone V3 API support"
This commit is contained in:
@@ -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 = {}
|
||||||
|
@@ -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
|
||||||
|
@@ -10,7 +10,7 @@ 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
|
||||||
|
|
||||||
@@ -22,11 +22,11 @@ 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
|
if provider.class == Class
|
||||||
provider.stubs(:openstack)
|
provider.stubs(:openstack)
|
||||||
@@ -46,6 +46,30 @@ describe Puppet::Provider::Openstack do
|
|||||||
end
|
end
|
||||||
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' ]])
|
||||||
|
.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 'it has no credentials' do
|
shared_examples 'it has no credentials' do
|
||||||
it 'fails to authenticate' do
|
it 'fails to authenticate' do
|
||||||
expect{ provider.request('project', 'list', nil, nil, '--long') }.to raise_error(Puppet::Error::OpenstackAuthInputError, /No credentials provided/)
|
expect{ provider.request('project', 'list', nil, nil, '--long') }.to raise_error(Puppet::Error::OpenstackAuthInputError, /No credentials provided/)
|
||||||
@@ -61,7 +85,7 @@ describe Puppet::Provider::Openstack do
|
|||||||
: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',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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',
|
||||||
@@ -181,7 +205,7 @@ Enabled="True"
|
|||||||
: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',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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',
|
||||||
|
Reference in New Issue
Block a user