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
# Password validation
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.")
end
auth_url << "/v#{credentials.version}" unless auth_url =~ /\/v\d(\.\d)?$/
credentials.auth_url = auth_url
credentials.password = resource[:password]
credentials.user_id = id

View File

@ -5,23 +5,23 @@
# === Parameters
#
# [*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 '/'.
#
# [*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 '/'.
#
# [*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 '/'.
#
# [*region*]
# (optional) Region for endpoint. (Defaults to 'RegionOne')
#
# [*version*]
# (optional) API version for endpoint. Appended to all endpoint urls. (Defaults to 'v2.0')
#
# [*user_domain*]
# (Optional) Domain for $auth_name
# Defaults to undef (use the keystone server default domain)
@ -36,6 +36,15 @@
# If keystone_project_domain is not specified, use $keystone_default_domain
# 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
#
# class { 'keystone::endpoint':
@ -48,20 +57,36 @@ class keystone::endpoint (
$public_url = 'http://127.0.0.1:5000',
$internal_url = undef,
$admin_url = 'http://127.0.0.1:35357',
$version = 'v2.0',
$region = 'RegionOne',
$user_domain = undef,
$project_domain = undef,
$default_domain = undef,
$version = 'v2.0', # DEPRECATED
) {
$public_url_real = "${public_url}/${version}"
$admin_url_real = "${admin_url}/${version}"
if empty($version) {
$admin_url_real = $admin_url
$public_url_real = $public_url
if $internal_url {
$internal_url_real = "${internal_url}/${version}"
} else {
$internal_url_real = "${public_url}/${version}"
if $internal_url {
$internal_url_real = $internal_url
}
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':
@ -77,5 +102,4 @@ class keystone::endpoint (
project_domain => $project_domain,
default_domain => $default_domain,
}
}

View File

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

View File

@ -34,6 +34,21 @@ describe 'keystone::endpoint' do
)}
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
let :params do

View File

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