1#!/usr/local/bin/python3.8 2# -*- coding: utf-8 -*- 3# Copyright: Ansible Project 4# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 6from __future__ import absolute_import, division, print_function 7__metaclass__ = type 8 9 10DOCUMENTATION = ''' 11--- 12module: profitbricks_datacenter 13short_description: Create or destroy a ProfitBricks Virtual Datacenter. 14description: 15 - This is a simple module that supports creating or removing vDCs. A vDC is required before you can create servers. This module has a dependency 16 on profitbricks >= 1.0.0 17options: 18 name: 19 description: 20 - The name of the virtual datacenter. 21 type: str 22 description: 23 description: 24 - The description of the virtual datacenter. 25 type: str 26 required: false 27 location: 28 description: 29 - The datacenter location. 30 type: str 31 required: false 32 default: us/las 33 choices: [ "us/las", "de/fra", "de/fkb" ] 34 subscription_user: 35 description: 36 - The ProfitBricks username. Overrides the PB_SUBSCRIPTION_ID environment variable. 37 type: str 38 required: false 39 subscription_password: 40 description: 41 - THe ProfitBricks password. Overrides the PB_PASSWORD environment variable. 42 type: str 43 required: false 44 wait: 45 description: 46 - wait for the datacenter to be created before returning 47 required: false 48 default: "yes" 49 type: bool 50 wait_timeout: 51 description: 52 - how long before wait gives up, in seconds 53 type: int 54 default: 600 55 state: 56 description: 57 - Create or terminate datacenters. 58 - "The available choices are: C(present), C(absent)." 59 type: str 60 required: false 61 default: 'present' 62 63requirements: [ "profitbricks" ] 64author: Matt Baldwin (@baldwinSPC) <baldwin@stackpointcloud.com> 65''' 66 67EXAMPLES = ''' 68- name: Create a datacenter 69 community.general.profitbricks_datacenter: 70 datacenter: Tardis One 71 wait_timeout: 500 72 73- name: Destroy a datacenter (remove all servers, volumes, and other objects in the datacenter) 74 community.general.profitbricks_datacenter: 75 datacenter: Tardis One 76 wait_timeout: 500 77 state: absent 78''' 79 80import re 81import time 82 83HAS_PB_SDK = True 84try: 85 from profitbricks.client import ProfitBricksService, Datacenter 86except ImportError: 87 HAS_PB_SDK = False 88 89from ansible.module_utils.basic import AnsibleModule 90 91 92LOCATIONS = ['us/las', 93 'de/fra', 94 'de/fkb'] 95 96uuid_match = re.compile( 97 r'[\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}', re.I) 98 99 100def _wait_for_completion(profitbricks, promise, wait_timeout, msg): 101 if not promise: 102 return 103 wait_timeout = time.time() + wait_timeout 104 while wait_timeout > time.time(): 105 time.sleep(5) 106 operation_result = profitbricks.get_request( 107 request_id=promise['requestId'], 108 status=True) 109 110 if operation_result['metadata']['status'] == "DONE": 111 return 112 elif operation_result['metadata']['status'] == "FAILED": 113 raise Exception( 114 'Request failed to complete ' + msg + ' "' + str( 115 promise['requestId']) + '" to complete.') 116 117 raise Exception( 118 'Timed out waiting for async operation ' + msg + ' "' + str( 119 promise['requestId'] 120 ) + '" to complete.') 121 122 123def _remove_datacenter(module, profitbricks, datacenter): 124 try: 125 profitbricks.delete_datacenter(datacenter) 126 except Exception as e: 127 module.fail_json(msg="failed to remove the datacenter: %s" % str(e)) 128 129 130def create_datacenter(module, profitbricks): 131 """ 132 Creates a Datacenter 133 134 This will create a new Datacenter in the specified location. 135 136 module : AnsibleModule object 137 profitbricks: authenticated profitbricks object. 138 139 Returns: 140 True if a new datacenter was created, false otherwise 141 """ 142 name = module.params.get('name') 143 location = module.params.get('location') 144 description = module.params.get('description') 145 wait = module.params.get('wait') 146 wait_timeout = int(module.params.get('wait_timeout')) 147 148 i = Datacenter( 149 name=name, 150 location=location, 151 description=description 152 ) 153 154 try: 155 datacenter_response = profitbricks.create_datacenter(datacenter=i) 156 157 if wait: 158 _wait_for_completion(profitbricks, datacenter_response, 159 wait_timeout, "_create_datacenter") 160 161 results = { 162 'datacenter_id': datacenter_response['id'] 163 } 164 165 return results 166 167 except Exception as e: 168 module.fail_json(msg="failed to create the new datacenter: %s" % str(e)) 169 170 171def remove_datacenter(module, profitbricks): 172 """ 173 Removes a Datacenter. 174 175 This will remove a datacenter. 176 177 module : AnsibleModule object 178 profitbricks: authenticated profitbricks object. 179 180 Returns: 181 True if the datacenter was deleted, false otherwise 182 """ 183 name = module.params.get('name') 184 changed = False 185 186 if(uuid_match.match(name)): 187 _remove_datacenter(module, profitbricks, name) 188 changed = True 189 else: 190 datacenters = profitbricks.list_datacenters() 191 192 for d in datacenters['items']: 193 vdc = profitbricks.get_datacenter(d['id']) 194 195 if name == vdc['properties']['name']: 196 name = d['id'] 197 _remove_datacenter(module, profitbricks, name) 198 changed = True 199 200 return changed 201 202 203def main(): 204 module = AnsibleModule( 205 argument_spec=dict( 206 name=dict(), 207 description=dict(), 208 location=dict(choices=LOCATIONS, default='us/las'), 209 subscription_user=dict(), 210 subscription_password=dict(no_log=True), 211 wait=dict(type='bool', default=True), 212 wait_timeout=dict(default=600, type='int'), 213 state=dict(default='present'), # @TODO add choices 214 ) 215 ) 216 if not HAS_PB_SDK: 217 module.fail_json(msg='profitbricks required for this module') 218 219 if not module.params.get('subscription_user'): 220 module.fail_json(msg='subscription_user parameter is required') 221 if not module.params.get('subscription_password'): 222 module.fail_json(msg='subscription_password parameter is required') 223 224 subscription_user = module.params.get('subscription_user') 225 subscription_password = module.params.get('subscription_password') 226 227 profitbricks = ProfitBricksService( 228 username=subscription_user, 229 password=subscription_password) 230 231 state = module.params.get('state') 232 233 if state == 'absent': 234 if not module.params.get('name'): 235 module.fail_json(msg='name parameter is required deleting a virtual datacenter.') 236 237 try: 238 (changed) = remove_datacenter(module, profitbricks) 239 module.exit_json( 240 changed=changed) 241 except Exception as e: 242 module.fail_json(msg='failed to set datacenter state: %s' % str(e)) 243 244 elif state == 'present': 245 if not module.params.get('name'): 246 module.fail_json(msg='name parameter is required for a new datacenter') 247 if not module.params.get('location'): 248 module.fail_json(msg='location parameter is required for a new datacenter') 249 250 try: 251 (datacenter_dict_array) = create_datacenter(module, profitbricks) 252 module.exit_json(**datacenter_dict_array) 253 except Exception as e: 254 module.fail_json(msg='failed to set datacenter state: %s' % str(e)) 255 256 257if __name__ == '__main__': 258 main() 259