Upgrade the Keystone library to use v3

In order to enable and deploy federated Keystone, we need to use version
3 of the Keystone API and the v3 Keystone Client. This work begins that
transition by having a set of backwards compatible library commands.

Specifically, this commit updates the keystone library to use v3
Keystone Client and the usage of ensure_tenant in the os_keystone tasks
to use the v3 admin url.

In version 3 of Keystone's Endpoints (Catalog) API each endpoint only
has one URL and has separate interface types (public, internal, admin).
This change updates all uses of ensure_endpoint to structure the
endpoint data in a better way for the ensure_endpoint command in the
keystone module. As a result, some incidents where internalurl and
adminurl were swapped have been fixed.

Note:
In new deployments the endpoints will be created using the v3 API and
will therefore not be available via the v2 API. This will be a breaking
change to legacy CLI clients. The openstack CLI should be used instead.

DocImpact
Related-Bug: #1470635
Partially-implements: blueprint keystone-federation
Change-Id: I2cd4f505e850b4b113452abc25ee00d486b1637d
This commit is contained in:
Ian Cordasco
2015-06-29 23:23:08 -05:00
committed by Miguel Grinberg
parent 36640a8f43
commit c1fdbab4de
16 changed files with 302 additions and 174 deletions

View File

@@ -152,9 +152,10 @@ keystone_service_adminurl: "{{ keystone_service_adminuri }}/v2.0"
keystone_service_publicuri_v3: "{{ keystone_service_publicuri_proto }}://{{ external_lb_vip_address }}:{{ keystone_service_port }}" keystone_service_publicuri_v3: "{{ keystone_service_publicuri_proto }}://{{ external_lb_vip_address }}:{{ keystone_service_port }}"
keystone_service_publicurl_v3: "{{ keystone_service_publicuri_v3 }}/v3" keystone_service_publicurl_v3: "{{ keystone_service_publicuri_v3 }}/v3"
keystone_service_internaluri_v3: "{{ keystone_service_internaluri_proto }}://{{ internal_lb_vip_address }}:{{ keystone_service_port }}" keystone_service_internaluri_v3: "{{ keystone_service_internaluri_proto }}://{{ internal_lb_vip_address }}:{{ keystone_service_port }}"
keystone_service_internalurl_v3: "{{ keystone_service_adminuri_v3 }}/v3" keystone_service_internalurl_v3: "{{ keystone_service_internaluri_v3 }}/v3"
keystone_service_adminuri_v3: "{{ keystone_service_adminuri_proto }}://{{ internal_lb_vip_address }}:{{ keystone_admin_port }}" keystone_service_adminuri_v3: "{{ keystone_service_adminuri_proto }}://{{ internal_lb_vip_address }}:{{ keystone_admin_port }}"
keystone_service_adminurl_v3: "{{ keystone_service_adminuri_v3 }}/v3" keystone_service_adminurl_v3: "{{ keystone_service_adminuri_v3 }}/v3"
keystone_service_adminurl: "{{ keystone_service_adminurl_v3 }}"
keystone_cache_backend_argument: "url:{% for host in groups['memcached'] %}{{ hostvars[host]['container_address'] }}{% if not loop.last %},{% endif %}{% endfor %}:{{ memcached_port }}" keystone_cache_backend_argument: "url:{% for host in groups['memcached'] %}{{ hostvars[host]['container_address'] }}{% if not loop.last %},{% endif %}{% endfor %}:{{ memcached_port }}"
keystone_memcached_servers: "{% for host in groups['keystone_all'] %}{{ hostvars[host]['container_address'] }}:{{ memcached_port }}{% if not loop.last %},{% endif %}{% endfor %}" keystone_memcached_servers: "{% for host in groups['keystone_all'] %}{{ hostvars[host]['container_address'] }}:{{ memcached_port }}{% if not loop.last %},{% endif %}{% endfor %}"
keystone_service_region: "{{ service_region }}" keystone_service_region: "{{ service_region }}"
@@ -171,8 +172,9 @@ heat_service_region: "{{ service_region }}"
## OpenStack Openrc ## OpenStack Openrc
openrc_os_auth_url: "{{ keystone_service_internalurl }}" openrc_os_auth_url: "{{ keystone_service_internalurl_v3 }}"
openrc_os_password: "{{ keystone_auth_admin_password }}" openrc_os_password: "{{ keystone_auth_admin_password }}"
openrc_os_domain_name: "Default"
## Tempest Options ## Tempest Options

View File

@@ -87,7 +87,7 @@ EXAMPLES = """
import glanceclient.client as glclient import glanceclient.client as glclient
import keystoneclient.v2_0.client as ksclient import keystoneclient.v3.client as ksclient
COMMAND_MAP = {'image-list': 'list_images', COMMAND_MAP = {'image-list': 'list_images',
@@ -126,7 +126,7 @@ class ManageGlance(object):
self.keystone = ksclient.Client(insecure=insecure, self.keystone = ksclient.Client(insecure=insecure,
username=openrc['OS_USERNAME'], username=openrc['OS_USERNAME'],
password=openrc['OS_PASSWORD'], password=openrc['OS_PASSWORD'],
tenant_name=openrc['OS_TENANT_NAME'], project_name=openrc['OS_PROJECT_NAME'],
auth_url=openrc['OS_AUTH_URL']) auth_url=openrc['OS_AUTH_URL'])
def _init_glance(self): def _init_glance(self):

View File

@@ -22,9 +22,11 @@ DOCUMENTATION = """
module: keystone module: keystone
version_added: "1.6.2" version_added: "1.6.2"
short_description: short_description:
- Manage OpenStack Identity (keystone) users, tenants, roles, and endpoints. - Manage OpenStack Identity (keystone) users, projects, roles, and
endpoints.
description: description:
- Manage OpenStack Identity (keystone) users, tenants, roles, and endpoints. - Manage OpenStack Identity (keystone) users, projects, roles, and
endpoints.
options: options:
return_code: return_code:
description: description:
@@ -41,6 +43,11 @@ options:
- Password of login user - Password of login user
required: false required: false
default: 'yes' default: 'yes'
login_project_name:
description:
- The project login_user belongs to
required: false
default: None
login_tenant_name: login_tenant_name:
description: description:
- The tenant login_user belongs to - The tenant login_user belongs to
@@ -65,6 +72,11 @@ options:
- The name of the user that has to added/removed from OpenStack - The name of the user that has to added/removed from OpenStack
required: false required: false
default: None default: None
project_name:
description:
- The project name that has be added/removed
required: false
default: None
tenant_name: tenant_name:
description: description:
- The tenant name that has be added/removed - The tenant name that has be added/removed
@@ -84,9 +96,14 @@ options:
- Name of the region. - Name of the region.
required: false required: false
default: None default: None
domain_name:
description:
- Name of the domain to add a project to.
required: false
default: 'default'
description: description:
description: description:
- A description for the tenant - A description for the project
required: false required: false
default: None default: None
email: email:
@@ -99,27 +116,19 @@ options:
- Type of service. - Type of service.
required: false required: false
default: None default: None
publicurl: endpoint_list:
description: description:
- Public URL. - List of endpoints to add to keystone for a service
required: false
default: None
adminurl:
description:
- Admin URL.
required: false
default: None
internalurl:
description:
- Internal URL.
required: false required: false
default: None default: None
type: list
command: command:
description: description:
- Indicate desired state of the resource - Indicate desired state of the resource
choices: ['get_tenant', 'get_user', 'get_role', 'ensure_service', choices: ['get_tenant', 'get_project', 'get_user', 'get_role',
'ensure_endpoint', 'ensure_role', 'ensure_user', 'ensure_service', 'ensure_endpoint', 'ensure_role',
'ensure_user_role', 'ensure_tenant'] 'ensure_user', 'ensure_user_role', 'ensure_tenant',
'ensure_project']
required: true required: true
insecure: insecure:
description: description:
@@ -133,23 +142,24 @@ author: Kevin Carter
""" """
EXAMPLES = """ EXAMPLES = """
# Create an admin tenant # Create an admin project
- keystone: - keystone:
command: "ensure_tenant" command: "ensure_project"
tenant_name: "admin" project_name: "admin"
description: "Admin Tenant" domain_name: "Default"
description: "Admin project"
# Create a service tenant # Create a service project
- keystone: - keystone:
command: "ensure_tenant" command: "ensure_project"
tenant_name: "service" project_name: "service"
description: "Service Tenant" description: "Service project"
# Create an admin user # Create an admin user
- keystone: - keystone:
command: "ensure_user" command: "ensure_user"
user_name: "admin" user_name: "admin"
tenant_name: "admin" project_name: "admin"
password: "secrete" password: "secrete"
email: "admin@some-domain.com" email: "admin@some-domain.com"
@@ -162,15 +172,16 @@ EXAMPLES = """
- keystone: - keystone:
command: "ensure_user" command: "ensure_user"
user_name: "glance" user_name: "glance"
tenant_name: "service" project_name: "service"
password: "secrete" password: "secrete"
domain_name: "Default"
email: "glance@some-domain.com" email: "glance@some-domain.com"
# Add a role to a user # Add a role to a user
- keystone: - keystone:
command: "ensure_user_role" command: "ensure_user_role"
user_name: "glance" user_name: "glance"
tenant_name: "service" project_name: "service"
role_name: "admin" role_name: "admin"
# Create a service # Create a service
@@ -186,14 +197,18 @@ EXAMPLES = """
region_name: "RegionOne" region_name: "RegionOne"
service_name: "glance" service_name: "glance"
service_type: "image" service_type: "image"
publicurl: "http://127.0.0.1:9292" endpoint_list:
adminurl: "http://127.0.0.1:9292" - url: "http://127.0.0.1:9292"
internalurl: "http://127.0.0.1:9292" interface: "public"
- url: "http://127.0.0.1:9292"
interface: "admin"
- url: "http://127.0.0.1:9292"
interface: "internal"
# Get tenant id # Get project id
- keystone: - keystone:
command: "get_tenant" command: "get_project"
tenant_name: "admin" project_name: "admin"
# Get user id # Get user id
- keystone: - keystone:
@@ -210,6 +225,13 @@ EXAMPLES = """
COMMAND_MAP = { COMMAND_MAP = {
'get_tenant': { 'get_tenant': {
'variables': [ 'variables': [
'project_name',
'tenant_name'
]
},
'get_project': {
'variables': [
'project_name',
'tenant_name' 'tenant_name'
] ]
}, },
@@ -221,6 +243,7 @@ COMMAND_MAP = {
'get_role': { 'get_role': {
'variables': [ 'variables': [
'role_name', 'role_name',
'project_name',
'tenant_name', 'tenant_name',
'user_name' 'user_name'
] ]
@@ -237,9 +260,7 @@ COMMAND_MAP = {
'region_name', 'region_name',
'service_name', 'service_name',
'service_type', 'service_type',
'publicurl', 'endpoint_list'
'adminurl',
'internalurl'
] ]
}, },
'ensure_role': { 'ensure_role': {
@@ -249,21 +270,33 @@ COMMAND_MAP = {
}, },
'ensure_user': { 'ensure_user': {
'variables': [ 'variables': [
'project_name',
'tenant_name', 'tenant_name',
'user_name', 'user_name',
'password', 'password',
'email' 'email',
'domain_name'
] ]
}, },
'ensure_user_role': { 'ensure_user_role': {
'variables': [ 'variables': [
'user_name', 'user_name',
'project_name',
'tenant_name', 'tenant_name',
'role_name' 'role_name'
] ]
}, },
'ensure_project': {
'variables': [
'project_name',
'tenant_name',
'description',
'domain_name'
]
},
'ensure_tenant': { 'ensure_tenant': {
'variables': [ 'variables': [
'project_name',
'tenant_name', 'tenant_name',
'description' 'description'
] ]
@@ -271,7 +304,7 @@ COMMAND_MAP = {
} }
try: try:
from keystoneclient.v2_0 import client from keystoneclient.v3 import client
except ImportError: except ImportError:
keystoneclient_found = False keystoneclient_found = False
else: else:
@@ -363,6 +396,7 @@ class ManageKeystone(object):
'endpoint', 'endpoint',
'login_user', 'login_user',
'login_password', 'login_password',
'login_project_name',
'login_tenant_name', 'login_tenant_name',
'token', 'token',
'insecure' 'insecure'
@@ -372,18 +406,19 @@ class ManageKeystone(object):
endpoint = variables_dict.pop('endpoint') endpoint = variables_dict.pop('endpoint')
login_user = variables_dict.pop('login_user') login_user = variables_dict.pop('login_user')
login_password = variables_dict.pop('login_password') login_password = variables_dict.pop('login_password')
login_tenant_name = variables_dict.pop('login_tenant_name') login_project_name = (variables_dict.pop('login_project_name', None) or
variables_dict.pop('login_tenant_name'))
token = variables_dict.pop('token') token = variables_dict.pop('token')
insecure = variables_dict.pop('insecure') insecure = variables_dict.pop('insecure')
if token is None: if token is None:
if login_tenant_name is None: if login_project_name is None:
self.failure( self.failure(
error='Missing Tenant Name', error='Missing Project Name',
rc=2, rc=2,
msg='If you do not specify a token you must use a tenant' msg='If you do not specify a token you must use a project'
' name for authentication. Try adding' ' name for authentication. Try adding'
' [ login_tenant_name ] to the task' ' [ login_project_name ] to the task'
) )
if login_password is None: if login_password is None:
self.failure( self.failure(
@@ -406,22 +441,38 @@ class ManageKeystone(object):
auth_url=endpoint, auth_url=endpoint,
username=login_user, username=login_user,
password=login_password, password=login_password,
tenant_name=login_tenant_name project_name=login_project_name
) )
def _get_tenant(self, name): def _get_domain(self, name):
"""Return tenant information. """Return domain information.
:param name: ``str`` Name of the tenant. :param str name: Name of the domain.
""" """
for entry in self.keystone.tenants.list(): for entry in self.keystone.domains.list():
if entry.name == name:
return entry
else:
return None
def _get_project(self, name):
"""Return project information.
Formerly, _get_tenant
:param name: ``str`` Name of the project.
"""
for entry in self.keystone.projects.list():
if entry.name == name: if entry.name == name:
return entry return entry
else: else:
return None return None
def get_tenant(self, variables): def get_tenant(self, variables):
"""Return a tenant id. return self.get_project(variables)
def get_project(self, variables):
"""Return a project id.
This will return `None` if the ``name`` is not found. This will return `None` if the ``name`` is not found.
@@ -429,43 +480,51 @@ class ManageKeystone(object):
use within the Keystone Command. use within the Keystone Command.
""" """
self._authenticate() self._authenticate()
variables_dict = self._get_vars(variables, required=['tenant_name']) variables_dict = self._get_vars(variables)
tenant_name = variables_dict.pop('tenant_name') project_name = (variables_dict.pop('project_name', None) or
tenant = self._get_tenant(name=tenant_name) variables_dict.pop('tenant_name'))
if tenant is None: project = self._get_project(name=project_name)
if project is None:
self.failure( self.failure(
error='tenant [ %s ] was not found.' % tenant_name, error='project [ %s ] was not found.' % project_name,
rc=2, rc=2,
msg='tenant was not found, does it exist?' msg='project was not found, does it exist?'
) )
return self._facts(facts={'id': tenant.id}) return self._facts(facts={'id': project.id})
def ensure_tenant(self, variables): def ensure_tenant(self, variables):
"""Create a new tenant within Keystone if it does not exist. return self.ensure_project(variables)
Returns the tenant ID on a successful run. def ensure_project(self, variables):
"""Create a new project within Keystone if it does not exist.
Returns the project ID on a successful run.
:param variables: ``list`` List of all variables that are available to :param variables: ``list`` List of all variables that are available to
use within the Keystone Command. use within the Keystone Command.
""" """
self._authenticate() self._authenticate()
variables_dict = self._get_vars(variables, required=['tenant_name']) variables_dict = self._get_vars(variables)
tenant_name = variables_dict.pop('tenant_name') project_name = (variables_dict.pop('project_name', None) or
tenant_description = variables_dict.pop('description') variables_dict.pop('tenant_name'))
if tenant_description is None: domain_name = variables_dict.pop('domain_name', None) or 'Default'
tenant_description = 'Tenant %s' % tenant_name project_description = variables_dict.pop('description')
if project_description is None:
project_description = 'Project %s' % project_name
tenant = self._get_tenant(name=tenant_name) domain = self._get_domain(name=domain_name)
if tenant is None: project = self._get_project(name=project_name)
if project is None:
self.state_change = True self.state_change = True
tenant = self.keystone.tenants.create( project = self.keystone.projects.create(
tenant_name=tenant_name, name=project_name,
description=tenant_description, description=project_description,
domain=domain,
enabled=True enabled=True
) )
return self._facts(facts={'id': tenant.id}) return self._facts(facts={'id': project.id})
def _get_user(self, name): def _get_user(self, name):
"""Return a user information. """Return a user information.
@@ -481,7 +540,7 @@ class ManageKeystone(object):
return None return None
def get_user(self, variables): def get_user(self, variables):
"""Return a tenant id. """Return a project id.
This will return `None` if the ``name`` is not found. This will return `None` if the ``name`` is not found.
@@ -510,19 +569,28 @@ class ManageKeystone(object):
use within the Keystone Command. use within the Keystone Command.
""" """
self._authenticate() self._authenticate()
required_vars = ['tenant_name', 'user_name', 'password'] required_vars = ['user_name', 'password']
variables_dict = self._get_vars(variables, required=required_vars) variables_dict = self._get_vars(variables, required=required_vars)
tenant_name = variables_dict.pop('tenant_name') project_name = (variables_dict.pop('project_name', None) or
variables_dict.pop('tenant_name'))
password = variables_dict.pop('password') password = variables_dict.pop('password')
user_name = variables_dict.pop('user_name') user_name = variables_dict.pop('user_name')
email = variables_dict.pop('email') email = variables_dict.pop('email')
# NOTE(sigmavirus24): Since we don't require domain, this will be None
# in the dictionary. When we pop it, we can't provide a default
# because 'domain' exists and is None. In order to use a default
# value, we need to use `or 'default'` here to make sure we default to
# the default domain. If we don't do it this way, Keystone throws a
# 401 Unauthorized which is just plain wrong.
domain_name = variables_dict.pop('domain_name', None) or 'Default'
tenant = self._get_tenant(name=tenant_name) domain = self._get_domain(name=domain_name)
if tenant is None: project = self._get_project(name=project_name)
if project is None:
self.failure( self.failure(
error='tenant [ %s ] was not found.' % tenant_name, error='project [ %s ] was not found.' % project_name,
rc=2, rc=2,
msg='tenant was not found, does it exist?' msg='project was not found, does it exist?'
) )
user = self._get_user(name=user_name) user = self._get_user(name=user_name)
@@ -532,7 +600,8 @@ class ManageKeystone(object):
name=user_name, name=user_name,
password=password, password=password,
email=email, email=email,
tenant_id=tenant.id domain=domain,
default_project=project
) )
return self._facts(facts={'id': user.id}) return self._facts(facts={'id': user.id})
@@ -571,7 +640,7 @@ class ManageKeystone(object):
return self._facts(facts={'id': role_data.id}) return self._facts(facts={'id': role_data.id})
def _get_role_data(self, user_name, tenant_name, role_name): def _get_role_data(self, user_name, project_name, role_name):
user = self._get_user(name=user_name) user = self._get_user(name=user_name)
if user is None: if user is None:
self.failure( self.failure(
@@ -580,12 +649,12 @@ class ManageKeystone(object):
msg='User was not found, does it exist?' msg='User was not found, does it exist?'
) )
tenant = self._get_tenant(name=tenant_name) project = self._get_project(name=project_name)
if tenant is None: if project is None:
self.failure( self.failure(
error='tenant [ %s ] was not found.' % tenant_name, error='project [ %s ] was not found.' % project_name,
rc=2, rc=2,
msg='tenant was not found, does it exist?' msg='project was not found, does it exist?'
) )
role = self._get_role(name=role_name) role = self._get_role(name=role_name)
@@ -596,7 +665,7 @@ class ManageKeystone(object):
msg='role was not found, does it exist?' msg='role was not found, does it exist?'
) )
return user, tenant, role return user, project, role
def ensure_role(self, variables): def ensure_role(self, variables):
"""Create a new role within Keystone if it does not exist. """Create a new role within Keystone if it does not exist.
@@ -617,8 +686,8 @@ class ManageKeystone(object):
return self._facts(facts={'id': role.id}) return self._facts(facts={'id': role.id})
def _get_user_roles(self, name, user, tenant): def _get_user_roles(self, name, user, project):
for entry in self.keystone.users.list_roles(user, tenant.id): for entry in self.keystone.roles.list(user=user, project=project):
if entry.name == name: if entry.name == name:
return entry return entry
else: else:
@@ -626,26 +695,30 @@ class ManageKeystone(object):
def ensure_user_role(self, variables): def ensure_user_role(self, variables):
self._authenticate() self._authenticate()
required_vars = ['user_name', 'tenant_name', 'role_name'] required_vars = ['user_name', 'role_name']
variables_dict = self._get_vars(variables, required=required_vars) variables_dict = self._get_vars(variables, required=required_vars)
user_name = variables_dict.pop('user_name') user_name = variables_dict.pop('user_name')
tenant_name = variables_dict.pop('tenant_name') # NOTE(sigmavirus24): Try to get the project_name, but
# don't error out on it. This will change when the playbooks are
# updated to use project_name instead of tenant_name
project_name = (variables_dict.pop('project_name', None)
or variables_dict.pop('tenant_name'))
role_name = variables_dict.pop('role_name') role_name = variables_dict.pop('role_name')
user, tenant, role = self._get_role_data( user, project, role = self._get_role_data(
user_name=user_name, tenant_name=tenant_name, role_name=role_name user_name=user_name, project_name=project_name, role_name=role_name
) )
user_role = self._get_user_roles( user_role = self._get_user_roles(
name=role_name, user=user, tenant=tenant name=role_name, user=user, project=project
) )
if user_role is None: if user_role is None:
self.keystone.roles.add_user_role( self.keystone.roles.grant(
user=user, role=role, tenant=tenant user=user, role=role, project=project
) )
user_role = self._get_user_roles( user_role = self._get_user_roles(
name=role_name, user=user, tenant=tenant name=role_name, user=user, project=project
) )
return self._facts(facts={'id': user_role.id}) return self._facts(facts={'id': user_role.id})
@@ -681,19 +754,18 @@ class ManageKeystone(object):
self.state_change = True self.state_change = True
service = self.keystone.services.create( service = self.keystone.services.create(
name=service_name, name=service_name,
service_type=service_type, type=service_type,
description=description description=description
) )
return self._facts(facts={'id': service.id}) return self._facts(facts={'id': service.id})
def _get_endpoint(self, region, publicurl, adminurl, internalurl): def _get_endpoint(self, region, url, interface):
for entry in self.keystone.endpoints.list(): for entry in self.keystone.endpoints.list():
check = [ check = [
entry.region == region, entry.region == region,
entry.publicurl == publicurl, entry.url == url,
entry.adminurl == adminurl, entry.interface == interface
entry.internalurl == internalurl
] ]
if all(check): if all(check):
return entry return entry
@@ -713,18 +785,14 @@ class ManageKeystone(object):
'region_name', 'region_name',
'service_name', 'service_name',
'service_type', 'service_type',
'publicurl', 'endpoint_list'
'adminurl',
'internalurl'
] ]
variables_dict = self._get_vars(variables, required=required_vars) variables_dict = self._get_vars(variables, required=required_vars)
service_name = variables_dict.pop('service_name') service_name = variables_dict.pop('service_name')
service_type = variables_dict.pop('service_type') service_type = variables_dict.pop('service_type')
region = variables_dict.pop('region_name') region = variables_dict.pop('region_name')
publicurl = variables_dict.pop('publicurl') endpoint_list = variables_dict.pop('endpoint_list')
adminurl = variables_dict.pop('adminurl')
internalurl = variables_dict.pop('internalurl')
service = self._get_service(name=service_name, srv_type=service_type) service = self._get_service(name=service_name, srv_type=service_type)
if service is None: if service is None:
@@ -734,23 +802,28 @@ class ManageKeystone(object):
msg='Service was not found, does it exist?' msg='Service was not found, does it exist?'
) )
endpoints = {}
for endpoint_dict in endpoint_list:
url = endpoint_dict.pop('url')
interface = endpoint_dict.pop('interface')
endpoint = self._get_endpoint( endpoint = self._get_endpoint(
region=region, region=region,
publicurl=publicurl, url=url,
adminurl=adminurl, interface=interface
internalurl=internalurl
) )
if endpoint is None: if endpoint is None:
self.state_change = True self.state_change = True
endpoint = self.keystone.endpoints.create( endpoint = self.keystone.endpoints.create(
region=region, region=region,
service_id=service.id, service=service,
publicurl=publicurl, url=url,
adminurl=adminurl, interface=interface
internalurl=internalurl
) )
endpoints[interface] = endpoint
return self._facts(facts={'id': endpoint.id}) return self._facts(
facts={'%sid' % interface: endpoint.id
for interface, endpoint in endpoints.items()})
def main(): def main():
@@ -780,6 +853,12 @@ def main():
tenant_name=dict( tenant_name=dict(
required=False required=False
), ),
project_name=dict(
required=False
),
domain_name=dict(
required=False
),
role_name=dict( role_name=dict(
required=False required=False
), ),
@@ -798,14 +877,9 @@ def main():
service_type=dict( service_type=dict(
required=False required=False
), ),
publicurl=dict( endpoint_list=dict(
required=False required=False,
), type='list'
adminurl=dict(
required=False
),
internalurl=dict(
required=False
), ),
command=dict( command=dict(
required=True, required=True,
@@ -843,6 +917,6 @@ def main():
# import module snippets # import module snippets
from ansible.module_utils.basic import * from ansible.module_utils.basic import * # NOQA
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@@ -114,7 +114,7 @@ EXAMPLES = """
""" """
import keystoneclient.v2_0.client as ksclient import keystoneclient.v3.client as ksclient
from neutronclient.neutron import client as nclient from neutronclient.neutron import client as nclient
@@ -258,7 +258,7 @@ class ManageNeutron(object):
self.keystone = ksclient.Client(insecure=insecure, self.keystone = ksclient.Client(insecure=insecure,
username=openrc['OS_USERNAME'], username=openrc['OS_USERNAME'],
password=openrc['OS_PASSWORD'], password=openrc['OS_PASSWORD'],
tenant_name=openrc['OS_TENANT_NAME'], project_name=openrc['OS_PROJECT_NAME'],
auth_url=openrc['OS_AUTH_URL']) auth_url=openrc['OS_AUTH_URL'])
def _init_neutron(self): def _init_neutron(self):

View File

@@ -10,9 +10,21 @@ export NOVA_ENDPOINT_TYPE={{ openrc_nova_endpoint_type }}
export OS_ENDPOINT_TYPE={{ openrc_os_endpoint_type }} export OS_ENDPOINT_TYPE={{ openrc_os_endpoint_type }}
export OS_USERNAME={{ openrc_os_username }} export OS_USERNAME={{ openrc_os_username }}
export OS_PASSWORD={{ openrc_os_password }} export OS_PASSWORD={{ openrc_os_password }}
export OS_PROJECT_NAME={{ openrc_os_tenant_name }}
# NOTE(sigmavirus24): The tenant name setting should be removed when
# python-cinderclient stops checking for it and failing if it doesn't exist.
export OS_TENANT_NAME={{ openrc_os_tenant_name }} export OS_TENANT_NAME={{ openrc_os_tenant_name }}
export OS_AUTH_URL={{ openrc_os_auth_url }} export OS_AUTH_URL={{ openrc_os_auth_url }}
export OS_NO_CACHE=1 export OS_NO_CACHE=1
export OS_USER_DOMAIN_NAME={{ openrc_os_domain_name }}
export OS_PROJECT_DOMAIN_NAME={{ openrc_os_domain_name }}
# For openstackclient
{% if openrc_os_auth_url.endswith('v3') %}
export OS_IDENTITY_API_VERSION=3
{% else %}
export OS_IDENTITY_API_VERSION=2
{% endif %}
{% if openrc_insecure | bool %} {% if openrc_insecure | bool %}
# Convenience Aliases for Self-Signed Certs # Convenience Aliases for Self-Signed Certs

View File

@@ -73,9 +73,13 @@
region_name: "{{ service_region }}" region_name: "{{ service_region }}"
service_name: "{{ service_name }}" service_name: "{{ service_name }}"
service_type: "{{ service_type }}" service_type: "{{ service_type }}"
publicurl: "{{ service_publicurl }}" endpoint_list:
adminurl: "{{ service_internalurl }}" - url: "{{ service_publicurl }}"
internalurl: "{{ service_adminurl }}" interface: "public"
- url: "{{ service_adminurl }}"
interface: "admin"
- url: "{{ service_internalurl }}"
interface: "internal"
register: add_service register: add_service
until: add_service|success until: add_service|success
retries: 5 retries: 5

View File

@@ -79,10 +79,14 @@
region_name: "{{ service_region }}" region_name: "{{ service_region }}"
service_name: "{{ service_name }}" service_name: "{{ service_name }}"
service_type: "{{ service_type }}" service_type: "{{ service_type }}"
publicurl: "{{ service_publicurl }}"
adminurl: "{{ service_internalurl }}"
internalurl: "{{ service_adminurl }}"
insecure: "{{ keystone_service_adminuri_insecure }}" insecure: "{{ keystone_service_adminuri_insecure }}"
endpoint_list:
- url: "{{ service_publicurl }}"
interface: "public"
- url: "{{ service_internalurl }}"
interface: "internal"
- url: "{{ service_adminurl }}"
interface: "admin"
register: add_service register: add_service
until: add_service|success until: add_service|success
retries: 5 retries: 5

View File

@@ -79,10 +79,14 @@
region_name: "{{ glance_service_region }}" region_name: "{{ glance_service_region }}"
service_name: "{{ glance_service_name }}" service_name: "{{ glance_service_name }}"
service_type: "{{ glance_service_type }}" service_type: "{{ glance_service_type }}"
publicurl: "{{ glance_service_publicurl }}"
adminurl: "{{ glance_service_internalurl }}"
internalurl: "{{ glance_service_adminurl }}"
insecure: "{{ keystone_service_adminuri_insecure }}" insecure: "{{ keystone_service_adminuri_insecure }}"
endpoint_list:
- url: "{{ glance_service_publicurl }}"
interface: "public"
- url: "{{ glance_service_internalurl }}"
interface: "internal"
- url: "{{ glance_service_adminurl }}"
interface: "admin"
register: add_service register: add_service
until: add_service|success until: add_service|success
retries: 5 retries: 5

View File

@@ -79,10 +79,14 @@
region_name: "{{ service_region }}" region_name: "{{ service_region }}"
service_name: "{{ service_name }}" service_name: "{{ service_name }}"
service_type: "{{ service_type }}" service_type: "{{ service_type }}"
publicurl: "{{ service_publicurl }}"
internalurl: "{{ service_internalurl }}"
adminurl: "{{ service_adminurl }}"
insecure: "{{ keystone_service_adminuri_insecure }}" insecure: "{{ keystone_service_adminuri_insecure }}"
endpoint_list:
- url: "{{ service_publicurl }}"
interface: "public"
- url: "{{ service_internalurl }}"
interface: "internal"
- url: "{{ service_adminurl }}"
interface: "admin"
register: add_service register: add_service
until: add_service|success until: add_service|success
retries: 5 retries: 5

View File

@@ -102,18 +102,20 @@ keystone_service_user_name: keystone
keystone_service_tenant_name: service keystone_service_tenant_name: service
keystone_service_publicuri: "{{ keystone_service_publicuri_proto }}://{{ external_lb_vip_address }}:{{ keystone_service_port }}" keystone_service_publicuri: "{{ keystone_service_publicuri_proto }}://{{ external_lb_vip_address }}:{{ keystone_service_port }}"
keystone_service_publicurl: "{{ keystone_service_publicuri }}/v2.0"
keystone_service_internaluri: "{{ keystone_service_internaluri_proto }}://{{ internal_lb_vip_address }}:{{ keystone_service_port }}" keystone_service_internaluri: "{{ keystone_service_internaluri_proto }}://{{ internal_lb_vip_address }}:{{ keystone_service_port }}"
keystone_service_internalurl: "{{ keystone_service_internaluri }}/v2.0"
keystone_service_adminuri: "{{ keystone_service_adminuri_proto }}://{{ internal_lb_vip_address }}:{{ keystone_admin_port }}" keystone_service_adminuri: "{{ keystone_service_adminuri_proto }}://{{ internal_lb_vip_address }}:{{ keystone_admin_port }}"
keystone_service_adminurl: "{{ keystone_service_adminuri }}/v2.0"
keystone_service_publicuri_v3: "{{ keystone_service_publicuri_proto }}://{{ external_lb_vip_address }}:{{ keystone_service_port }}" keystone_service_publicurl_v2: "{{ keystone_service_publicuri }}/v2.0"
keystone_service_publicurl_v3: "{{ keystone_service_publicuri_v3 }}/v3" keystone_service_internalurl_v2: "{{ keystone_service_internaluri }}/v2.0"
keystone_service_internaluri_v3: "{{ keystone_service_internaluri_proto }}://{{ internal_lb_vip_address }}:{{ keystone_service_port }}" keystone_service_adminurl_v2: "{{ keystone_service_adminuri }}/v2.0"
keystone_service_internalurl_v3: "{{ keystone_service_internaluri_v3 }}/v3"
keystone_service_adminuri_v3: "{{ keystone_service_adminuri_proto }}://{{ internal_lb_vip_address }}:{{ keystone_admin_port }}" keystone_service_publicurl_v3: "{{ keystone_service_publicuri }}/v3"
keystone_service_adminurl_v3: "{{ keystone_service_adminuri_v3 }}/v3" keystone_service_internalurl_v3: "{{ keystone_service_internaluri }}/v3"
keystone_service_adminurl_v3: "{{ keystone_service_adminuri }}/v3"
keystone_service_publicurl: "{{ keystone_service_publicurl_v3 }}"
keystone_service_internalurl: "{{ keystone_service_internalurl_v3 }}"
keystone_service_adminurl: "{{ keystone_service_adminurl_v3 }}"
## Set this value to override the "public_endpoint" keystone.conf variable ## Set this value to override the "public_endpoint" keystone.conf variable
#keystone_public_endpoint: #keystone_public_endpoint:

View File

@@ -194,10 +194,14 @@
region_name: "{{ keystone_service_region }}" region_name: "{{ keystone_service_region }}"
service_name: "{{ keystone_service_name }}" service_name: "{{ keystone_service_name }}"
service_type: "{{ keystone_service_type }}" service_type: "{{ keystone_service_type }}"
publicurl: "{{ keystone_service_publicurl }}"
adminurl: "{{ keystone_service_adminurl }}"
internalurl: "{{ keystone_service_internalurl }}"
insecure: "{{ keystone_service_adminuri_insecure }}" insecure: "{{ keystone_service_adminuri_insecure }}"
endpoint_list:
- url: "{{ keystone_service_publicurl }}"
interface: "public"
- url: "{{ keystone_service_adminurl_v3 }}"
interface: "admin"
- url: "{{ keystone_service_internalurl }}"
interface: "internal"
register: add_service register: add_service
until: add_service|success until: add_service|success
retries: 5 retries: 5

View File

@@ -79,10 +79,14 @@
region_name: "{{ service_region }}" region_name: "{{ service_region }}"
service_name: "{{ service_name }}" service_name: "{{ service_name }}"
service_type: "{{ service_type }}" service_type: "{{ service_type }}"
publicurl: "{{ service_publicurl }}"
adminurl: "{{ service_internalurl }}"
internalurl: "{{ service_adminurl }}"
insecure: "{{ keystone_service_adminuri_insecure }}" insecure: "{{ keystone_service_adminuri_insecure }}"
endpoint_list:
- url: "{{ service_publicurl }}"
interface: "public"
- url: "{{ service_internalurl }}"
interface: "internal"
- url: "{{ service_adminurl }}"
interface: "admin"
register: add_service register: add_service
until: add_service|success until: add_service|success
retries: 5 retries: 5

View File

@@ -79,10 +79,14 @@
region_name: "{{ service_region }}" region_name: "{{ service_region }}"
service_name: "{{ service_name }}" service_name: "{{ service_name }}"
service_type: "{{ service_type }}" service_type: "{{ service_type }}"
publicurl: "{{ service_publicurl }}"
adminurl: "{{ service_internalurl }}"
internalurl: "{{ service_adminurl }}"
insecure: "{{ keystone_service_adminuri_insecure }}" insecure: "{{ keystone_service_adminuri_insecure }}"
endpoint_list:
- url: "{{ service_publicurl }}"
interface: "public"
- url: "{{ service_internalurl }}"
interface: "internal"
- url: "{{ service_adminurl }}"
interface: "admin"
register: add_service register: add_service
until: add_service|success until: add_service|success
retries: 5 retries: 5

View File

@@ -139,11 +139,17 @@ port = {{ glance_service_port }}
[neutron] [neutron]
url = {{ neutron_service_adminurl }} url = {{ neutron_service_adminurl }}
region_name = {{ neutron_service_region }} region_name = {{ neutron_service_region }}
auth_plugin = password
auth_strategy = keystone auth_strategy = keystone
admin_auth_url = {{ keystone_service_adminurl }} # Keystone client plugin password option
admin_password = {{ neutron_service_password }} password = {{ neutron_service_password }}
admin_username = {{ neutron_service_user_name }} # Keystone client plugin username option
admin_tenant_name = {{ neutron_service_project_name }} username = {{ neutron_service_user_name }}
project_name = {{ neutron_service_project_name }}
user_domain_name = {{ neutron_service_domain_name |default("Default") }}
project_domain_name = {{ neutron_service_domain_name |default("Default") }}
# Keystone client plugin authentication URL option
auth_url = {{ keystone_service_adminurl }}
metadata_proxy_shared_secret = {{ nova_metadata_proxy_secret }} metadata_proxy_shared_secret = {{ nova_metadata_proxy_secret }}
service_metadata_proxy = {{ nova_metadata_proxy_enabled }} service_metadata_proxy = {{ nova_metadata_proxy_enabled }}

View File

@@ -163,10 +163,14 @@
region_name: "{{ swift_service_region }}" region_name: "{{ swift_service_region }}"
service_name: "{{ swift_service_name }}" service_name: "{{ swift_service_name }}"
service_type: "{{ swift_service_type }}" service_type: "{{ swift_service_type }}"
publicurl: "{{ swift_service_publicurl }}"
adminurl: "{{ swift_service_internalurl }}"
internalurl: "{{ swift_service_adminurl }}"
insecure: "{{ keystone_service_adminuri_insecure }}" insecure: "{{ keystone_service_adminuri_insecure }}"
endpoint_list:
- url: "{{ swift_service_publicurl }}"
interface: "public"
- url: "{{ swift_service_internalurl }}"
interface: "internal"
- url: "{{ swift_service_adminurl }}"
interface: "admin"
register: add_service register: add_service
until: add_service|success until: add_service|success
retries: 5 retries: 5

View File

@@ -110,7 +110,7 @@ admin_tenant_id = {{ tempest_admin_tenant_id }}
alt_tenant_name = alt_demo alt_tenant_name = alt_demo
alt_password = alt_demo alt_password = alt_demo
alt_username = alt_demo alt_username = alt_demo
auth_version = v2 auth_version = v3
catalog_type = identity catalog_type = identity
disable_ssl_certificate_validation = {{ keystone_service_internaluri_insecure | bool }} disable_ssl_certificate_validation = {{ keystone_service_internaluri_insecure | bool }}
endpoint_type = internalURL endpoint_type = internalURL
@@ -123,7 +123,7 @@ username = demo
[identity-feature-enabled] [identity-feature-enabled]
api_v2 = true api_v2 = true
api_v3 = false api_v3 = true
trust = false trust = false