summaryrefslogtreecommitdiff
path: root/openstack/usr/share/openstack/modules/keystone_service
diff options
context:
space:
mode:
Diffstat (limited to 'openstack/usr/share/openstack/modules/keystone_service')
-rw-r--r--openstack/usr/share/openstack/modules/keystone_service309
1 files changed, 309 insertions, 0 deletions
diff --git a/openstack/usr/share/openstack/modules/keystone_service b/openstack/usr/share/openstack/modules/keystone_service
new file mode 100644
index 00000000..aa4302d1
--- /dev/null
+++ b/openstack/usr/share/openstack/modules/keystone_service
@@ -0,0 +1,309 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+DOCUMENTATION = '''
+---
+module: keystone_service
+short_description: Manage OpenStack Identity (keystone) service endpoints
+options:
+ name:
+ description:
+ - name of service (e.g., keystone)
+ required: yes
+ type:
+ description:
+ - type of service (e.g., identity)
+ required: yes
+ description:
+ description:
+ - description of service (e.g., Identity Service)
+ required: yes
+ public_url:
+ description:
+ - public url of service.
+ - 'Alias: I(url)'
+ - 'Alias: I(publicurl)'
+ required: yes
+ internal_url:
+ description:
+ - internal url of service.
+ - 'Alias: I(internalurl)'
+ required: no
+ default: value of public_url
+ admin_url:
+ description:
+ - admin url of service.
+ - 'Alias: I(adminurl)'
+ required: no
+ default: value of public_url
+ insecure:
+ description:
+ - allow use of self-signed SSL certificates
+ required: no
+ choices: [ "yes", "no" ]
+ region:
+ description:
+ - region of service
+ required: yes
+ state:
+ description:
+ - Indicate desired state of the resource
+ choices: ['present', 'absent']
+ default: present
+
+
+
+requirements: [ python-keystoneclient ]
+author: Lorin Hochstein
+'''
+
+EXAMPLES = '''
+examples:
+keystone_service: >
+ name=keystone
+ type=identity
+ description="Keystone Identity Service"
+ publicurl=http://192.168.206.130:5000/v2.0
+ internalurl=http://192.168.206.130:5000/v2.0
+ adminurl=http://192.168.206.130:35357/v2.0
+
+keystone_service: >
+ name=glance
+ type=image
+ description="Glance Identity Service"
+ url=http://192.168.206.130:9292
+
+'''
+
+try:
+ from keystoneclient.v2_0 import client
+except ImportError:
+ keystoneclient_found = False
+else:
+ keystoneclient_found = True
+
+import traceback
+
+
+def authenticate(endpoint, token, login_user, login_password, tenant_name,
+ insecure):
+ """Return a keystone client object"""
+
+ if token:
+ return client.Client(endpoint=endpoint, token=token, insecure=insecure)
+ else:
+ return client.Client(auth_url=endpoint, username=login_user,
+ password=login_password, tenant_name=tenant_name,
+ insecure=insecure)
+
+def get_service(keystone, name):
+ """ Retrieve a service by name """
+ services = [x for x in keystone.services.list() if x.name == name]
+ count = len(services)
+ if count == 0:
+ raise KeyError("No keystone services with name %s" % name)
+ elif count > 1:
+ raise ValueError("%d services with name %s" % (count, name))
+ else:
+ return services[0]
+
+
+def get_endpoint(keystone, name):
+ """ Retrieve a service endpoint by name """
+ service = get_service(keystone, name)
+ endpoints = [x for x in keystone.endpoints.list()
+ if x.service_id == service.id]
+ count = len(endpoints)
+ if count == 0:
+ raise KeyError("No keystone endpoints with service name %s" % name)
+ elif count > 1:
+ raise ValueError("%d endpoints with service name %s" % (count, name))
+ else:
+ return endpoints[0]
+
+
+def ensure_service_present(keystone, name, service_type, description,
+ check_mode):
+ """ Ensure the service is present and has the right values
+
+ Returns a pair, where the first element is a boolean that indicates
+ a state change, and the second element is the service uuid, or None
+ if running in check mode"""
+ service = None
+ try:
+ service = get_service(keystone, name)
+ except:
+ # Service doesn't exist yet, we'll need to create one
+ pass
+ else:
+ # See if it matches exactly
+ if service.name == name and \
+ service.type == service_type and \
+ service.description == description:
+
+ # Same, no changes needed
+ return (False, service.id)
+
+ # At this point, we know we will need to make a change
+ if check_mode:
+ return (True, None)
+
+ if service is None:
+ service = keystone.services.create(name=name,
+ service_type=service_type,
+ description=description)
+ return (True, service.id)
+ else:
+ msg = "keystone v2 API doesn't support updating services"
+ raise ValueError(msg)
+
+
+def ensure_endpoint_present(keystone, name, public_url, internal_url,
+ admin_url, region, check_mode):
+ """ Ensure the service endpoint is present and have the right values
+
+ Assumes the service object has already been created at this point"""
+
+ service = get_service(keystone, name)
+ endpoint = None
+ try:
+ endpoint = get_endpoint(keystone, name)
+ except:
+ # Endpoint doesn't exist yet, we'll need to create one
+ pass
+ else:
+ # See if it matches
+ if endpoint.publicurl == public_url and \
+ endpoint.adminurl == admin_url and \
+ endpoint.internalurl == internal_url and \
+ endpoint.region == region:
+
+ # Same, no changes needed
+ return (False, endpoint.id)
+
+ # At this point, we know we will need to make a change
+ if check_mode:
+ return (True, None)
+
+ if endpoint is None:
+ endpoint = keystone.endpoints.create(region=region,
+ service_id=service.id,
+ publicurl=public_url,
+ adminurl=admin_url,
+ internalurl=internal_url)
+ return (True, endpoint.id)
+ else:
+ msg = "keystone v2 API doesn't support updating endpoints"
+ raise ValueError(msg)
+
+
+def ensure_service_absent(keystone, name, check_mode):
+ """ Ensure the service is absent"""
+
+ raise NotImplementedError()
+
+def ensure_endpoint_absent(keystone, name, check_mode):
+ """ Ensure the service endpoint """
+ raise NotImplementedError()
+
+
+def dispatch(keystone, name, service_type, description, public_url,
+ internal_url, admin_url, region, state, check_mode):
+
+ if state == 'present':
+ (service_changed, service_id) = ensure_service_present(keystone,
+ name,
+ service_type,
+ description,
+ check_mode)
+
+ (endpoint_changed, endpoint_id) = ensure_endpoint_present(
+ keystone,
+ name,
+ public_url,
+ internal_url,
+ admin_url,
+ region,
+ check_mode)
+ return dict(changed=service_changed or endpoint_changed,
+ service_id=service_id,
+ endpoint_id=endpoint_id)
+ elif state == 'absent':
+ endpoint_changed = ensure_endpoint_absent(keystone, name, check_mode)
+ service_changed = ensure_service_absent(keystone, name, check_mode)
+ return dict(changed=service_changed or endpoint_changed)
+ else:
+ raise ValueError("Code should never reach here")
+
+
+
+def main():
+
+ module = AnsibleModule(
+ argument_spec=dict(
+ name=dict(required=True),
+ type=dict(required=True),
+ description=dict(required=False),
+ public_url=dict(required=True, aliases=['url', 'publicurl']),
+ internal_url=dict(required=False, aliases=['internalurl']),
+ admin_url=dict(required=False, aliases=['adminurl']),
+ region=dict(required=True),
+ state=dict(default='present', choices=['present', 'absent']),
+ endpoint=dict(required=False,
+ default="http://127.0.0.1:35357/v2.0",
+ aliases=['auth_url']),
+ token=dict(required=False),
+ insecure=dict(required=False, default=False, choices=BOOLEANS),
+
+ login_user=dict(required=False),
+ login_password=dict(required=False),
+ tenant_name=dict(required=False, aliases=['tenant'])
+ ),
+ supports_check_mode=True,
+ mutually_exclusive=[['token', 'login_user'],
+ ['token', 'login_password'],
+ ['token', 'tenant_name']]
+ )
+
+ endpoint = module.params['endpoint']
+ token = module.params['token']
+ login_user = module.params['login_user']
+ login_password = module.params['login_password']
+ tenant_name = module.params['tenant_name']
+ insecure = module.boolean(module.params['insecure'])
+ name = module.params['name']
+ service_type = module.params['type']
+ description = module.params['description']
+ public_url = module.params['public_url']
+ internal_url = module.params['internal_url']
+ if internal_url is None:
+ internal_url = public_url
+ admin_url = module.params['admin_url']
+ if admin_url is None:
+ admin_url = public_url
+ region = module.params['region']
+ state = module.params['state']
+
+ keystone = authenticate(endpoint, token, login_user, login_password,
+ tenant_name, insecure)
+ check_mode = module.check_mode
+
+ try:
+ d = dispatch(keystone, name, service_type, description,
+ public_url, internal_url, admin_url, region, state,
+ check_mode)
+ except Exception:
+ if check_mode:
+ # If we have a failure in check mode
+ module.exit_json(changed=True,
+ msg="exception: %s" % traceback.format_exc())
+ else:
+ module.fail_json(msg=traceback.format_exc())
+ else:
+ module.exit_json(**d)
+
+
+# this is magic, see lib/ansible/module_common.py
+#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
+if __name__ == '__main__':
+ main()