mirror of
				https://github.com/ansible-collections/community.general.git
				synced 2025-10-26 05:50:36 -07:00 
			
		
		
		
	Add more semantic markup (#6744)
Add more semantic markup.
(cherry picked from commit 13e9e4b196)
Co-authored-by: Felix Fontein <felix@fontein.de>
		
	
			
		
			
				
	
	
		
			439 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			439 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/python
 | |
| # -*- coding: utf-8 -*-
 | |
| 
 | |
| # Copyright (c) 2017, Ansible Project
 | |
| # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
 | |
| # SPDX-License-Identifier: GPL-3.0-or-later
 | |
| 
 | |
| from __future__ import absolute_import, division, print_function
 | |
| __metaclass__ = type
 | |
| 
 | |
| DOCUMENTATION = '''
 | |
| ---
 | |
| module: sl_vm
 | |
| 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'.
 | |
| extends_documentation_fragment:
 | |
|   - community.general.attributes
 | |
| attributes:
 | |
|   check_mode:
 | |
|     support: none
 | |
|   diff_mode:
 | |
|     support: none
 | |
| options:
 | |
|   instance_id:
 | |
|     description:
 | |
|       - Instance Id of the virtual instance to perform action option.
 | |
|     type: str
 | |
|   hostname:
 | |
|     description:
 | |
|       - Hostname to be provided to a virtual instance.
 | |
|     type: str
 | |
|   domain:
 | |
|     description:
 | |
|       - Domain name to be provided to a virtual instance.
 | |
|     type: str
 | |
|   datacenter:
 | |
|     description:
 | |
|       - Datacenter for the virtual instance to be deployed.
 | |
|     type: str
 | |
|     choices:
 | |
|       - ams01
 | |
|       - ams03
 | |
|       - che01
 | |
|       - dal01
 | |
|       - dal05
 | |
|       - dal06
 | |
|       - dal09
 | |
|       - dal10
 | |
|       - dal12
 | |
|       - dal13
 | |
|       - fra02
 | |
|       - fra04
 | |
|       - fra05
 | |
|       - hkg02
 | |
|       - hou02
 | |
|       - lon02
 | |
|       - lon04
 | |
|       - lon06
 | |
|       - mel01
 | |
|       - mex01
 | |
|       - mil01
 | |
|       - mon01
 | |
|       - osl01
 | |
|       - par01
 | |
|       - sao01
 | |
|       - sea01
 | |
|       - seo01
 | |
|       - sjc01
 | |
|       - sjc03
 | |
|       - sjc04
 | |
|       - sng01
 | |
|       - syd01
 | |
|       - syd04
 | |
|       - tok02
 | |
|       - tor01
 | |
|       - wdc01
 | |
|       - wdc04
 | |
|       - wdc06
 | |
|       - wdc07
 | |
|   tags:
 | |
|     description:
 | |
|       - Tag or list of tags to be provided to a virtual instance.
 | |
|     type: str
 | |
|   hourly:
 | |
|     description:
 | |
|       - Flag to determine if the instance should be hourly billed.
 | |
|     type: bool
 | |
|     default: true
 | |
|   private:
 | |
|     description:
 | |
|       - Flag to determine if the instance should be private only.
 | |
|     type: bool
 | |
|     default: false
 | |
|   dedicated:
 | |
|     description:
 | |
|       - Flag to determine if the instance should be deployed in dedicated space.
 | |
|     type: bool
 | |
|     default: false
 | |
|   local_disk:
 | |
|     description:
 | |
|       - Flag to determine if local disk should be used for the new instance.
 | |
|     type: bool
 | |
|     default: true
 | |
|   cpus:
 | |
|     description:
 | |
|       - Count of cpus to be assigned to new virtual instance.
 | |
|     type: int
 | |
|     choices: [1, 2, 4, 8, 16, 32, 56]
 | |
|   memory:
 | |
|     description:
 | |
|       - Amount of memory to be assigned to new virtual instance.
 | |
|     type: int
 | |
|     choices: [1024, 2048, 4096, 6144, 8192, 12288, 16384, 32768, 49152, 65536, 131072, 247808]
 | |
|   flavor:
 | |
|     description:
 | |
|       - Specify which SoftLayer flavor template to use instead of cpus and memory.
 | |
|     version_added: '0.2.0'
 | |
|     type: str
 | |
|   disks:
 | |
|     description:
 | |
|       - List of disk sizes to be assigned to new virtual instance.
 | |
|     default: [ 25 ]
 | |
|     type: list
 | |
|     elements: int
 | |
|   os_code:
 | |
|     description:
 | |
|       - OS Code to be used for new virtual instance.
 | |
|     type: str
 | |
|   image_id:
 | |
|     description:
 | |
|       - Image Template to be used for new virtual instance.
 | |
|     type: str
 | |
|   nic_speed:
 | |
|     description:
 | |
|       - NIC Speed to be assigned to new virtual instance.
 | |
|     choices: [10, 100, 1000]
 | |
|     type: int
 | |
|   public_vlan:
 | |
|     description:
 | |
|       - VLAN by its Id to be assigned to the public NIC.
 | |
|     type: str
 | |
|   private_vlan:
 | |
|     description:
 | |
|       - VLAN by its Id to be assigned to the private NIC.
 | |
|     type: str
 | |
|   ssh_keys:
 | |
|     description:
 | |
|       - List of ssh keys by their Id to be assigned to a virtual instance.
 | |
|     type: list
 | |
|     elements: str
 | |
|     default: []
 | |
|   post_uri:
 | |
|     description:
 | |
|       - URL of a post provisioning script to be loaded and executed on virtual instance.
 | |
|     type: str
 | |
|   state:
 | |
|     description:
 | |
|       - Create, or cancel a virtual instance.
 | |
|       - Specify V(present) for create, V(absent) to cancel.
 | |
|     choices: [ absent, present ]
 | |
|     default: present
 | |
|     type: str
 | |
|   wait:
 | |
|     description:
 | |
|       - Flag used to wait for active status before returning.
 | |
|     type: bool
 | |
|     default: true
 | |
|   wait_time:
 | |
|     description:
 | |
|       - Time in seconds before wait returns.
 | |
|     default: 600
 | |
|     type: int
 | |
| 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
 | |
|     community.general.sl_vm:
 | |
|       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
 | |
|     community.general.sl_vm:
 | |
|       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-replicas
 | |
|         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-replicas
 | |
|         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
 | |
|     community.general.sl_vm:
 | |
|       state: absent
 | |
|       tags: ansible-module-test
 | |
| '''
 | |
| 
 | |
| # TODO: Disabled RETURN as it is breaking the build for docs. Needs to be fixed.
 | |
| RETURN = '''# '''
 | |
| 
 | |
| import json
 | |
| import time
 | |
| 
 | |
| try:
 | |
|     import SoftLayer
 | |
|     from SoftLayer import VSManager
 | |
| 
 | |
|     HAS_SL = True
 | |
|     vsManager = VSManager(SoftLayer.create_client_from_env())
 | |
| except ImportError:
 | |
|     HAS_SL = False
 | |
| 
 | |
| from ansible.module_utils.basic import AnsibleModule
 | |
| from ansible.module_utils.six import string_types
 | |
| 
 | |
| 
 | |
| # TODO: get this info from API
 | |
| STATES = ['present', 'absent']
 | |
| DATACENTERS = ['ams01', 'ams03', 'che01', 'dal01', 'dal05', 'dal06', 'dal09', 'dal10', 'dal12', 'dal13', 'fra02',
 | |
|                'fra04', 'fra05', 'hkg02', 'hou02', 'lon02', 'lon04', 'lon06', 'mel01', 'mex01', 'mil01', 'mon01',
 | |
|                'osl01', 'par01', 'sao01', 'sea01', 'seo01', 'sjc01', 'sjc03', 'sjc04', 'sng01', 'syd01', 'syd04',
 | |
|                'tok02', 'tor01', 'wdc01', 'wdc04', 'wdc06', 'wdc07']
 | |
| CPU_SIZES = [1, 2, 4, 8, 16, 32, 56]
 | |
| MEMORY_SIZES = [1024, 2048, 4096, 6144, 8192, 12288, 16384, 32768, 49152, 65536, 131072, 247808]
 | |
| 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]
 | |
| 
 | |
| 
 | |
| def create_virtual_instance(module):
 | |
| 
 | |
|     instances = vsManager.list_instances(
 | |
|         hostname=module.params.get('hostname'),
 | |
|         domain=module.params.get('domain'),
 | |
|         datacenter=module.params.get('datacenter')
 | |
|     )
 | |
| 
 | |
|     if instances:
 | |
|         return False, None
 | |
| 
 | |
|     # Check if OS or Image Template is provided (Can't be both, defaults to OS)
 | |
|     if (module.params.get('os_code') is not None and module.params.get('os_code') != ''):
 | |
|         module.params['image_id'] = ''
 | |
|     elif (module.params.get('image_id') is not 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'),
 | |
|         flavor=module.params.get('flavor'),
 | |
|         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 is not 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 Exception:
 | |
|             completed = False
 | |
| 
 | |
|     return completed, instance
 | |
| 
 | |
| 
 | |
| def cancel_instance(module):
 | |
|     canceled = True
 | |
|     if module.params.get('instance_id') is None and (module.params.get('tags') or module.params.get('hostname') or module.params.get('domain')):
 | |
|         tags = module.params.get('tags')
 | |
|         if isinstance(tags, string_types):
 | |
|             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 Exception:
 | |
|                 canceled = False
 | |
|     elif module.params.get('instance_id') and module.params.get('instance_id') != 0:
 | |
|         try:
 | |
|             vsManager.cancel_instance(instance['id'])
 | |
|         except Exception:
 | |
|             canceled = False
 | |
|     else:
 | |
|         return False, None
 | |
| 
 | |
|     return canceled, None
 | |
| 
 | |
| 
 | |
| def main():
 | |
| 
 | |
|     module = AnsibleModule(
 | |
|         argument_spec=dict(
 | |
|             instance_id=dict(type='str'),
 | |
|             hostname=dict(type='str'),
 | |
|             domain=dict(type='str'),
 | |
|             datacenter=dict(type='str', choices=DATACENTERS),
 | |
|             tags=dict(type='str'),
 | |
|             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),
 | |
|             flavor=dict(type='str'),
 | |
|             disks=dict(type='list', elements='int', default=[25]),
 | |
|             os_code=dict(type='str'),
 | |
|             image_id=dict(type='str'),
 | |
|             nic_speed=dict(type='int', choices=NIC_SPEEDS),
 | |
|             public_vlan=dict(type='str'),
 | |
|             private_vlan=dict(type='str'),
 | |
|             ssh_keys=dict(type='list', elements='str', default=[], no_log=False),
 | |
|             post_uri=dict(type='str'),
 | |
|             state=dict(type='str', 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') is True and instance:
 | |
|             (changed, instance) = wait_for_instance(module, instance['id'])
 | |
| 
 | |
|     module.exit_json(changed=changed, instance=json.loads(json.dumps(instance, default=lambda o: o.__dict__)))
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     main()
 |