Implement Keystone domain creation
Keystone domain has to be created for Heat. This patch implements this via helper script [1] since we don't have support for Keystone v3 API in puppet-keystone yet. This implementation should be refactored as soon as we will have v3 API available in puppet-keystone. For more info please check [2]. [1] https://github.com/openstack/heat/blob/master/bin/heat-keystone-setup-domain [2] https://bugzilla.redhat.com/show_bug.cgi?id=1076172 Change-Id: I036a84eee6b9d0afa9a9ed96849494324ba4c4db
This commit is contained in:
parent
72eee325ef
commit
41608dc6c8
3
Gemfile
3
Gemfile
@ -4,6 +4,9 @@ group :development, :test do
|
|||||||
gem 'puppetlabs_spec_helper', :require => false
|
gem 'puppetlabs_spec_helper', :require => false
|
||||||
gem 'puppet-lint', '~> 0.3.2'
|
gem 'puppet-lint', '~> 0.3.2'
|
||||||
gem 'rake', '10.1.1'
|
gem 'rake', '10.1.1'
|
||||||
|
gem 'rspec', '< 2.99'
|
||||||
|
gem 'json'
|
||||||
|
gem 'webmock'
|
||||||
end
|
end
|
||||||
|
|
||||||
if puppetversion = ENV['PUPPET_GEM_VERSION']
|
if puppetversion = ENV['PUPPET_GEM_VERSION']
|
||||||
|
183
lib/puppet/provider/heat_domain_id_setter/ruby.rb
Normal file
183
lib/puppet/provider/heat_domain_id_setter/ruby.rb
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
## NB: This must work with Ruby 1.8!
|
||||||
|
|
||||||
|
# This provider permits the stack_user_domain parameter in heat.conf
|
||||||
|
# to be set by providing a domain_name to the Puppet module and
|
||||||
|
# using the Keystone REST API to translate the name into the corresponding
|
||||||
|
# UUID.
|
||||||
|
#
|
||||||
|
# This requires that tenant names be unique. If there are multiple matches
|
||||||
|
# for a given tenant name, this provider will raise an exception.
|
||||||
|
|
||||||
|
require 'rubygems'
|
||||||
|
require 'net/http'
|
||||||
|
require 'json'
|
||||||
|
|
||||||
|
class KeystoneError < Puppet::Error
|
||||||
|
end
|
||||||
|
|
||||||
|
class KeystoneConnectionError < KeystoneError
|
||||||
|
end
|
||||||
|
|
||||||
|
class KeystoneAPIError < KeystoneError
|
||||||
|
end
|
||||||
|
|
||||||
|
# Provides common request handling semantics to the other methods in
|
||||||
|
# this module.
|
||||||
|
#
|
||||||
|
# +req+::
|
||||||
|
# An HTTPRequest object
|
||||||
|
# +url+::
|
||||||
|
# A parsed URL (returned from URI.parse)
|
||||||
|
def handle_request(req, url)
|
||||||
|
begin
|
||||||
|
res = Net::HTTP.start(url.host, url.port) {|http|
|
||||||
|
http.request(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
if res.code != '200'
|
||||||
|
raise KeystoneAPIError, "Received error response from Keystone server at #{url}: #{res.message}"
|
||||||
|
end
|
||||||
|
rescue Errno::ECONNREFUSED => detail
|
||||||
|
raise KeystoneConnectionError, "Failed to connect to Keystone server at #{url}: #{detail}"
|
||||||
|
rescue SocketError => detail
|
||||||
|
raise KeystoneConnectionError, "Failed to connect to Keystone server at #{url}: #{detail}"
|
||||||
|
end
|
||||||
|
|
||||||
|
res
|
||||||
|
end
|
||||||
|
|
||||||
|
# Authenticates to a Keystone server and obtains an authentication token.
|
||||||
|
# It returns a 2-element +[token, authinfo]+, where +token+ is a token
|
||||||
|
# suitable for passing to openstack apis in the +X-Auth-Token+ header, and
|
||||||
|
# +authinfo+ is the complete response from Keystone, including the service
|
||||||
|
# catalog (if available).
|
||||||
|
#
|
||||||
|
# +auth_url+::
|
||||||
|
# Keystone endpoint URL. This function assumes API version
|
||||||
|
# 2.0 and an administrative endpoint, so this will typically look like
|
||||||
|
# +http://somehost:35357/v2.0+.
|
||||||
|
#
|
||||||
|
# +username+::
|
||||||
|
# Username for authentication.
|
||||||
|
#
|
||||||
|
# +password+::
|
||||||
|
# Password for authentication
|
||||||
|
#
|
||||||
|
# +tenantID+::
|
||||||
|
# Tenant UUID
|
||||||
|
#
|
||||||
|
# +tenantName+::
|
||||||
|
# Tenant name
|
||||||
|
#
|
||||||
|
def keystone_v2_authenticate(auth_url,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
tenantId=nil,
|
||||||
|
tenantName=nil)
|
||||||
|
|
||||||
|
post_args = {
|
||||||
|
'auth' => {
|
||||||
|
'passwordCredentials' => {
|
||||||
|
'username' => username,
|
||||||
|
'password' => password
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
|
||||||
|
if tenantId
|
||||||
|
post_args['auth']['tenantId'] = tenantId
|
||||||
|
end
|
||||||
|
|
||||||
|
if tenantName
|
||||||
|
post_args['auth']['tenantName'] = tenantName
|
||||||
|
end
|
||||||
|
|
||||||
|
url = URI.parse("#{auth_url}/tokens")
|
||||||
|
req = Net::HTTP::Post.new url.path
|
||||||
|
req['content-type'] = 'application/json'
|
||||||
|
req.body = post_args.to_json
|
||||||
|
|
||||||
|
res = handle_request(req, url)
|
||||||
|
data = JSON.parse res.body
|
||||||
|
return data['access']['token']['id'], data
|
||||||
|
end
|
||||||
|
|
||||||
|
# Queries a Keystone server to a list of all tenants.
|
||||||
|
#
|
||||||
|
# +auth_url+::
|
||||||
|
# Keystone endpoint. See the notes for +auth_url+ in
|
||||||
|
# +keystone_v2_authenticate+.
|
||||||
|
#
|
||||||
|
# +token+::
|
||||||
|
# A Keystone token that will be passed in requests as the value of the
|
||||||
|
# +X-Auth-Token+ header.
|
||||||
|
#
|
||||||
|
def keystone_v3_domains(auth_url,
|
||||||
|
token)
|
||||||
|
|
||||||
|
auth_url.sub!('v2.0', 'v3')
|
||||||
|
url = URI.parse("#{auth_url}/domains")
|
||||||
|
req = Net::HTTP::Get.new url.path
|
||||||
|
req['content-type'] = 'application/json'
|
||||||
|
req['x-auth-token'] = token
|
||||||
|
|
||||||
|
res = handle_request(req, url)
|
||||||
|
data = JSON.parse res.body
|
||||||
|
data['domains']
|
||||||
|
end
|
||||||
|
|
||||||
|
Puppet::Type.type(:heat_domain_id_setter).provide(:ruby) do
|
||||||
|
def authenticate
|
||||||
|
token, authinfo = keystone_v2_authenticate(
|
||||||
|
@resource[:auth_url],
|
||||||
|
@resource[:auth_username],
|
||||||
|
@resource[:auth_password],
|
||||||
|
nil,
|
||||||
|
@resource[:auth_tenant_name])
|
||||||
|
|
||||||
|
return token
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_domain_by_name(token)
|
||||||
|
domains = keystone_v3_domains(
|
||||||
|
@resource[:auth_url],
|
||||||
|
token)
|
||||||
|
domains.select{|domain| domain['name'] == @resource[:domain_name]}
|
||||||
|
end
|
||||||
|
|
||||||
|
def exists?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
config
|
||||||
|
end
|
||||||
|
|
||||||
|
# This looks for the domain specified by the 'domain_name' parameter to
|
||||||
|
# the resource and returns the corresponding UUID if there is a single
|
||||||
|
# match.
|
||||||
|
#
|
||||||
|
# Raises a KeystoneAPIError if:
|
||||||
|
#
|
||||||
|
# - There are multiple matches, or
|
||||||
|
# - There are zero matches
|
||||||
|
def get_domain_id
|
||||||
|
token = authenticate
|
||||||
|
domains = find_domain_by_name(token)
|
||||||
|
|
||||||
|
if domains.length == 1
|
||||||
|
return domains[0]['id']
|
||||||
|
elsif domains.length > 1
|
||||||
|
name = domains[0]['name']
|
||||||
|
raise KeystoneAPIError, 'Found multiple matches for domain name "#{name}"'
|
||||||
|
else
|
||||||
|
raise KeystoneAPIError, 'Unable to find matching domain'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def config
|
||||||
|
Puppet::Type.type(:heat_config).new(
|
||||||
|
{:name => 'DEFAULT/stack_user_domain', :value => "#{get_domain_id}"}
|
||||||
|
).create
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
@ -40,4 +40,8 @@ Puppet::Type.newtype(:heat_config) do
|
|||||||
defaultto false
|
defaultto false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
provider.create
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
31
lib/puppet/type/heat_domain_id_setter.rb
Normal file
31
lib/puppet/type/heat_domain_id_setter.rb
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
Puppet::Type.newtype(:heat_domain_id_setter) do
|
||||||
|
|
||||||
|
ensurable
|
||||||
|
|
||||||
|
newparam(:name, :namevar => true) do
|
||||||
|
desc 'The name of the setting to update'
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:domain_name) do
|
||||||
|
desc 'The heat domain name'
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:auth_url) do
|
||||||
|
desc 'The Keystone endpoint URL'
|
||||||
|
defaultto 'http://localhost:35357/v2.0'
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:auth_username) do
|
||||||
|
desc 'Username with which to authenticate'
|
||||||
|
defaultto 'admin'
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:auth_password) do
|
||||||
|
desc 'Password with which to authenticate'
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:auth_tenant_name) do
|
||||||
|
desc 'Tenant name with which to authenticate'
|
||||||
|
defaultto 'admin'
|
||||||
|
end
|
||||||
|
end
|
73
manifests/keystone/domain.pp
Normal file
73
manifests/keystone/domain.pp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
# == Class: heat::keystone::domain
|
||||||
|
#
|
||||||
|
# Configures heat domain in Keystone.
|
||||||
|
#
|
||||||
|
# Note: Implementation is done by heat-keystone-setup-domain script temporarily
|
||||||
|
# because currently puppet-keystone does not support v3 API
|
||||||
|
#
|
||||||
|
# === Parameters
|
||||||
|
#
|
||||||
|
# [*auth_url*]
|
||||||
|
# Keystone auth url
|
||||||
|
#
|
||||||
|
# [*keystone_admin*]
|
||||||
|
# Keystone admin user
|
||||||
|
#
|
||||||
|
# [*keystone_password*]
|
||||||
|
# Keystone admin password
|
||||||
|
#
|
||||||
|
# [*keystone_tenant*]
|
||||||
|
# Keystone admin tenant name
|
||||||
|
#
|
||||||
|
# [*domain_name*]
|
||||||
|
# Heat domain name. Defaults to 'heat'.
|
||||||
|
#
|
||||||
|
# [*domain_admin*]
|
||||||
|
# Keystone domain admin user which will be created. Defaults to 'heat_admin'.
|
||||||
|
#
|
||||||
|
# [*domain_password*]
|
||||||
|
# Keystone domain admin user password. Defaults to 'changeme'.
|
||||||
|
#
|
||||||
|
class heat::keystone::domain (
|
||||||
|
$auth_url = undef,
|
||||||
|
$keystone_admin = undef,
|
||||||
|
$keystone_password = undef,
|
||||||
|
$keystone_tenant = undef,
|
||||||
|
$domain_name = 'heat',
|
||||||
|
$domain_admin = 'heat_admin',
|
||||||
|
$domain_password = 'changeme',
|
||||||
|
) {
|
||||||
|
|
||||||
|
include heat::params
|
||||||
|
|
||||||
|
$cmd_evn = [
|
||||||
|
"OS_USERNAME=${keystone_admin}",
|
||||||
|
"OS_PASSWORD=${keystone_password}",
|
||||||
|
"OS_AUTH_URL=${auth_url}",
|
||||||
|
"HEAT_DOMAIN=${domain_name}",
|
||||||
|
"HEAT_DOMAIN_ADMIN=${domain_admin}",
|
||||||
|
"HEAT_DOMAIN_PASSWORD=${domain_password}"
|
||||||
|
]
|
||||||
|
exec { 'heat_domain_create':
|
||||||
|
path => '/usr/bin',
|
||||||
|
command => 'heat-keystone-setup-domain &>/dev/null',
|
||||||
|
environment => $cmd_evn,
|
||||||
|
require => Package['heat-common'],
|
||||||
|
}
|
||||||
|
|
||||||
|
heat_domain_id_setter { 'heat_domain_id':
|
||||||
|
ensure => present,
|
||||||
|
domain_name => $domain_name,
|
||||||
|
auth_url => $auth_url,
|
||||||
|
auth_username => $keystone_admin,
|
||||||
|
auth_password => $keystone_password,
|
||||||
|
auth_tenant_name => $keystone_tenant,
|
||||||
|
require => Exec['heat_domain_create'],
|
||||||
|
}
|
||||||
|
|
||||||
|
heat_config {
|
||||||
|
'DEFAULT/stack_domain_admin': value => $domain_admin;
|
||||||
|
'DEFAULT/stack_domain_admin_password': value => $domain_password;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
66
spec/classes/heat_keystone_domain_spec.rb
Normal file
66
spec/classes/heat_keystone_domain_spec.rb
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe 'heat::keystone::domain' do
|
||||||
|
|
||||||
|
let :params do {
|
||||||
|
:auth_url => 'http://127.0.0.1:35357/v2.0',
|
||||||
|
:keystone_admin => 'admin',
|
||||||
|
:keystone_password => 'admin_passwd',
|
||||||
|
:keystone_tenant => 'admin',
|
||||||
|
:domain_name => 'heat',
|
||||||
|
:domain_admin => 'heat_admin',
|
||||||
|
:domain_password => 'domain_passwd'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_examples_for 'heat keystone domain' do
|
||||||
|
it 'configure heat.conf' do
|
||||||
|
should contain_heat_config('DEFAULT/stack_domain_admin').with_value(params[:domain_admin])
|
||||||
|
should contain_heat_config('DEFAULT/stack_domain_admin_password').with_value(params[:domain_password])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should configure heat domain id' do
|
||||||
|
should contain_heat_domain_id_setter('heat_domain_id').with(
|
||||||
|
:ensure => 'present',
|
||||||
|
:domain_name => params[:domain_name],
|
||||||
|
:auth_url => params[:auth_url],
|
||||||
|
:auth_username => params[:keystone_admin],
|
||||||
|
:auth_password => params[:keystone_password],
|
||||||
|
:auth_tenant_name => params[:keystone_tenant]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should exec helper script' do
|
||||||
|
should contain_exec('heat_domain_create').with(
|
||||||
|
:command => 'heat-keystone-setup-domain &>/dev/null',
|
||||||
|
:path => '/usr/bin',
|
||||||
|
:require => 'Package[heat-common]',
|
||||||
|
:environment => [
|
||||||
|
"OS_USERNAME=#{params[:keystone_admin]}",
|
||||||
|
"OS_PASSWORD=#{params[:keystone_password]}",
|
||||||
|
"OS_AUTH_URL=#{params[:auth_url]}",
|
||||||
|
"HEAT_DOMAIN=#{params[:domain_name]}",
|
||||||
|
"HEAT_DOMAIN_ADMIN=#{params[:domain_admin]}",
|
||||||
|
"HEAT_DOMAIN_PASSWORD=#{params[:domain_password]}"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
context 'on Debian platforms' do
|
||||||
|
let :facts do
|
||||||
|
{ :osfamily => 'Debian' }
|
||||||
|
end
|
||||||
|
|
||||||
|
it_configures 'heat keystone domain'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'on RedHat platforms' do
|
||||||
|
let :facts do
|
||||||
|
{ :osfamily => 'RedHat' }
|
||||||
|
end
|
||||||
|
|
||||||
|
it_configures 'heat keystone domain'
|
||||||
|
end
|
||||||
|
end
|
@ -1,5 +1,7 @@
|
|||||||
require 'puppetlabs_spec_helper/module_spec_helper'
|
require 'puppetlabs_spec_helper/module_spec_helper'
|
||||||
require 'shared_examples'
|
require 'shared_examples'
|
||||||
|
require 'webmock/rspec'
|
||||||
|
require 'json'
|
||||||
|
|
||||||
RSpec.configure do |c|
|
RSpec.configure do |c|
|
||||||
c.alias_it_should_behave_like_to :it_configures, 'configures'
|
c.alias_it_should_behave_like_to :it_configures, 'configures'
|
||||||
|
177
spec/unit/provider/heat_domain_id_setter/heat_spec.rb
Normal file
177
spec/unit/provider/heat_domain_id_setter/heat_spec.rb
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
require 'puppet'
|
||||||
|
require 'puppet/type/heat_domain_id_setter'
|
||||||
|
|
||||||
|
provider_class = Puppet::Type.type(:heat_domain_id_setter).provider(:ruby)
|
||||||
|
|
||||||
|
# used to simulate an authentication response from Keystone
|
||||||
|
# (POST v2.0/tokens)
|
||||||
|
auth_response = {
|
||||||
|
'access' => {
|
||||||
|
'token' => {
|
||||||
|
'id' => 'TOKEN',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# used to simulate a response to GET v3/domains
|
||||||
|
domains_response = {
|
||||||
|
'domains' => [
|
||||||
|
{
|
||||||
|
'name' => 'heat',
|
||||||
|
'id' => 'UUID_HEAT'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name' => 'multiple_matches_domain',
|
||||||
|
'id' => 'UUID1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name' => 'multiple_matches_domain',
|
||||||
|
'id' => 'UUID2'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Stub for ini_setting resource
|
||||||
|
Puppet::Type.newtype(:ini_setting) do
|
||||||
|
end
|
||||||
|
|
||||||
|
# Stub for ini_setting provider
|
||||||
|
Puppet::Type.newtype(:ini_setting).provide(:ruby) do
|
||||||
|
def create
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'Puppet::Type.type(:heat_keystone_domain_id_setter)' do
|
||||||
|
let :params do
|
||||||
|
{
|
||||||
|
:name => 'heat_domain_id',
|
||||||
|
:ensure => 'present',
|
||||||
|
:domain_name => 'heat',
|
||||||
|
:auth_url => 'http://127.0.0.1:35357/v2.0',
|
||||||
|
:auth_username => 'admin',
|
||||||
|
:auth_password => 'admin_passwd',
|
||||||
|
:auth_tenant_name => 'admin',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should have a non-nil provider' do
|
||||||
|
expect(provider_class).not_to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when url is correct' do
|
||||||
|
before :each do
|
||||||
|
stub_request(:post, "http://127.0.0.1:35357/v2.0/tokens").
|
||||||
|
to_return(:status => 200,
|
||||||
|
:body => auth_response.to_json,
|
||||||
|
:headers => {})
|
||||||
|
stub_request(:get, "http://127.0.0.1:35357/v3/domains").
|
||||||
|
with(:headers => {'X-Auth-Token'=>'TOKEN'}).
|
||||||
|
to_return(:status => 200,
|
||||||
|
:body => domains_response.to_json,
|
||||||
|
:headers => {})
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should create a resource' do
|
||||||
|
resource = Puppet::Type::Heat_domain_id_setter.new(params)
|
||||||
|
provider = provider_class.new(resource)
|
||||||
|
expect(provider.exists?).to be_false
|
||||||
|
expect(provider.create).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# What happens if we ask for a domain that does not exist?
|
||||||
|
context 'when domain cannot be found' do
|
||||||
|
before :each do
|
||||||
|
stub_request(:post, "http://127.0.0.1:35357/v2.0/tokens").
|
||||||
|
to_return(:status => 200,
|
||||||
|
:body => auth_response.to_json,
|
||||||
|
:headers => {})
|
||||||
|
stub_request(:get, "http://127.0.0.1:35357/v3/domains").
|
||||||
|
with(:headers => {'X-Auth-Token'=>'TOKEN'}).
|
||||||
|
to_return(:status => 200,
|
||||||
|
:body => domains_response.to_json,
|
||||||
|
:headers => {})
|
||||||
|
|
||||||
|
params.merge!(:domain_name => 'bad_domain_name')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should receive an api error' do
|
||||||
|
resource = Puppet::Type::Heat_domain_id_setter.new(params)
|
||||||
|
provider = provider_class.new(resource)
|
||||||
|
expect(provider.exists?).to be_false
|
||||||
|
expect { provider.create }.to raise_error KeystoneAPIError, /Unable to find matching domain/
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# What happens if we ask for a domain name that results in multiple
|
||||||
|
# matches?
|
||||||
|
context 'when there are multiple matching domains' do
|
||||||
|
before :each do
|
||||||
|
stub_request(:post, "http://127.0.0.1:35357/v2.0/tokens").
|
||||||
|
to_return(:status => 200,
|
||||||
|
:body => auth_response.to_json,
|
||||||
|
:headers => {})
|
||||||
|
stub_request(:get, "http://127.0.0.1:35357/v3/domains").
|
||||||
|
with(:headers => {'X-Auth-Token'=>'TOKEN'}).
|
||||||
|
to_return(:status => 200,
|
||||||
|
:body => domains_response.to_json,
|
||||||
|
:headers => {})
|
||||||
|
|
||||||
|
params.merge!(:domain_name => 'multiple_matches_domain')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should receive an api error' do
|
||||||
|
resource = Puppet::Type::Heat_domain_id_setter.new(params)
|
||||||
|
provider = provider_class.new(resource)
|
||||||
|
expect(provider.exists?).to be_false
|
||||||
|
expect { provider.create }.to raise_error KeystoneAPIError, /Found multiple matches for domain name/
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# What happens if we pass a bad password?
|
||||||
|
context 'when password is incorrect' do
|
||||||
|
before :each do
|
||||||
|
stub_request(:post, "http://127.0.0.1:35357/v2.0/tokens").
|
||||||
|
to_return(:status => 401,
|
||||||
|
:body => auth_response.to_json,
|
||||||
|
:headers => {})
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should receive an authentication error' do
|
||||||
|
resource = Puppet::Type::Heat_domain_id_setter.new(params)
|
||||||
|
provider = provider_class.new(resource)
|
||||||
|
expect(provider.exists?).to be_false
|
||||||
|
expect { provider.create }.to raise_error KeystoneAPIError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# What happens if the server is not listening?
|
||||||
|
context 'when keystone server is unavailable' do
|
||||||
|
before :each do
|
||||||
|
stub_request(:post, "http://127.0.0.1:35357/v2.0/tokens").to_raise Errno::ECONNREFUSED
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should receive a connection error' do
|
||||||
|
resource = Puppet::Type::Heat_domain_id_setter.new(params)
|
||||||
|
provider = provider_class.new(resource)
|
||||||
|
expect(provider.exists?).to be_false
|
||||||
|
expect { provider.create }.to raise_error KeystoneConnectionError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# What happens if we mistype the hostname?
|
||||||
|
context 'when keystone server is unknown' do
|
||||||
|
before :each do
|
||||||
|
stub_request(:post, "http://127.0.0.1:35357/v2.0/tokens").to_raise SocketError, 'getaddrinfo: Name or service not known'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should receive a connection error' do
|
||||||
|
resource = Puppet::Type::Heat_domain_id_setter.new(params)
|
||||||
|
provider = provider_class.new(resource)
|
||||||
|
expect(provider.exists?).to be_false
|
||||||
|
expect { provider.create }.to raise_error KeystoneConnectionError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user