#!/usr/bin/python -tt # 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 . DOCUMENTATION = ''' --- module: rax_keypair short_description: Create a keypair for use with Rackspace Cloud Servers description: - Create a keypair for use with Rackspace Cloud Servers version_added: 1.5 options: api_key: description: - Rackspace API key (overrides C(credentials)) credentials: description: - File to find the Rackspace credentials in (ignored if C(api_key) and C(username) are provided) default: null aliases: ['creds_file'] name: description: - Name of keypair required: true public_key: description: - Public Key string to upload default: null region: description: - Region to create the load balancer in default: DFW username: description: - Rackspace username (overrides C(credentials)) state: description: - Indicate desired state of the resource choices: ['present', 'absent'] default: present requirements: [ "pyrax" ] author: Matt Martz notes: - The following environment variables can be used, C(RAX_USERNAME), C(RAX_API_KEY), C(RAX_CREDS_FILE), C(RAX_CREDENTIALS), C(RAX_REGION). - C(RAX_CREDENTIALS) and C(RAX_CREDS_FILE) points to a credentials file appropriate for pyrax. See U(https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#authenticating) - C(RAX_USERNAME) and C(RAX_API_KEY) obviate the use of a credentials file - C(RAX_REGION) defines a Rackspace Public Cloud region (DFW, ORD, LON, ...) - Keypairs cannot be manipulated, only created and deleted. To "update" a keypair you must first delete and then recreate. ''' EXAMPLES = ''' - name: Create a keypair hosts: local gather_facts: False tasks: - name: keypair request local_action: module: rax_keypair credentials: ~/.raxpub name: my_keypair region: DFW register: keypair - name: Create local public key local_action: module: copy content: "{{ keypair.keypair.public_key }}" dest: "{{ inventory_dir }}/{{ keypair.keypair.name }}.pub" - name: Create local private key local_action: module: copy content: "{{ keypair.keypair.private_key }}" dest: "{{ inventory_dir }}/{{ keypair.keypair.name }}" ''' import sys import os from types import NoneType try: import pyrax except ImportError: print("failed=True msg='pyrax required for this module'") sys.exit(1) from novaclient.exceptions import NotFound NON_CALLABLES = (basestring, bool, dict, int, list, NoneType) def to_dict(obj): instance = {} for key in dir(obj): value = getattr(obj, key) if (isinstance(value, NON_CALLABLES) and not key.startswith('_')): instance[key] = value return instance def rax_keypair(module, name, public_key, state): changed = False cs = pyrax.cloudservers keypair = {} if state == 'present': try: keypair = cs.keypairs.find(name=name) except NotFound: try: keypair = cs.keypairs.create(name, public_key) changed = True except Exception, e: module.fail_json(msg='%s' % e.message) except Exception, e: module.fail_json(msg='%s' % e.message) elif state == 'absent': try: keypair = cs.keypairs.find(name=name) except: pass if keypair: try: keypair.delete() changed = True except Exception, e: module.fail_json(msg='%s' % e.message) module.exit_json(changed=changed, keypair=to_dict(keypair)) def main(): module = AnsibleModule( argument_spec=dict( api_key=dict(), credentials=dict(aliases=['creds_file']), name=dict(), public_key=dict(), region=dict(), state=dict(default='present', choices=['absent', 'present']), username=dict(), ), ) api_key = module.params.get('api_key') credentials = module.params.get('credentials') name = module.params.get('name') public_key = module.params.get('public_key') region = module.params.get('region') state = module.params.get('state') username = module.params.get('username') try: username = username or os.environ.get('RAX_USERNAME') api_key = api_key or os.environ.get('RAX_API_KEY') credentials = (credentials or os.environ.get('RAX_CREDENTIALS') or os.environ.get('RAX_CREDS_FILE')) region = region or os.environ.get('RAX_REGION') except KeyError, e: module.fail_json(msg='Unable to load %s' % e.message) try: pyrax.set_setting('identity_type', 'rackspace') if api_key and username: pyrax.set_credentials(username, api_key=api_key, region=region) elif credentials: credentials = os.path.expanduser(credentials) pyrax.set_credential_file(credentials, region=region) else: raise Exception('No credentials supplied!') except Exception, e: module.fail_json(msg='%s' % e.message) rax_keypair(module, name, public_key, state) from ansible.module_utils.basic import * main()