Merge pull request #4845 from lorin/ec2_ubuntu_ami
New module: ec2_ami_search
This commit is contained in:
commit
7a45e04777
1 changed files with 193 additions and 0 deletions
193
library/cloud/ec2_ami_search
Normal file
193
library/cloud/ec2_ami_search
Normal file
|
@ -0,0 +1,193 @@
|
|||
#!/usr/bin/python
|
||||
#
|
||||
# (c) 2013, Nimbis Services
|
||||
#
|
||||
# This file is part of Ansible
|
||||
#
|
||||
# Ansible 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.
|
||||
#
|
||||
# Ansible 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 Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ec2_ami_search
|
||||
short_description: Retrieve AWS AMI for a given operating system.
|
||||
description:
|
||||
- Look up the most recent AMI on AWS for a given operating system.
|
||||
- Returns C(ami), C(aki), C(ari), C(serial), C(tag)
|
||||
- If there is no AKI or ARI associated with an image, these will be C(null).
|
||||
- Example output: C({"ami": "ami-69f5a900", "changed": false, "aki": "aki-88aa75e1", "tag": "release", "ari": null, "serial": "20131024"})
|
||||
options:
|
||||
distro:
|
||||
description: Linux distribution (e.g., C(ubuntu))
|
||||
required: true
|
||||
choices: ["ubuntu"]
|
||||
release:
|
||||
description: short name of the release (e.g., C(precise))
|
||||
required: true
|
||||
stream:
|
||||
description: Type of release.
|
||||
required: false
|
||||
default: "server"
|
||||
choices: ["server", "desktop"]
|
||||
store:
|
||||
description: Back-end store for instance
|
||||
required: false
|
||||
default: "ebs"
|
||||
choices: ["ebs", "instance-store"]
|
||||
arch:
|
||||
description: CPU architecture
|
||||
required: false
|
||||
default: "amd64"
|
||||
choices: ["i386", "amd64"]
|
||||
region:
|
||||
description: EC2 region
|
||||
required: false
|
||||
default: us-east-1
|
||||
choices: ["ap-northeast-1", "ap-southeast-1", "ap-southeast-2",
|
||||
"eu-west-1", "sa-east-1", "us-east-1", "us-west-1", "us-west-2"]
|
||||
virt:
|
||||
description: virutalization type
|
||||
required: false
|
||||
default: paravirtual
|
||||
choices: ["paravirtual", "hvm"]
|
||||
|
||||
author: Lorin Hochstein
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Lauch an Ubuntu 12.04 (Precise Pangolin) EC2 instance
|
||||
hosts: 127.0.0.1
|
||||
connection: local
|
||||
tasks:
|
||||
- name: Get the Ubuntu precise AMI
|
||||
ec2_ami_search: distro=ubuntu release=precise region=us-west-1 store=instance-store
|
||||
register: ubuntu_image
|
||||
- name: Start the EC2 instance
|
||||
ec2: image={{ ubuntu_image.ami }} instance_type=m1.small key_name=mykey
|
||||
'''
|
||||
|
||||
import csv
|
||||
import json
|
||||
import urllib2
|
||||
import urlparse
|
||||
|
||||
SUPPORTED_DISTROS = ['ubuntu']
|
||||
|
||||
AWS_REGIONS = ['ap-northeast-1',
|
||||
'ap-southeast-1',
|
||||
'ap-southeast-2',
|
||||
'eu-west-1',
|
||||
'sa-east-1',
|
||||
'us-east-1',
|
||||
'us-west-1',
|
||||
'us-west-2']
|
||||
|
||||
|
||||
def get_url(module, url):
|
||||
""" Get url and return response """
|
||||
try:
|
||||
r = urllib2.urlopen(url)
|
||||
except (urllib2.HTTPError, urllib2.URLError), e:
|
||||
code = getattr(e, 'code', -1)
|
||||
module.fail_json(msg="Request failed: %s" % str(e), status_code=code)
|
||||
return r
|
||||
|
||||
|
||||
def ubuntu(module):
|
||||
""" Get the ami for ubuntu """
|
||||
|
||||
release = module.params['release']
|
||||
stream = module.params['stream']
|
||||
store = module.params['store']
|
||||
arch = module.params['arch']
|
||||
region = module.params['region']
|
||||
virt = module.params['virt']
|
||||
|
||||
url = get_ubuntu_url(release, stream)
|
||||
|
||||
req = get_url(module, url)
|
||||
reader = csv.reader(req, delimiter='\t')
|
||||
try:
|
||||
ami, aki, ari, tag, serial = lookup_ubuntu_ami(reader, release, stream,
|
||||
store, arch, region, virt)
|
||||
module.exit_json(changed=False, ami=ami, aki=aki, ari=ari, tag=tag,
|
||||
serial=serial)
|
||||
except KeyError:
|
||||
module.fail_json(msg="No matching AMI found")
|
||||
|
||||
|
||||
def lookup_ubuntu_ami(table, release, stream, store, arch, region, virt):
|
||||
""" Look up the Ubuntu AMI that matches query given a table of AMIs
|
||||
|
||||
table: an iterable that returns a row of
|
||||
(release, stream, tag, serial, region, ami, aki, ari, virt)
|
||||
release: ubuntu release name
|
||||
stream: 'server' or 'desktop'
|
||||
store: 'ebs' or 'instance-store'
|
||||
arch: 'i386' or 'amd64'
|
||||
region: EC2 region
|
||||
virt: 'paravirtual' or 'hvm'
|
||||
|
||||
Returns (ami, aki, ari, tag, serial)"""
|
||||
expected = (release, stream, store, arch, region, virt)
|
||||
|
||||
for row in table:
|
||||
(actual_release, actual_stream, tag, serial,
|
||||
actual_store, actual_arch, actual_region, ami, aki, ari,
|
||||
actual_virt) = row
|
||||
actual = (actual_release, actual_stream, actual_store, actual_arch,
|
||||
actual_region, actual_virt)
|
||||
if actual == expected:
|
||||
# aki and ari are sometimes blank
|
||||
if aki == '':
|
||||
aki = None
|
||||
if ari == '':
|
||||
ari = None
|
||||
return (ami, aki, ari, tag, serial)
|
||||
|
||||
raise KeyError()
|
||||
|
||||
|
||||
def get_ubuntu_url(release, stream):
|
||||
url = "https://cloud-images.ubuntu.com/query/%s/%s/released.current.txt"
|
||||
return url % (release, stream)
|
||||
|
||||
|
||||
def main():
|
||||
arg_spec = dict(
|
||||
distro=dict(required=True, choices=SUPPORTED_DISTROS),
|
||||
release=dict(required=True),
|
||||
stream=dict(required=False, default='server',
|
||||
choices=['desktop', 'server']),
|
||||
store=dict(required=False, default='ebs',
|
||||
choices=['ebs', 'instance-store']),
|
||||
arch=dict(required=False, default='amd64',
|
||||
choices=['i386', 'amd64']),
|
||||
region=dict(required=False, default='us-east-1', choices=AWS_REGIONS),
|
||||
virt=dict(required=False, default='paravirtual',
|
||||
choices=['paravirtual', 'hvm'])
|
||||
)
|
||||
module = AnsibleModule(argument_spec=arg_spec)
|
||||
distro = module.params['distro']
|
||||
|
||||
if distro == 'ubuntu':
|
||||
ubuntu(module)
|
||||
else:
|
||||
module.fail_json(msg="Unsupported distro: %s" % distro)
|
||||
|
||||
|
||||
|
||||
# this is magic, see lib/ansible/module_common.py
|
||||
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in a new issue