@ -104,6 +104,12 @@ options:
- The path to the file which has to be uploaded, mutually exclusive with copy_from
- The path to the file which has to be uploaded, mutually exclusive with copy_from
required: false
required: false
default: None
default: None
endpoint_type:
description:
- endpoint URL type
choices: [publicURL, internalURL]
required: false
default: publicURL
requirements: ["glanceclient", "keystoneclient"]
requirements: ["glanceclient", "keystoneclient"]
'''
'''
@ -114,7 +120,7 @@ EXAMPLES = '''
login_password=passme
login_password=passme
login_tenant_name=admin
login_tenant_name=admin
name=cirros
name=cirros
container_format=bare
container_format=bare
disk_format=qcow2
disk_format=qcow2
state=present
state=present
copy_from=http:launchpad.net/cirros/trunk/0.3.0/+download/cirros-0.3.0-x86_64-disk.img
copy_from=http:launchpad.net/cirros/trunk/0.3.0/+download/cirros-0.3.0-x86_64-disk.img
@ -127,45 +133,49 @@ try:
except ImportError:
except ImportError:
print("failed=True msg='glanceclient and keystone client are required'")
print("failed=True msg='glanceclient and keystone client are required'")
def _get_ksclient(module, kwargs):
def _get_ksclient(module, kwargs):
try:
try:
client = ksclient.Client(username=kwargs.get('login_username'),
client = ksclient.Client(username=kwargs.get('login_username'),
password=kwargs.get('login_password'),
password=kwargs.get('login_password'),
tenant_name=kwargs.get('login_tenant_name'),
tenant_name=kwargs.get('login_tenant_name'),
auth_url=kwargs.get('auth_url'))
auth_url=kwargs.get('auth_url'))
except Exception, e:
except Exception, e:
module.fail_json(msg = "Error authenticating to the keystone: %s " % e.message)
module.fail_json(msg="Error authenticating to the keystone: %s " % e.message)
return client
return client
def _get_endpoint(module, client):
def _get_endpoint(module, client, endpoint_type):
try:
try:
endpoint = client.service_catalog.url_for(service_type='image', endpoint_type='publicURL' )
endpoint = client.service_catalog.url_for(service_type='image', endpoint_type=endpoint_type )
except Exception, e:
except Exception, e:
module.fail_json(msg = "Error getting endpoint for glance: %s" % e.message)
module.fail_json(msg="Error getting endpoint for glance: %s" % e.message)
return endpoint
return endpoint
def _get_glance_client(module, kwargs):
def _get_glance_client(module, kwargs):
_ksclient = _get_ksclient(module, kwargs)
_ksclient = _get_ksclient(module, kwargs)
token = _ksclient.auth_token
token = _ksclient.auth_token
endpoint =_get_endpoint(module, _ksclient)
endpoint =_get_endpoint(module, _ksclient, kwargs.get('endpoint_type') )
kwargs = {
kwargs = {
'token': token,
'token': token,
}
}
try:
try:
client = glanceclient.Client('1', endpoint, **kwargs)
client = glanceclient.Client('1', endpoint, **kwargs)
except Exception, e:
except Exception, e:
module.fail_json(msg = "Error in connecting to glance: %s" %e.message)
module.fail_json(msg="Error in connecting to glance: %s" % e.message)
return client
return client
def _glance_image_present(module, params, client):
def _glance_image_present(module, params, client):
try:
try:
for image in client.images.list():
for image in client.images.list():
if image.name == params['name']:
if image.name == params['name']:
return image.id
return image.id
return None
return None
except Exception, e:
except Exception, e:
module.fail_json(msg = "Error in fetching image list: %s" %e.message)
module.fail_json(msg="Error in fetching image list: %s" % e.message)
def _glance_image_create(module, params, client):
def _glance_image_create(module, params, client):
kwargs = {
kwargs = {
@ -176,7 +186,7 @@ def _glance_image_create(module, params, client):
'is_public': params.get('is_public'),
'is_public': params.get('is_public'),
'copy_from': params.get('copy_from'),
'copy_from': params.get('copy_from'),
}
}
try:
try:
timeout = float(params.get('timeout'))
timeout = float(params.get('timeout'))
expire = time.time() + timeout
expire = time.time() + timeout
image = client.images.create(**kwargs)
image = client.images.create(**kwargs)
@ -187,24 +197,26 @@ def _glance_image_create(module, params, client):
if image.status == 'active':
if image.status == 'active':
break
break
time.sleep(5)
time.sleep(5)
except Exception, e:
except Exception, e:
module.fail_json(msg = "Error in creating image: %s" %e.message)
module.fail_json(msg="Error in creating image: %s" % e.message)
if image.status == 'active':
if image.status == 'active':
module.exit_json(changed = True, result = image.status, id=image.id)
module.exit_json(changed=True, result=image.status, id=image.id)
else:
else:
module.fail_json(msg = " The module timed out, please check manually " + image.status)
module.fail_json(msg=" The module timed out, please check manually " + image.status)
def _glance_delete_image(module, params, client):
def _glance_delete_image(module, params, client):
try:
try:
for image in client.images.list():
for image in client.images.list():
if image.name == params['name']:
if image.name == params['name']:
client.images.delete(image)
client.images.delete(image)
except Exception, e:
except Exception, e:
module.fail_json(msg = "Error in deleting image: %s" %e.message)
module.fail_json(msg="Error in deleting image: %s" % e.message)
module.exit_json(changed = True, result = "Deleted")
module.exit_json(changed=True, result="Deleted")
def main():
def main():
module = AnsibleModule(
module = AnsibleModule(
argument_spec = dict(
argument_spec = dict(
login_username = dict(default='admin'),
login_username = dict(default='admin'),
@ -220,30 +232,30 @@ def main():
min_ram = dict(default=None),
min_ram = dict(default=None),
is_public = dict(default=True),
is_public = dict(default=True),
copy_from = dict(default= None),
copy_from = dict(default= None),
timeout = dict(default=180),
timeout = dict(default=180),
file = dict(default=None),
file = dict(default=None),
state = dict(default='present', choices=['absent', 'present'])
endpoint_type = dict(default='publicURL', choices=['publicURL', 'internalURL']),
state = dict(default='present', choices=['absent', 'present'])
),
),
mutually_exclusive = [['file','copy_from']],
mutually_exclusive = [['file','copy_from']],
)
)
if module.params['state'] == 'present':
if module.params['state'] == 'present':
if not module.params['file'] and not module.params['copy_from']:
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")
module.fail_json(msg="Either file or copy_from variable should be set to create the image")
client = _get_glance_client(module, module.params)
client = _get_glance_client(module, module.params)
id = _glance_image_present(module, module.params, client)
id = _glance_image_present(module, module.params, client)
if not id:
if not id:
_glance_image_create(module, module.params, client)
_glance_image_create(module, module.params, client)
module.exit_json(changed = False, id = id, result = "success")
module.exit_json(changed=False, id=id, result="success")
if module.params['state'] == 'absent':
if module.params['state'] == 'absent':
client = _get_glance_client(module, module.params)
client = _get_glance_client(module, module.params)
id = _glance_image_present(module, module.params, client)
id = _glance_image_present(module, module.params, client)
if not id:
if not id:
module.exit_json(changed = False, result = "Success")
module.exit_json(changed=False, result="Success")
else:
else:
_glance_delete_image(module, module.params, client)
_glance_delete_image(module, module.params, client)
# this is magic, see lib/ansible/module.params['common.py
# this is magic, see lib/ansible/module.params['common.py
from ansible.module_utils.basic import *
from ansible.module_utils.basic import *
main()
main()