Add ability to filter on image and flavor names

The fun part about having multiple vendors providing the same cloud
is that while their APIs are the same, what they do with their metadata
tends to be ... fun. So in order to be able to express sanely what you
want without needing to stick tons of unreadable uuids in your config,
it turns out what sometimes you need to further filter image and flavor
names. Specific examples are (deprecated) images in HP Cloud and the
Standard and Performance flavors on Rackspace.
This commit is contained in:
Monty Taylor 2014-08-02 20:31:31 -07:00
parent 65adb6465b
commit b80be42ed9

View file

@ -17,6 +17,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this software. If not, see <http://www.gnu.org/licenses/>. # along with this software. If not, see <http://www.gnu.org/licenses/>.
import operator
import os import os
try: try:
@ -81,6 +82,9 @@ options:
- The name of the base image to boot. Mutually exclusive with image_id - The name of the base image to boot. Mutually exclusive with image_id
required: true required: true
default: None default: None
image_filter:
description:
- Text to use to filter image names, for the case, such as HP, where there are multiple image names matching the common identifying portions. image_filter is a negative match filter - it is text that may not exist in the image name. Defaults to "(deprecated)"
flavor_id: flavor_id:
description: description:
- The id of the flavor in which the new VM has to be created. Mutually exclusive with flavor_ram - The id of the flavor in which the new VM has to be created. Mutually exclusive with flavor_ram
@ -91,6 +95,9 @@ options:
- The minimum amount of ram in MB that the flavor in which the new VM has to be created must have. Mutually exclusive with flavor_id - The minimum amount of ram in MB that the flavor in which the new VM has to be created must have. Mutually exclusive with flavor_id
required: false required: false
default: 1 default: 1
flavor_filter:
description:
- Text to use to filter flavor names, for the case, such as Rackspace, where there are multiple flavors that have the same ram count. flavor_filter is a positive match filter - it must exist in the flavor name.
key_name: key_name:
description: description:
- The key pair name to be used when creating a VM - The key pair name to be used when creating a VM
@ -335,26 +342,22 @@ def _get_ips(addresses, ext_tag, key_name):
def _get_image_id(module, nova): def _get_image_id(module, nova):
if module.params['image_name']: if module.params['image_name']:
image = None for image in nova.images.list():
for img in nova.images.list(): if (module.params['image_name'] in img.name and (
if img.name == module.params['image_name']: not module.params['image_filter']
image = img or module.params['image_filter'] not in img.name)):
break return image.id
if img.name.startswith(module.params['image_name']) and '(deprecated)' not in img.name: module.fail_json(msg = "Error finding image id from name(%s)" % module.params['image_name'])
image = img
if not image:
module.fail_json(msg = "Error finding image id from name(%s)" % module.params['image_name'])
return image.id
return module.params['image_id'] return module.params['image_id']
def _get_flavor_id(module, nova): def _get_flavor_id(module, nova):
if module.params['flavor_ram']: if module.params['flavor_ram']:
try: for flavor in sorted(nova.flavors.list(), key=operator.attrgetter('ram')):
flavor = nova.flavors.find(ram=module.params['flavor_ram']) if (flavor.ram >= module.params['flavor_ram'] and
except exceptions.NotFound as e: (not module.params['flavor_filter'] or module.params['flavor_filter'] in flavor.name)):
return flavor.id
module.fail_json(msg = "Error finding flavor with %sMB of RAM" % module.params['flavor_ram']) module.fail_json(msg = "Error finding flavor with %sMB of RAM" % module.params['flavor_ram'])
return flavor.id
return module.params['flavor_id'] return module.params['flavor_id']
@ -440,8 +443,10 @@ def main():
name = dict(required=True), name = dict(required=True),
image_id = dict(default=None), image_id = dict(default=None),
image_name = dict(default=None), image_name = dict(default=None),
image_filter = dict(default='(deprecated)'),
flavor_id = dict(default=1), flavor_id = dict(default=1),
flavor_ram = dict(default=None, type='int'), flavor_ram = dict(default=None, type='int'),
flavor_filter = dict(default=None),
key_name = dict(default=None), key_name = dict(default=None),
security_groups = dict(default='default'), security_groups = dict(default='default'),
nics = dict(default=None), nics = dict(default=None),
@ -488,7 +493,7 @@ def main():
_get_server_state(module, nova) _get_server_state(module, nova)
_delete_server(module, nova) _delete_server(module, nova)
# this is magic, see lib/ansible/module.params['common.py # this is magic, see lib/ansible/module_common.py
from ansible.module_utils.basic import * from ansible.module_utils.basic import *
from ansible.module_utils.openstack import * from ansible.module_utils.openstack import *
main() main()