mirror of https://github.com/ansible/ansible.git
Added Softlayer Module
parent
8b83aa4c50
commit
c6598e3672
@ -0,0 +1,348 @@
|
||||
#!/usr/bin/python
|
||||
# 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: SoftLayer
|
||||
short_description: create or cancel a virtual instance in SoftLayer
|
||||
description:
|
||||
- Creates or cancels SoftLayer instances. When created, optionally waits for it to be 'running'.
|
||||
version_added: "2.1"
|
||||
options:
|
||||
instance_id:
|
||||
description:
|
||||
- Instance Id of the virtual instance to perform action option
|
||||
required: false
|
||||
default: null
|
||||
hostname:
|
||||
description:
|
||||
- Hostname to be provided to a virtual instance
|
||||
required: false
|
||||
default: null
|
||||
domain:
|
||||
description:
|
||||
- Domain name to be provided to a virtual instance
|
||||
required: false
|
||||
default: null
|
||||
datacenter:
|
||||
description:
|
||||
- Datacenter for the virtual instance to be deployed
|
||||
required: false
|
||||
default: null
|
||||
tags:
|
||||
description:
|
||||
- Tag or list of tags to be provided to a virtual instance
|
||||
required: false
|
||||
default: null
|
||||
hourly:
|
||||
description:
|
||||
- Flag to determine if the instance should be hourly billed
|
||||
required: false
|
||||
default: true
|
||||
private:
|
||||
description:
|
||||
- Flag to determine if the instance should be private only
|
||||
required: false
|
||||
default: false
|
||||
dedicated:
|
||||
description:
|
||||
- Falg to determine if the instance should be deployed in dedicated space
|
||||
required: false
|
||||
default: false
|
||||
local_disk:
|
||||
description:
|
||||
- Flag to determine if local disk should be used for the new instance
|
||||
required: false
|
||||
default: true
|
||||
cpus:
|
||||
description:
|
||||
- Count of cpus to be assigned to new virtual instance
|
||||
required: true
|
||||
default: null
|
||||
memory:
|
||||
description:
|
||||
- Amount of memory to be assigned to new virtual instance
|
||||
required: true
|
||||
default: null
|
||||
disks:
|
||||
description:
|
||||
- List of disk sizes to be assigned to new virtual instance
|
||||
required: true
|
||||
default: [25]
|
||||
os_code:
|
||||
description:
|
||||
- OS Code to be used for new virtual instance
|
||||
required: false
|
||||
default: null
|
||||
image_id:
|
||||
description:
|
||||
- Image Template to be used for new virtual instance
|
||||
required: false
|
||||
default: null
|
||||
nic_speed:
|
||||
description:
|
||||
- NIC Speed to be assigned to new virtual instance
|
||||
required: false
|
||||
default: 10
|
||||
public_vlan:
|
||||
description:
|
||||
- VLAN by its Id to be assigned to the public NIC
|
||||
required: false
|
||||
default: null
|
||||
private_vlan:
|
||||
description:
|
||||
- VLAN by its Id to be assigned to the private NIC
|
||||
required: false
|
||||
default: null
|
||||
ssh_keys:
|
||||
description:
|
||||
- List of ssh keys by their Id to be assigned to a virtual instance
|
||||
required: false
|
||||
default: null
|
||||
post_uri:
|
||||
description:
|
||||
- URL of a post provisioning script ot be loaded and exectued on virtual instance
|
||||
required: false
|
||||
default: null
|
||||
state:
|
||||
description:
|
||||
- Create, or cancel a virtual instance. Specify "present" for create, "absent" to cancel.
|
||||
required: false
|
||||
default: 'present'
|
||||
wait:
|
||||
description:
|
||||
- Flag used to wait for active status before returning
|
||||
required: false
|
||||
default: true
|
||||
wait_timeout:
|
||||
description:
|
||||
- time in seconds before wait returns
|
||||
required: false
|
||||
default: 600
|
||||
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "softlayer >= 4.1.1"
|
||||
author: "Matt Colton (@mcltn)"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Build instance
|
||||
hosts: localhost
|
||||
gather_facts: False
|
||||
tasks:
|
||||
- name: Build instance request
|
||||
local_action:
|
||||
module: sl
|
||||
hostname: instance-1
|
||||
domain: anydomain.com
|
||||
datacenter: dal09
|
||||
tags: ansible-module-test
|
||||
hourly: True
|
||||
private: False
|
||||
dedicated: False
|
||||
local_disk: True
|
||||
cpus: 1
|
||||
memory: 1024
|
||||
disks: [25]
|
||||
os_code: UBUNTU_LATEST
|
||||
wait: False
|
||||
|
||||
- name: Build additional instances
|
||||
hosts: localhost
|
||||
gather_facts: False
|
||||
tasks:
|
||||
- name: Build instances request
|
||||
local_action:
|
||||
module: sl
|
||||
hostname: "{{ item.hostname }}"
|
||||
domain: "{{ item.domain }}"
|
||||
datacenter: "{{ item.datacenter }}"
|
||||
tags: "{{ item.tags }}"
|
||||
hourly: "{{ item.hourly }}"
|
||||
private: "{{ item.private }}"
|
||||
dedicated: "{{ item.dedicated }}"
|
||||
local_disk: "{{ item.local_disk }}"
|
||||
cpus: "{{ item.cpus }}"
|
||||
memory: "{{ item.memory }}"
|
||||
disks: "{{ item.disks }}"
|
||||
os_code: "{{ item.os_code }}"
|
||||
ssh_keys: "{{ item.ssh_keys }}"
|
||||
wait: "{{ item.wait }}"
|
||||
with_items:
|
||||
- { hostname: 'instance-2', domain: 'anydomain.com', datacenter: 'dal09', tags: ['ansible-module-test', 'ansible-module-test-slaves'], hourly: True, private: False, dedicated: False, local_disk: True, cpus: 1, memory: 1024, disks: [25,100], os_code: 'UBUNTU_LATEST', ssh_keys: [], wait: True }
|
||||
- { hostname: 'instance-3', domain: 'anydomain.com', datacenter: 'dal09', tags: ['ansible-module-test', 'ansible-module-test-slaves'], hourly: True, private: False, dedicated: False, local_disk: True, cpus: 1, memory: 1024, disks: [25,100], os_code: 'UBUNTU_LATEST', ssh_keys: [], wait: True }
|
||||
|
||||
|
||||
- name: Cancel instances
|
||||
hosts: localhost
|
||||
gather_facts: False
|
||||
tasks:
|
||||
- name: Cancel by tag
|
||||
local_action:
|
||||
module: sl
|
||||
state: absent
|
||||
tags: ansible-module-test
|
||||
'''
|
||||
|
||||
# TODO: Disabled RETURN as it is breaking the build for docs. Needs to be fixed.
|
||||
RETURN = '''# '''
|
||||
|
||||
import time
|
||||
|
||||
STATES = ['present', 'absent']
|
||||
DATACENTERS = ['ams01','ams03','dal01','dal05','dal06','dal09','fra02','hkg02','hou02','lon2','mel01','mex01','mil01','mon01','par01','sjc01','sjc03','sao01','sea01','sng01','syd01','tok02','tor01','wdc01','wdc04']
|
||||
CPU_SIZES = [1,2,4,8,16]
|
||||
MEMORY_SIZES = [1024,2048,4096,6144,8192,12288,16384,32768,49152,65536]
|
||||
INITIALDISK_SIZES = [25,100]
|
||||
LOCALDISK_SIZES = [25,100,150,200,300]
|
||||
SANDISK_SIZES = [10,20,25,30,40,50,75,100,125,150,175,200,250,300,350,400,500,750,1000,1500,2000]
|
||||
NIC_SPEEDS = [10,100,1000]
|
||||
|
||||
try:
|
||||
import SoftLayer
|
||||
from SoftLayer import VSManager
|
||||
|
||||
HAS_SL = True
|
||||
vsManager = VSManager(SoftLayer.create_client_from_env())
|
||||
except ImportError:
|
||||
HAS_SL = False
|
||||
|
||||
|
||||
def create_virtual_instance(module):
|
||||
|
||||
# Check if OS or Image Template is provided (Can't be both, defaults to OS)
|
||||
if (module.params.get('os_code') != None and module.params.get('os_code') != ''):
|
||||
module.params['image_id'] = ''
|
||||
elif (module.params.get('image_id') != None and module.params.get('image_id') != ''):
|
||||
module.params['os_code'] = ''
|
||||
module.params['disks'] = [] # Blank out disks since it will use the template
|
||||
else:
|
||||
return False, None
|
||||
|
||||
tags = module.params.get('tags')
|
||||
if isinstance(tags, list):
|
||||
tags = ','.join(map(str, module.params.get('tags')))
|
||||
|
||||
instance = vsManager.create_instance(
|
||||
hostname = module.params.get('hostname'),
|
||||
domain = module.params.get('domain'),
|
||||
cpus = module.params.get('cpus'),
|
||||
memory = module.params.get('memory'),
|
||||
hourly = module.params.get('hourly'),
|
||||
datacenter = module.params.get('datacenter'),
|
||||
os_code = module.params.get('os_code'),
|
||||
image_id = module.params.get('image_id'),
|
||||
local_disk = module.params.get('local_disk'),
|
||||
disks = module.params.get('disks'),
|
||||
ssh_keys = module.params.get('ssh_keys'),
|
||||
nic_speed = module.params.get('nic_speed'),
|
||||
private = module.params.get('private'),
|
||||
public_vlan = module.params.get('public_vlan'),
|
||||
private_vlan = module.params.get('private_vlan'),
|
||||
dedicated = module.params.get('dedicated'),
|
||||
post_uri = module.params.get('post_uri'),
|
||||
tags = tags)
|
||||
|
||||
if instance != None and instance['id'] > 0:
|
||||
return True, instance
|
||||
else:
|
||||
return False, None
|
||||
|
||||
|
||||
def wait_for_instance(module,id):
|
||||
instance = None
|
||||
completed = False
|
||||
wait_timeout = time.time() + module.params.get('wait_time')
|
||||
while not completed and wait_timeout > time.time():
|
||||
try:
|
||||
completed = vsManager.wait_for_ready(id, 10, 2)
|
||||
if completed:
|
||||
instance = vsManager.get_instance(id)
|
||||
except:
|
||||
completed = False
|
||||
|
||||
return completed, instance
|
||||
|
||||
|
||||
def cancel_instance(module):
|
||||
canceled = True
|
||||
if module.params.get('instance_id') == None and (module.params.get('tags') or module.params.get('hostname') or module.params.get('domain')):
|
||||
tags = module.params.get('tags')
|
||||
if isinstance(tags, basestring):
|
||||
tags = [module.params.get('tags')]
|
||||
instances = vsManager.list_instances(tags = tags, hostname = module.params.get('hostname'), domain = module.params.get('domain'))
|
||||
for instance in instances:
|
||||
try:
|
||||
vsManager.cancel_instance(instance['id'])
|
||||
except:
|
||||
canceled = False
|
||||
elif module.params.get('instance_id') and module.params.get('instance_id') != 0:
|
||||
try:
|
||||
vsManager.cancel_instance(instance['id'])
|
||||
except:
|
||||
canceled = False
|
||||
else:
|
||||
return False, None
|
||||
|
||||
return canceled, None
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
instance_id=dict(),
|
||||
hostname=dict(),
|
||||
domain=dict(),
|
||||
datacenter=dict(choices=DATACENTERS),
|
||||
tags=dict(),
|
||||
hourly=dict(type='bool', default=True),
|
||||
private=dict(type='bool', default=False),
|
||||
dedicated=dict(type='bool', default=False),
|
||||
local_disk=dict(type='bool', default=True),
|
||||
cpus=dict(type='int', choices=CPU_SIZES),
|
||||
memory=dict(type='int', choices=MEMORY_SIZES),
|
||||
disks=dict(type='list', default=[25]),
|
||||
os_code=dict(),
|
||||
image_id=dict(),
|
||||
nic_speed=dict(type='int', choices=NIC_SPEEDS),
|
||||
public_vlan=dict(),
|
||||
private_vlan=dict(),
|
||||
ssh_keys=dict(type='list', default=[]),
|
||||
post_uri=dict(),
|
||||
state=dict(default='present', choices=STATES),
|
||||
wait=dict(type='bool', default=True),
|
||||
wait_time=dict(type='int', default=600)
|
||||
)
|
||||
)
|
||||
|
||||
if not HAS_SL:
|
||||
module.fail_json(msg='softlayer python library required for this module')
|
||||
|
||||
if module.params.get('state') == 'absent':
|
||||
(changed, instance) = cancel_instance(module)
|
||||
|
||||
elif module.params.get('state') == 'present':
|
||||
(changed, instance) = create_virtual_instance(module)
|
||||
if module.params.get('wait') == True:
|
||||
(changed, instance) = wait_for_instance(module, instance['id'])
|
||||
|
||||
module.exit_json(changed=changed, instance=json.loads(json.dumps(instance, default=lambda o: o.__dict__)))
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue