Endpoints can be APIs version-less

Since Keystone V3, the endpoints don't need API versions numbers to be specified
in their respective URL [1]. Effectively, Keystone automatically adjusts to
either versions depending on the context.

For instance, using the default values will generate the following catalog:
keystone identity RegionOne
  publicURL: http://127.0.0.1:5000
  internalURL: http://127.0.0.1:5000
  adminURL: http://127.0.0.1:35357

Note:
Openstack wiki pages might not reflect this entirely yet and there are still
examples using the version number in the URLs.

This patch preserves the version parameter for the endpoint manifests but also
allows the version to be removed properly when it's blandked (version => '').

[1] https://github.com/openstack/keystone/blob/master/doc/source/http-api.rst

Change-Id: I8584d1c1e0a111d016ee507f8b004d5e131a2700
This commit is contained in:
Gilles Dubreuil 2015-08-18 11:25:46 +10:00
parent 6d8239183b
commit 9f8ea7d7b4
6 changed files with 66 additions and 31 deletions

View File

@ -102,11 +102,9 @@ Puppet::Type.type(:keystone_user).provide(
else else
# Password validation # Password validation
credentials = Puppet::Provider::Openstack::CredentialsV3.new credentials = Puppet::Provider::Openstack::CredentialsV3.new
unless auth_url = self.class.get_auth_url unless credentials.auth_url = self.class.get_auth_url
raise(Puppet::Error::OpenstackAuthInputError, "Could not find authentication url to validate user's password.") raise(Puppet::Error::OpenstackAuthInputError, "Could not find authentication url to validate user's password.")
end end
auth_url << "/v#{credentials.version}" unless auth_url =~ /\/v\d(\.\d)?$/
credentials.auth_url = auth_url
credentials.password = resource[:password] credentials.password = resource[:password]
credentials.user_id = id credentials.user_id = id

View File

@ -5,23 +5,23 @@
# === Parameters # === Parameters
# #
# [*public_url*] # [*public_url*]
# (optional) Public url for keystone endpoint. (Defaults to 'http://127.0.0.1:5000') # (optional) Public url for keystone endpoint.
# Defaults to 'http://127.0.0.1:5000'
# This url should *not* contain any version or trailing '/'. # This url should *not* contain any version or trailing '/'.
# #
# [*internal_url*] # [*internal_url*]
# (optional) Internal url for keystone endpoint. (Defaults to $public_url) # (optional) Internal url for keystone endpoint.
# Defaults to $public_url
# This url should *not* contain any version or trailing '/'. # This url should *not* contain any version or trailing '/'.
# #
# [*admin_url*] # [*admin_url*]
# (optional) Admin url for keystone endpoint. (Defaults to 'http://127.0.0.1:35357') # (optional) Admin url for keystone endpoint.
# Defaults to 'http://127.0.0.1:35357'
# This url should *not* contain any version or trailing '/'. # This url should *not* contain any version or trailing '/'.
# #
# [*region*] # [*region*]
# (optional) Region for endpoint. (Defaults to 'RegionOne') # (optional) Region for endpoint. (Defaults to 'RegionOne')
# #
# [*version*]
# (optional) API version for endpoint. Appended to all endpoint urls. (Defaults to 'v2.0')
#
# [*user_domain*] # [*user_domain*]
# (Optional) Domain for $auth_name # (Optional) Domain for $auth_name
# Defaults to undef (use the keystone server default domain) # Defaults to undef (use the keystone server default domain)
@ -36,6 +36,15 @@
# If keystone_project_domain is not specified, use $keystone_default_domain # If keystone_project_domain is not specified, use $keystone_default_domain
# Defaults to undef # Defaults to undef
# #
# === DEPRECATED
#
# [*version*]
# (optional) API version for endpoint.
# Defaults to 'v2.0'
# If the version is assigned to null value (forced to undef), then it won't be
# used. This is the expected behaviour since Keystone V3 handles API versions
# from the context.
#
# === Examples # === Examples
# #
# class { 'keystone::endpoint': # class { 'keystone::endpoint':
@ -48,20 +57,36 @@ class keystone::endpoint (
$public_url = 'http://127.0.0.1:5000', $public_url = 'http://127.0.0.1:5000',
$internal_url = undef, $internal_url = undef,
$admin_url = 'http://127.0.0.1:35357', $admin_url = 'http://127.0.0.1:35357',
$version = 'v2.0',
$region = 'RegionOne', $region = 'RegionOne',
$user_domain = undef, $user_domain = undef,
$project_domain = undef, $project_domain = undef,
$default_domain = undef, $default_domain = undef,
$version = 'v2.0', # DEPRECATED
) { ) {
$public_url_real = "${public_url}/${version}" if empty($version) {
$admin_url_real = "${admin_url}/${version}" $admin_url_real = $admin_url
$public_url_real = $public_url
if $internal_url { if $internal_url {
$internal_url_real = "${internal_url}/${version}" $internal_url_real = $internal_url
} else { }
$internal_url_real = "${public_url}/${version}" else {
$internal_url_real = $public_url
}
}
else {
warning('The version parameter is deprecated in Liberty.')
$public_url_real = "${public_url}/${version}"
$admin_url_real = "${admin_url}/${version}"
if $internal_url {
$internal_url_real = "${internal_url}/${version}"
}
else {
$internal_url_real = "${public_url}/${version}"
}
} }
keystone::resource::service_identity { 'keystone': keystone::resource::service_identity { 'keystone':
@ -77,5 +102,4 @@ class keystone::endpoint (
project_domain => $project_domain, project_domain => $project_domain,
default_domain => $default_domain, default_domain => $default_domain,
} }
} }

View File

@ -74,9 +74,8 @@ describe 'basic keystone server with resources' do
email => 'test@example.tld', email => 'test@example.tld',
password => 'a_big_secret', password => 'a_big_secret',
} }
# Default Keystone endpoints use localhost, default ports and v2.0
class { '::keystone::endpoint': class { '::keystone::endpoint':
public_url => "http://127.0.0.1:5000/",
admin_url => "http://127.0.0.1:35357/",
default_domain => 'admin', default_domain => 'admin',
} }
::keystone::resource::service_identity { 'beaker-ci': ::keystone::resource::service_identity { 'beaker-ci':

View File

@ -73,9 +73,8 @@ describe 'keystone server running with Apache/WSGI with resources' do
email => 'test@example.tld', email => 'test@example.tld',
password => 'a_big_secret', password => 'a_big_secret',
} }
# Default Keystone endpoints use localhost, default ports and v2.0
class { '::keystone::endpoint': class { '::keystone::endpoint':
public_url => "http://127.0.0.1:5000/",
admin_url => "http://127.0.0.1:35357/",
default_domain => 'admin', default_domain => 'admin',
} }
::keystone::resource::service_identity { 'beaker-ci': ::keystone::resource::service_identity { 'beaker-ci':

View File

@ -34,6 +34,21 @@ describe 'keystone::endpoint' do
)} )}
end end
describe 'without a version' do
# We need to test empty value '' to override the default value, using undef
# cannot un-set classes parameters.
let :params do
{ :version => '' }
end
it { is_expected.to contain_keystone_endpoint('RegionOne/keystone').with(
:ensure => 'present',
:public_url => 'http://127.0.0.1:5000',
:admin_url => 'http://127.0.0.1:35357',
:internal_url => 'http://127.0.0.1:5000'
)}
end
describe 'without internal_url parameter' do describe 'without internal_url parameter' do
let :params do let :params do

View File

@ -10,7 +10,7 @@ describe provider_class do
ENV['OS_USERNAME'] = 'test' ENV['OS_USERNAME'] = 'test'
ENV['OS_PASSWORD'] = 'abc123' ENV['OS_PASSWORD'] = 'abc123'
ENV['OS_PROJECT_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:5000'
end end
describe 'when managing an endpoint' do describe 'when managing an endpoint' do
@ -19,9 +19,9 @@ describe provider_class do
{ {
:name => 'foo/bar', :name => 'foo/bar',
:ensure => 'present', :ensure => 'present',
:public_url => 'http://127.0.0.1:5000/v2.0', :public_url => 'http://127.0.0.1:5000',
:internal_url => 'http://127.0.0.1:5001/v2.0', :internal_url => 'http://127.0.0.1:5001',
:admin_url => 'http://127.0.0.1:5002/v2.0', :admin_url => 'http://127.0.0.1:5002',
} }
end end
@ -42,11 +42,11 @@ describe provider_class do
"1cb05cfed7c24279be884ba4f6520262","foo","bar","","http://127.0.0.1:5000/v2.0","http://127.0.0.1:5001/v2.0","http://127.0.0.1:5002/v2.0" "1cb05cfed7c24279be884ba4f6520262","foo","bar","","http://127.0.0.1:5000/v2.0","http://127.0.0.1:5001/v2.0","http://127.0.0.1:5002/v2.0"
') ')
provider.class.stubs(:openstack) provider.class.stubs(:openstack)
.with('endpoint', 'create', '--format', 'shell', ['bar', '--region', 'foo', '--publicurl', 'http://127.0.0.1:5000/v2.0', '--internalurl', 'http://127.0.0.1:5001/v2.0', '--adminurl', 'http://127.0.0.1:5002/v2.0']) .with('endpoint', 'create', '--format', 'shell', ['bar', '--region', 'foo', '--publicurl', 'http://127.0.0.1:5000', '--internalurl', 'http://127.0.0.1:5001', '--adminurl', 'http://127.0.0.1:5002'])
.returns('adminurl="http://127.0.0.1:5002/v2.0" .returns('adminurl="http://127.0.0.1:5002"
id="3a5c4378981e4112a0d44902a43e16ef" id="3a5c4378981e4112a0d44902a43e16ef"
internalurl="http://127.0.0.1:5001/v2.0" internalurl="http://127.0.0.1:5001"
publicurl="http://127.0.0.1:5000/v2.0" publicurl="http://127.0.0.1:5000"
region="foo" region="foo"
service_id="8137d72980fd462192f276585a002426" service_id="8137d72980fd462192f276585a002426"
service_name="bar" service_name="bar"
@ -62,7 +62,7 @@ service_type="test"
provider.class.stubs(:openstack) provider.class.stubs(:openstack)
.with('endpoint', 'list', '--quiet', '--format', 'csv', '--long') .with('endpoint', 'list', '--quiet', '--format', 'csv', '--long')
.returns('"ID","Region","Service Name","Service Type","PublicURL","AdminURL","InternalURL" .returns('"ID","Region","Service Name","Service Type","PublicURL","AdminURL","InternalURL"
"1cb05cfed7c24279be884ba4f6520262","foo","bar","test","http://127.0.0.1:5000/v2.0","http://127.0.0.1:5001/v2.0","http://127.0.0.1:5002/v2.0" "1cb05cfed7c24279be884ba4f6520262","foo","bar","test","http://127.0.0.1:5000","http://127.0.0.1:5001","http://127.0.0.1:5002"
') ')
provider.class.stubs(:openstack) provider.class.stubs(:openstack)
.with('endpoint', 'delete', []) .with('endpoint', 'delete', [])
@ -89,7 +89,7 @@ service_type="test"
provider.class.stubs(:openstack) provider.class.stubs(:openstack)
.with('endpoint', 'list', '--quiet', '--format', 'csv', '--long') .with('endpoint', 'list', '--quiet', '--format', 'csv', '--long')
.returns('"ID","Region","Service Name","Service Type","PublicURL","AdminURL","InternalURL" .returns('"ID","Region","Service Name","Service Type","PublicURL","AdminURL","InternalURL"
"3a5c4378981e4112a0d44902a43e16ef","foo","bar","test","http://127.0.0.1:5000/v2.0","http://127.0.0.1:5001/v2.0","http://127.0.0.1:5002/v2.0" "3a5c4378981e4112a0d44902a43e16ef","foo","bar","test","http://127.0.0.1:5000","http://127.0.0.1:5001","http://127.0.0.1:5002"
') ')
instances = Puppet::Type::Keystone_endpoint::ProviderOpenstack.instances instances = Puppet::Type::Keystone_endpoint::ProviderOpenstack.instances
expect(instances.count).to eq(1) expect(instances.count).to eq(1)