openstack-ansible/playbooks/library/glance
Jesse Pretorius 4341b79b3a Enable all services to use Keystone 'insecurely'
This patch introduces an insecure flag for the Keystone internal
 and admin endpoints:

* keystone_service_adminuri_insecure
* keystone_service_internaluri_insecure

Both values default to false. If you have setup SSL endpoints
for Keystone using an untrusted certificate then you should
set the appropriate flag to true in your user_variables.

This patch is used to enable testing and development with
Keystone SSL endpoints without having to make use of SSL
certificates signed by a trusted, public CA.

The patch introduces a new optional argument (insecure) to the
keystone, glance and neutron Ansible libraries. This is a
boolean value which, when true, enables these libraries to
access Keystone endpoints 'insecurely'. When these libraries
are used in plays, the appropriate value is set automatically
as per the above conditions.

Implements: blueprint keystone-federation
Change-Id: Ia07e7e201f901042dd06a86efe5c6f6725e9ce13
2015-07-10 14:06:25 +01:00

234 lines
7.3 KiB
Python

#!/usr/bin/env python
# Copyright 2014, Rackspace US, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
DOCUMENTATION = """
---
module: glance
short_description:
- Basic module for interacting with openstack glance
description:
- Basic module for interacting with openstack glance
options:
command:
description:
- Operation for the module to perform. Currently available
choices:
- image-list
- image-create
openrc_path:
decription:
- Path to openrc file from which credentials and keystoneclient
- endpoint will be extracted
image_name:
description:
- Name of the image to create
image_url:
description:
- URL from which to download the image data
image_container_format:
description:
- container format that the image uses (bare)
image_disk_format:
description:
- disk format that the image uses
image_is_public:
description:
- Should the image be visible to all tenants?
choices:
- true (public)
- false (private)
api_version:
description:
- which version of the glance api to use
choices:
- 1
- 2
default: 1
insecure:
description:
- Explicitly allow client to perform "insecure" TLS
choices:
- false
- true
default: false
author: Hugh Saunders
"""
EXAMPLES = """
# Create an image
- name: Ensure cirros image
glance:
command: 'image-create'
openrc_path: /root/openrc
image_name: cirros
image_url: 'https://example-domain.com/cirros-0.3.2-source.tar.gz'
image_container_format: bare
image_disk_format: qcow2
image_is_public: True
# Get facts about existing images
- name: Get image facts
glance:
command: 'image-list'
openrc_path: /root/openrc
"""
import glanceclient.client as glclient
import keystoneclient.v2_0.client as ksclient
COMMAND_MAP = {'image-list': 'list_images',
'image-create': 'create_image'}
class ManageGlance(object):
def __init__(self, module):
self.state_change = False
self.glance = None
self.keystone = None
self.module = module
try:
self._keystone_authenticate()
self._init_glance()
except Exception as e:
self.module.fail_json(
err="Initialisation Error: %s" % e,
rc=2, msg=str(e))
def _parse_openrc(self):
"""Get credentials from an openrc file."""
openrc_path = self.module.params['openrc_path']
line_re = re.compile('^export (?P<key>OS_\w*)=(?P<value>[^\n]*)')
with open(openrc_path) as openrc:
matches = [line_re.match(l) for l in openrc]
return dict(
(g.groupdict()['key'], g.groupdict()['value'])
for g in matches if g
)
def _keystone_authenticate(self):
"""Authenticate with Keystone."""
openrc = self._parse_openrc()
insecure = self.module.params['insecure']
self.keystone = ksclient.Client(insecure=insecure,
username=openrc['OS_USERNAME'],
password=openrc['OS_PASSWORD'],
tenant_name=openrc['OS_TENANT_NAME'],
auth_url=openrc['OS_AUTH_URL'])
def _init_glance(self):
"""Create glance client object using token and url from keystone."""
openrc = self._parse_openrc()
p = self.module.params
v = p['api_version']
ep = self.keystone.service_catalog.url_for(
service_type='image',
endpoint_type=openrc['OS_ENDPOINT_TYPE']
)
self.glance = glclient.Client(
endpoint='%s/v%s' % (ep, v),
token=self.keystone.get_token(self.keystone.session)
)
def route(self):
"""Run the command specified by the command parameter."""
getattr(self, COMMAND_MAP[self.module.params['command']])()
def _get_image_facts(self):
"""Helper function to format image list as a dictionary."""
p = self.module.params
v = p['api_version']
if v == '1':
return dict(
(i.name, i.to_dict()) for i in self.glance.images.list()
)
elif v == '2':
return dict(
(i.name, i) for i in self.glance.images.list()
)
def list_images(self):
"""Get information about available glance images.
Returns as a fact dictionary glance_images
"""
self.module.exit_json(
changed=self.state_change,
ansible_facts=dict(glance_images=self._get_image_facts()))
def create_image(self):
"""Create a glance image that references a remote url."""
p = self.module.params
v = p['api_version']
image_name = p['image_name']
image_opts = dict(
name=image_name,
disk_format=p['image_disk_format'],
container_format=p['image_container_format'],
copy_from=p['image_url']
)
if v == '1':
image_opts['is_public'] = p['image_is_public']
elif v == '2':
if p['image_is_public']:
vis = 'public'
else:
vis = 'private'
image_opts['visibility'] = vis
images = {i.name for i in self.glance.images.list()}
if image_name in images:
self.module.exit_json(
changed=self.state_change,
ansible_facts=dict(
glance_images=self._get_image_facts()
)
)
else:
self.glance.images.create(**image_opts)
self.state_change = True
self.module.exit_json(
changed=self.state_change,
ansible_facts=dict(
glance_images=self._get_image_facts()
)
)
def main():
module = AnsibleModule(
argument_spec=dict(
command=dict(required=True, choices=COMMAND_MAP.keys()),
openrc_path=dict(required=True),
image_name=dict(required=False),
image_url=dict(required=False),
image_container_format=dict(required=False),
image_disk_format=dict(required=False),
image_is_public=dict(required=False, choices=BOOLEANS),
api_version=dict(default='1', required=False, choices=['1', '2']),
insecure=dict(default=False, required=False,
choices=BOOLEANS + ['True', 'False'])
),
supports_check_mode=False
)
mg = ManageGlance(module)
mg.route()
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()