Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenStack Modules #2985

Merged
merged 1 commit into from
May 25, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
240 changes: 240 additions & 0 deletions library/cloud/glance_image
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

# (c) 2013, Benno Joy <benno@ansibleworks.com>
#
# This module is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this software. If not, see <http://www.gnu.org/licenses/>.

DOCUMENTATION = '''
---
module: glance_image
short_description: Add/Delete images from glance
description:
- Add or Remove images from the glance repository.
options:
login_username:
description:
- login username to authenticate to keystone
required: true
default: admin
login_password:
description:
- Password of login user
required: true
default: True
login_tenant_name:
description:
- The tenant name of the login user
required: true
default: True
auth_url:
description:
- The keystone url for authentication
required: false
default: 'http://127.0.0.1:35357/v2.0/'
region_name:
description:
- Name of the region
required: false
default: None
state:
description:
- Indicate desired state of the resource
choices: ['present', 'absent']
default: present
name:
description:
- Name that has to be given to the image
required: true
default: None
disk_format:
description:
- The format of the disk that is getting uploaded
required: false
default: qcow2
container_format:
description:
- The format of the container
required: false
default: bare
owner:
description:
- The owner of the image
required: false
default: None
min_disk:
description:
- The minimum disk space required to deploy this image
required: false
default: None
min_ram:
description:
- The minimum ram required to deploy this image
required: false
default: None
is_public:
description:
- Wether the image can be accesed publically
required: false
default: yes
copy_from:
description:
- A url from where the image can be downloaded, mutually exculsive with file parameter
required: false
default: None
timeout:
description:
- The time to wait for the image process to complete in seconds
required: false
default: 180
file:
description:
- The path to the file which has to be uploaded, mutually exclusive with copy_from
required: false
default: None
examples:
- code: "glance_image: login_username=admin login_password=passme login_tenant_name=admin name=cirros container_format=bare
disk_format=qcow2 state=present copy_from=http:launchpad.net/cirros/trunk/0.3.0/+download/cirros-0.3.0-x86_64-disk.img"
description: "Uploads an image from an http url"
requirements: ["glanceclient", "keystoneclient"]

'''

import time
try:
import glanceclient
from keystoneclient.v2_0 import client as ksclient
except ImportError:
print("failed=True msg='glanceclient and keystone client are required'")

def _get_ksclient(module, kwargs):
try:
client = ksclient.Client(username=kwargs.get('login_username'),
password=kwargs.get('login_password'),
tenant_name=kwargs.get('login_tenant_name'),
auth_url=kwargs.get('auth_url'))
except Exception as e:
module.fail_json(msg = "Error authenticating to the keystone: %s " % e.message)
return client


def _get_endpoint(module, client):
try:
endpoint = client.service_catalog.url_for(service_type='image', endpoint_type='publicURL')
except Exception as e:
module.fail_json(msg = "Error getting endpoint for glance: %s" % e.message)
return endpoint

def _get_glance_client(module, kwargs):
_ksclient = _get_ksclient(module, kwargs)
token = _ksclient.auth_token
endpoint =_get_endpoint(module, _ksclient)
kwargs = {
'token': token,
}
try:
client = glanceclient.Client('1', endpoint, **kwargs)
except Exception as e:
module.fail_json(msg = "Error in connecting to glance: %s" %e.message)
return client

def _glance_image_present(module, params, client):
try:
for image in client.images.list():
if image.name == params['name']:
return image.id
return None
except Exception as e:
module.fail_json(msg = "Error in fetching image list: %s" %e.message)

def _glance_image_create(module, params, client):
kwargs = {
'name': params.get('name'),
'disk_format': params.get('disk_format'),
'container_format': params.get('container_format'),
'owner': params.get('owner'),
'is_public': params.get('is_public'),
'copy_from': params.get('copy_from'),
}
try:
timeout = params.get('timeout')
expire = time.time() + timeout
image = client.images.create(**kwargs)
if not params['copy_from']:
image.update(data=open(params['file'], 'rb'))
while time.time() < expire:
image = client.images.get(image.id)
if image.status == 'active':
break
time.sleep(5)
except Exception as e:
module.fail_json(msg = "Error in creating image: %s" %e.message )
if image.status == 'active':
module.exit_json(changed = True, result = image.status, id=image.id)
else:
module.fail_json(msg = " The module timed out, please check manually " + image.status)

def _glance_delete_image(module, params, client):
try:
for image in client.images.list():
if image.name == params['name']:
client.images.delete(image)
except Exception as e:
module.fail_json(msg = "Error in deleting image: %s" %e.message)
module.exit_json(changed = True, result = "Deleted")

def main():

module = AnsibleModule(
argument_spec = dict(
login_username = dict(default='admin'),
login_password = dict(required=True),
login_tenant_name = dict(required=True),
auth_url = dict(default='http://127.0.0.1:35357/v2.0/'),
region_name = dict(default=None),
name = dict(required=True),
disk_format = dict(default='qcow2', choices=['aki', 'vhd', 'vmdk', 'raw', 'qcow2', 'vdi', 'iso']),
container_format = dict(default='bare', choices=['aki', 'ari', 'bare', 'ovf']),
owner = dict(default=None),
min_disk = dict(default=None),
min_ram = dict(default=None),
is_public = dict(default=True),
copy_from = dict(default= None),
timeout = dict(default=180),
file = dict(default=None),
state = dict(default='present', choices=['absent', 'present'])
),
mutually_exclusive = [['file','copy_from']],
)
if module.params['state'] == 'present':
if not module.params['file'] and not module.params['copy_from']:
module.fail_json(msg = "Either file or copy_from variable should be set to create the image")
client = _get_glance_client(module, module.params)
id = _glance_image_present(module, module.params, client)
if not id:
_glance_image_create(module, module.params, client)
module.exit_json(changed = False, id = id, result = "success")

if module.params['state'] == 'absent':
client = _get_glance_client(module, module.params)
id = _glance_image_present(module, module.params, client)
if not id:
module.exit_json(changed = False, result = "Success")
else:
_glance_delete_image(module, module.params, client)

# this is magic, see lib/ansible/module.params['common.py
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
main()