
This patch adds a dependency on the aimonb/aviator module and adds functionality to support interactions with the OpenStack services' API via aviator. The patch adds a parent provider that is intended for other providers to inherit from. The parent provider has methods to authenticate to openstack services, create session objects, and make requests. The authenticate method can accept credentials as an argument hash or infer credentials from the environment. It also adds a stub type parameter that allows types to incorporate basic parameters they need in order to support using aviator. Change-Id: I56b0d07ae8f4738037eda486b75a0f6e24fe80e7 Implements: blueprint use-aviator-in-module-resources
321 lines
10 KiB
Ruby
321 lines
10 KiB
Ruby
# Load libraries from aviator here to simulate how they live together in a real puppet run
|
|
$LOAD_PATH.push(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'modules', 'aviator', 'lib'))
|
|
require 'puppet'
|
|
require 'vcr'
|
|
require 'spec_helper'
|
|
require 'puppet/provider/aviator'
|
|
|
|
|
|
describe Puppet::Provider::Aviator do
|
|
|
|
before(:each) do
|
|
ENV['OS_USERNAME'] = nil
|
|
ENV['OS_PASSWORD'] = nil
|
|
ENV['OS_TENANT_NAME'] = nil
|
|
ENV['OS_AUTH_URL'] = nil
|
|
end
|
|
|
|
let(:log_file) { '/tmp/aviator_spec.log' }
|
|
|
|
let(:type) do
|
|
Puppet::Type.newtype(:test_resource) do
|
|
newparam(:name, :namevar => true)
|
|
newparam(:auth)
|
|
newparam(:log_file)
|
|
end
|
|
end
|
|
|
|
|
|
shared_examples 'creating a session using environment variables' do
|
|
it 'creates an authenticated session' do
|
|
ENV['OS_USERNAME'] = 'admin'
|
|
ENV['OS_PASSWORD'] = 'fyby-tet'
|
|
ENV['OS_TENANT_NAME'] = 'admin'
|
|
ENV['OS_AUTH_URL'] = 'http://192.168.11.4:35357/v2.0'
|
|
response = nil
|
|
VCR.use_cassette('aviator/session/with_password') do
|
|
session = provider.session
|
|
response = session.identity_service.request(:list_tenants, :session_data => provider.session_data)
|
|
end
|
|
expect(response.status).to eq(200)
|
|
end
|
|
end
|
|
|
|
shared_examples 'creating a session using a service token from keystone.conf' do
|
|
it 'creates an unauthenticated session' do
|
|
data = "[DEFAULT]\nadmin_token=sosp-kyl\nadmin_endpoint=http://192.168.11.4:35357/v2.0"
|
|
response = nil
|
|
VCR.use_cassette('aviator/session/with_token') do
|
|
# Stubbing File.read produces inconsistent results because of how IniConfig
|
|
# overrides the File class in some versions of Puppet.
|
|
# Stubbing FileType.filetype(:flat) simplifies working with IniConfig
|
|
Puppet::Util::FileType.filetype(:flat).any_instance.expects(:read).returns(StringIO.new(data).read)
|
|
session = provider.session
|
|
Puppet::Util::FileType.filetype(:flat).any_instance.unstub(:read)
|
|
response = session.identity_service.request(:list_tenants, :session_data => provider.session_data)
|
|
end
|
|
|
|
expect(response.status).to eq(200)
|
|
end
|
|
end
|
|
|
|
shared_examples 'it has no credentials' do
|
|
it 'fails to authenticate' do
|
|
expect{ provider.session }.to raise_error(Puppet::Error, /No credentials provided/)
|
|
end
|
|
end
|
|
|
|
shared_examples 'making request with an existing session' do
|
|
it 'makes a successful request' do
|
|
VCR.use_cassette('aviator/request/with_session') do
|
|
session = provider.session
|
|
response = provider.request(session.identity_service, :list_tenants)
|
|
expect(response.status).to eq(200)
|
|
end
|
|
end
|
|
end
|
|
|
|
shared_examples 'making request with injected session data' do
|
|
it 'makes a successful request' do
|
|
VCR.use_cassette('aviator/request/without_session') do
|
|
session = provider.session
|
|
response = provider.request(session.identity_service, :list_tenants)
|
|
expect(response.status).to eq(200)
|
|
end
|
|
end
|
|
end
|
|
|
|
shared_examples 'making request with no session or session data' do
|
|
it 'fails to make a request' do
|
|
expect{ provider.request(nil, :list_tenants) }.to raise_error(Puppet::Error, /Cannot make a request/)
|
|
end
|
|
end
|
|
|
|
describe '#session' do
|
|
|
|
context 'with valid password credentials in parameters' do
|
|
let(:resource_attrs) do
|
|
{
|
|
:name => 'stubresource',
|
|
:auth => {
|
|
'username' => 'admin',
|
|
'password' => 'fyby-tet',
|
|
'tenant_name' => 'admin',
|
|
'host_uri' => 'http://192.168.11.4:35357/v2.0',
|
|
}
|
|
}
|
|
end
|
|
|
|
it 'creates a session' do
|
|
provider = Puppet::Provider::Aviator.new(type.new(resource_attrs))
|
|
response = nil
|
|
VCR.use_cassette('aviator/session/with_password') do
|
|
session = provider.session
|
|
response = session.identity_service.request(:list_tenants)
|
|
end
|
|
expect(response.status).to eq(200)
|
|
end
|
|
end
|
|
|
|
context 'with valid openrc file in parameters' do
|
|
data = "export OS_USERNAME='admin'\nexport OS_PASSWORD='fyby-tet'\nexport OS_TENANT_NAME='admin'\nexport OS_AUTH_URL='http://192.168.11.4:35357/v2.0'"
|
|
let(:resource_attrs) do
|
|
{
|
|
:name => 'stubresource',
|
|
:auth => {
|
|
'openrc' => '/root/openrc'
|
|
}
|
|
}
|
|
end
|
|
|
|
it 'creates a session' do
|
|
provider = Puppet::Provider::Aviator.new(type.new(resource_attrs))
|
|
response = nil
|
|
VCR.use_cassette('aviator/session/with_password') do
|
|
File.expects(:open).with('/root/openrc').returns(StringIO.new(data))
|
|
session = provider.session
|
|
File.unstub(:open) # Ignore File.open calls to cassette file
|
|
response = session.identity_service.request(:list_tenants)
|
|
end
|
|
expect(response.status).to eq(200)
|
|
end
|
|
end
|
|
|
|
context 'with valid service token in parameters' do
|
|
let(:resource_attrs) do
|
|
{
|
|
:name => 'stubresource',
|
|
:auth => {
|
|
'service_token' => 'sosp-kyl',
|
|
'host_uri' => 'http://192.168.11.4:35357/v2.0'
|
|
}
|
|
}
|
|
end
|
|
|
|
subject(:session) do
|
|
provider = Puppet::Provider::Aviator.new(type.new(resource_attrs))
|
|
VCR.use_cassette('aviator/session/with_token') do
|
|
session = provider.session
|
|
response = session.identity_service.request(:list_tenants, :session_data => provider.session_data)
|
|
end
|
|
end
|
|
|
|
it 'creates a session' do
|
|
expect(session.status).to eq(200)
|
|
end
|
|
|
|
end
|
|
|
|
context 'with valid password credentials in environment variables' do
|
|
it_behaves_like 'creating a session using environment variables' do
|
|
let(:resource_attrs) do
|
|
{
|
|
:name => 'stubresource',
|
|
}
|
|
end
|
|
let(:provider) do
|
|
Puppet::Provider::Aviator.new(type.new(resource_attrs))
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'with valid service token in keystone.conf' do
|
|
it_behaves_like 'creating a session using a service token from keystone.conf' do
|
|
let(:resource_attrs) do
|
|
{
|
|
:name => 'stubresource',
|
|
}
|
|
end
|
|
let(:provider) do
|
|
Puppet::Provider::Aviator.new(type.new(resource_attrs))
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
context 'with no valid credentials' do
|
|
it_behaves_like 'it has no credentials' do
|
|
let(:resource_attrs) do
|
|
{
|
|
:name => 'stubresource',
|
|
}
|
|
end
|
|
let(:provider) { Puppet::Provider::Aviator.new(type.new(resource_attrs)) }
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
|
|
describe '::session' do
|
|
|
|
context 'with valid password credentials in environment variables' do
|
|
it_behaves_like 'creating a session using environment variables' do
|
|
let(:provider) { Puppet::Provider::Aviator.dup }
|
|
end
|
|
end
|
|
|
|
context 'with valid service token in keystone.conf' do
|
|
it_behaves_like 'creating a session using a service token from keystone.conf' do
|
|
let(:provider) { Puppet::Provider::Aviator.dup }
|
|
end
|
|
end
|
|
|
|
context 'with no valid credentials' do
|
|
it_behaves_like 'it has no credentials' do
|
|
let(:provider) { Puppet::Provider::Aviator.dup }
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#request' do
|
|
context 'when a session exists' do
|
|
it_behaves_like 'making request with an existing session' do
|
|
let(:resource_attrs) do
|
|
{
|
|
:name => 'stubresource',
|
|
:auth => {
|
|
'username' => 'admin',
|
|
'password' => 'fyby-tet',
|
|
'tenant_name' => 'admin',
|
|
'host_uri' => 'http://192.168.11.4:35357/v2.0',
|
|
}
|
|
}
|
|
end
|
|
let (:provider) { Puppet::Provider::Aviator.new(type.new(resource_attrs)) }
|
|
end
|
|
end
|
|
|
|
context 'when injecting session data' do
|
|
let(:resource_attrs) do
|
|
{
|
|
:name => 'stubresource',
|
|
:auth => {
|
|
'service_token' => 'sosp-kyl',
|
|
'host_uri' => 'http://192.168.11.4:35357/v2.0'
|
|
}
|
|
}
|
|
end
|
|
let(:provider) { Puppet::Provider::Aviator.new(type.new(resource_attrs)) }
|
|
it 'makes a successful request' do
|
|
provider = Puppet::Provider::Aviator.new(type.new(resource_attrs))
|
|
VCR.use_cassette('aviator/request/without_session') do
|
|
session = provider.session
|
|
response = provider.request(session.identity_service, :list_tenants)
|
|
expect(response.status).to eq(200)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when there is no session or session data' do
|
|
it_behaves_like 'making request with no session or session data' do
|
|
let(:resource_attrs) do
|
|
{
|
|
:name => 'stubresource',
|
|
}
|
|
end
|
|
let(:provider) {Puppet::Provider::Aviator.new(type.new(resource_attrs)) }
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '::request' do
|
|
context 'when a session exists' do
|
|
|
|
it_behaves_like 'making request with an existing session' do
|
|
let(:provider) { provider = Puppet::Provider::Aviator.dup }
|
|
before(:each) do
|
|
ENV['OS_USERNAME'] = 'admin'
|
|
ENV['OS_PASSWORD'] = 'fyby-tet'
|
|
ENV['OS_TENANT_NAME'] = 'admin'
|
|
ENV['OS_AUTH_URL'] = 'http://192.168.11.4:35357/v2.0'
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when injecting session data' do
|
|
let(:session_data) do
|
|
{
|
|
:base_url => 'http://192.168.11.4:35357/v2.0',
|
|
:service_token => 'sosp-kyl'
|
|
}
|
|
end
|
|
it 'makes a successful request' do
|
|
provider = Puppet::Provider::Aviator.dup
|
|
VCR.use_cassette('aviator/request/without_session') do
|
|
session = ::Aviator::Session.new(:config => { :provider => 'openstack' }, :log_file => log_file)
|
|
provider.session_data = session_data
|
|
response = provider.request(session.identity_service, :list_tenants)
|
|
expect(response.status).to eq(200)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when there is no session or session data' do
|
|
it_behaves_like 'making request with no session or session data' do
|
|
let(:provider) { Puppet::Provider::Aviator.dup }
|
|
end
|
|
end
|
|
end
|
|
end
|