mirror of
				https://github.com/ansible-collections/community.general.git
				synced 2025-10-25 13:34:01 -07:00 
			
		
		
		
	
		
			
				
	
	
		
			975 lines
		
	
	
	
		
			34 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			975 lines
		
	
	
	
		
			34 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/python
 | |
| # -*- coding: utf-8 -*-
 | |
| #
 | |
| # Copyright (c) 2015 CenturyLink
 | |
| # 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: clc_modify_server
 | |
| short_description: Modify servers in CenturyLink Cloud
 | |
| description:
 | |
|   - An Ansible module to modify servers in CenturyLink Cloud.
 | |
| extends_documentation_fragment:
 | |
|   - community.general.attributes
 | |
| attributes:
 | |
|   check_mode:
 | |
|     support: full
 | |
|   diff_mode:
 | |
|     support: none
 | |
| options:
 | |
|   server_ids:
 | |
|     description:
 | |
|       - A list of server Ids to modify.
 | |
|     type: list
 | |
|     required: true
 | |
|     elements: str
 | |
|   cpu:
 | |
|     description:
 | |
|       - How many CPUs to update on the server
 | |
|     type: str
 | |
|   memory:
 | |
|     description:
 | |
|       - Memory (in GB) to set to the server.
 | |
|     type: str
 | |
|   anti_affinity_policy_id:
 | |
|     description:
 | |
|       - The anti affinity policy id to be set for a hyper scale server.
 | |
|         This is mutually exclusive with 'anti_affinity_policy_name'
 | |
|     type: str
 | |
|   anti_affinity_policy_name:
 | |
|     description:
 | |
|       - The anti affinity policy name to be set for a hyper scale server.
 | |
|         This is mutually exclusive with 'anti_affinity_policy_id'
 | |
|     type: str
 | |
|   alert_policy_id:
 | |
|     description:
 | |
|       - The alert policy id to be associated to the server.
 | |
|         This is mutually exclusive with 'alert_policy_name'
 | |
|     type: str
 | |
|   alert_policy_name:
 | |
|     description:
 | |
|       - The alert policy name to be associated to the server.
 | |
|         This is mutually exclusive with 'alert_policy_id'
 | |
|     type: str
 | |
|   state:
 | |
|     description:
 | |
|       - The state to insure that the provided resources are in.
 | |
|     type: str
 | |
|     default: 'present'
 | |
|     choices: ['present', 'absent']
 | |
|   wait:
 | |
|     description:
 | |
|       - Whether to wait for the provisioning tasks to finish before returning.
 | |
|     type: bool
 | |
|     default: true
 | |
| requirements:
 | |
|     - python = 2.7
 | |
|     - requests >= 2.5.0
 | |
|     - clc-sdk
 | |
| author: "CLC Runner (@clc-runner)"
 | |
| notes:
 | |
|     - To use this module, it is required to set the below environment variables which enables access to the
 | |
|       Centurylink Cloud
 | |
|           - CLC_V2_API_USERNAME, the account login id for the centurylink cloud
 | |
|           - CLC_V2_API_PASSWORD, the account password for the centurylink cloud
 | |
|     - Alternatively, the module accepts the API token and account alias. The API token can be generated using the
 | |
|       CLC account login and password via the HTTP api call @ https://api.ctl.io/v2/authentication/login
 | |
|           - CLC_V2_API_TOKEN, the API token generated from https://api.ctl.io/v2/authentication/login
 | |
|           - CLC_ACCT_ALIAS, the account alias associated with the centurylink cloud
 | |
|     - Users can set CLC_V2_API_URL to specify an endpoint for pointing to a different CLC environment.
 | |
| '''
 | |
| 
 | |
| EXAMPLES = '''
 | |
| # Note - You must set the CLC_V2_API_USERNAME And CLC_V2_API_PASSWD Environment variables before running these examples
 | |
| 
 | |
| - name: Set the cpu count to 4 on a server
 | |
|   community.general.clc_modify_server:
 | |
|     server_ids:
 | |
|         - UC1TESTSVR01
 | |
|         - UC1TESTSVR02
 | |
|     cpu: 4
 | |
|     state: present
 | |
| 
 | |
| - name: Set the memory to 8GB on a server
 | |
|   community.general.clc_modify_server:
 | |
|     server_ids:
 | |
|         - UC1TESTSVR01
 | |
|         - UC1TESTSVR02
 | |
|     memory: 8
 | |
|     state: present
 | |
| 
 | |
| - name: Set the anti affinity policy on a server
 | |
|   community.general.clc_modify_server:
 | |
|     server_ids:
 | |
|         - UC1TESTSVR01
 | |
|         - UC1TESTSVR02
 | |
|     anti_affinity_policy_name: 'aa_policy'
 | |
|     state: present
 | |
| 
 | |
| - name: Remove the anti affinity policy on a server
 | |
|   community.general.clc_modify_server:
 | |
|     server_ids:
 | |
|         - UC1TESTSVR01
 | |
|         - UC1TESTSVR02
 | |
|     anti_affinity_policy_name: 'aa_policy'
 | |
|     state: absent
 | |
| 
 | |
| - name: Add the alert policy on a server
 | |
|   community.general.clc_modify_server:
 | |
|     server_ids:
 | |
|         - UC1TESTSVR01
 | |
|         - UC1TESTSVR02
 | |
|     alert_policy_name: 'alert_policy'
 | |
|     state: present
 | |
| 
 | |
| - name: Remove the alert policy on a server
 | |
|   community.general.clc_modify_server:
 | |
|     server_ids:
 | |
|         - UC1TESTSVR01
 | |
|         - UC1TESTSVR02
 | |
|     alert_policy_name: 'alert_policy'
 | |
|     state: absent
 | |
| 
 | |
| - name: Ret the memory to 16GB and cpu to 8 core on a lust if servers
 | |
|   community.general.clc_modify_server:
 | |
|     server_ids:
 | |
|         - UC1TESTSVR01
 | |
|         - UC1TESTSVR02
 | |
|     cpu: 8
 | |
|     memory: 16
 | |
|     state: present
 | |
| '''
 | |
| 
 | |
| RETURN = '''
 | |
| server_ids:
 | |
|     description: The list of server ids that are changed
 | |
|     returned: success
 | |
|     type: list
 | |
|     sample:
 | |
|         [
 | |
|             "UC1TEST-SVR01",
 | |
|             "UC1TEST-SVR02"
 | |
|         ]
 | |
| servers:
 | |
|     description: The list of server objects that are changed
 | |
|     returned: success
 | |
|     type: list
 | |
|     sample:
 | |
|         [
 | |
|            {
 | |
|               "changeInfo":{
 | |
|                  "createdBy":"service.wfad",
 | |
|                  "createdDate":1438196820,
 | |
|                  "modifiedBy":"service.wfad",
 | |
|                  "modifiedDate":1438196820
 | |
|               },
 | |
|               "description":"test-server",
 | |
|               "details":{
 | |
|                  "alertPolicies":[
 | |
| 
 | |
|                  ],
 | |
|                  "cpu":1,
 | |
|                  "customFields":[
 | |
| 
 | |
|                  ],
 | |
|                  "diskCount":3,
 | |
|                  "disks":[
 | |
|                     {
 | |
|                        "id":"0:0",
 | |
|                        "partitionPaths":[
 | |
| 
 | |
|                        ],
 | |
|                        "sizeGB":1
 | |
|                     },
 | |
|                     {
 | |
|                        "id":"0:1",
 | |
|                        "partitionPaths":[
 | |
| 
 | |
|                        ],
 | |
|                        "sizeGB":2
 | |
|                     },
 | |
|                     {
 | |
|                        "id":"0:2",
 | |
|                        "partitionPaths":[
 | |
| 
 | |
|                        ],
 | |
|                        "sizeGB":14
 | |
|                     }
 | |
|                  ],
 | |
|                  "hostName":"",
 | |
|                  "inMaintenanceMode":false,
 | |
|                  "ipAddresses":[
 | |
|                     {
 | |
|                        "internal":"10.1.1.1"
 | |
|                     }
 | |
|                  ],
 | |
|                  "memoryGB":1,
 | |
|                  "memoryMB":1024,
 | |
|                  "partitions":[
 | |
| 
 | |
|                  ],
 | |
|                  "powerState":"started",
 | |
|                  "snapshots":[
 | |
| 
 | |
|                  ],
 | |
|                  "storageGB":17
 | |
|               },
 | |
|               "groupId":"086ac1dfe0b6411989e8d1b77c4065f0",
 | |
|               "id":"test-server",
 | |
|               "ipaddress":"10.120.45.23",
 | |
|               "isTemplate":false,
 | |
|               "links":[
 | |
|                  {
 | |
|                     "href":"/v2/servers/wfad/test-server",
 | |
|                     "id":"test-server",
 | |
|                     "rel":"self",
 | |
|                     "verbs":[
 | |
|                        "GET",
 | |
|                        "PATCH",
 | |
|                        "DELETE"
 | |
|                     ]
 | |
|                  },
 | |
|                  {
 | |
|                     "href":"/v2/groups/wfad/086ac1dfe0b6411989e8d1b77c4065f0",
 | |
|                     "id":"086ac1dfe0b6411989e8d1b77c4065f0",
 | |
|                     "rel":"group"
 | |
|                  },
 | |
|                  {
 | |
|                     "href":"/v2/accounts/wfad",
 | |
|                     "id":"wfad",
 | |
|                     "rel":"account"
 | |
|                  },
 | |
|                  {
 | |
|                     "href":"/v2/billing/wfad/serverPricing/test-server",
 | |
|                     "rel":"billing"
 | |
|                  },
 | |
|                  {
 | |
|                     "href":"/v2/servers/wfad/test-server/publicIPAddresses",
 | |
|                     "rel":"publicIPAddresses",
 | |
|                     "verbs":[
 | |
|                        "POST"
 | |
|                     ]
 | |
|                  },
 | |
|                  {
 | |
|                     "href":"/v2/servers/wfad/test-server/credentials",
 | |
|                     "rel":"credentials"
 | |
|                  },
 | |
|                  {
 | |
|                     "href":"/v2/servers/wfad/test-server/statistics",
 | |
|                     "rel":"statistics"
 | |
|                  },
 | |
|                  {
 | |
|                     "href":"/v2/servers/wfad/510ec21ae82d4dc89d28479753bf736a/upcomingScheduledActivities",
 | |
|                     "rel":"upcomingScheduledActivities"
 | |
|                  },
 | |
|                  {
 | |
|                     "href":"/v2/servers/wfad/510ec21ae82d4dc89d28479753bf736a/scheduledActivities",
 | |
|                     "rel":"scheduledActivities",
 | |
|                     "verbs":[
 | |
|                        "GET",
 | |
|                        "POST"
 | |
|                     ]
 | |
|                  },
 | |
|                  {
 | |
|                     "href":"/v2/servers/wfad/test-server/capabilities",
 | |
|                     "rel":"capabilities"
 | |
|                  },
 | |
|                  {
 | |
|                     "href":"/v2/servers/wfad/test-server/alertPolicies",
 | |
|                     "rel":"alertPolicyMappings",
 | |
|                     "verbs":[
 | |
|                        "POST"
 | |
|                     ]
 | |
|                  },
 | |
|                  {
 | |
|                     "href":"/v2/servers/wfad/test-server/antiAffinityPolicy",
 | |
|                     "rel":"antiAffinityPolicyMapping",
 | |
|                     "verbs":[
 | |
|                        "PUT",
 | |
|                        "DELETE"
 | |
|                     ]
 | |
|                  },
 | |
|                  {
 | |
|                     "href":"/v2/servers/wfad/test-server/cpuAutoscalePolicy",
 | |
|                     "rel":"cpuAutoscalePolicyMapping",
 | |
|                     "verbs":[
 | |
|                        "PUT",
 | |
|                        "DELETE"
 | |
|                     ]
 | |
|                  }
 | |
|               ],
 | |
|               "locationId":"UC1",
 | |
|               "name":"test-server",
 | |
|               "os":"ubuntu14_64Bit",
 | |
|               "osType":"Ubuntu 14 64-bit",
 | |
|               "status":"active",
 | |
|               "storageType":"standard",
 | |
|               "type":"standard"
 | |
|            }
 | |
|         ]
 | |
| '''
 | |
| 
 | |
| __version__ = '${version}'
 | |
| 
 | |
| import json
 | |
| import os
 | |
| import traceback
 | |
| 
 | |
| from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
 | |
| 
 | |
| REQUESTS_IMP_ERR = None
 | |
| try:
 | |
|     import requests
 | |
| except ImportError:
 | |
|     REQUESTS_IMP_ERR = traceback.format_exc()
 | |
|     REQUESTS_FOUND = False
 | |
| else:
 | |
|     REQUESTS_FOUND = True
 | |
| 
 | |
| #
 | |
| #  Requires the clc-python-sdk.
 | |
| #  sudo pip install clc-sdk
 | |
| #
 | |
| CLC_IMP_ERR = None
 | |
| try:
 | |
|     import clc as clc_sdk
 | |
|     from clc import CLCException
 | |
|     from clc import APIFailedResponse
 | |
| except ImportError:
 | |
|     CLC_IMP_ERR = traceback.format_exc()
 | |
|     CLC_FOUND = False
 | |
|     clc_sdk = None
 | |
| else:
 | |
|     CLC_FOUND = True
 | |
| 
 | |
| from ansible.module_utils.basic import AnsibleModule, missing_required_lib
 | |
| 
 | |
| 
 | |
| class ClcModifyServer:
 | |
|     clc = clc_sdk
 | |
| 
 | |
|     def __init__(self, module):
 | |
|         """
 | |
|         Construct module
 | |
|         """
 | |
|         self.clc = clc_sdk
 | |
|         self.module = module
 | |
| 
 | |
|         if not CLC_FOUND:
 | |
|             self.module.fail_json(msg=missing_required_lib('clc-sdk'), exception=CLC_IMP_ERR)
 | |
|         if not REQUESTS_FOUND:
 | |
|             self.module.fail_json(msg=missing_required_lib('requests'), exception=REQUESTS_IMP_ERR)
 | |
|         if requests.__version__ and LooseVersion(requests.__version__) < LooseVersion('2.5.0'):
 | |
|             self.module.fail_json(
 | |
|                 msg='requests library  version should be >= 2.5.0')
 | |
| 
 | |
|         self._set_user_agent(self.clc)
 | |
| 
 | |
|     def process_request(self):
 | |
|         """
 | |
|         Process the request - Main Code Path
 | |
|         :return: Returns with either an exit_json or fail_json
 | |
|         """
 | |
|         self._set_clc_credentials_from_env()
 | |
| 
 | |
|         p = self.module.params
 | |
|         cpu = p.get('cpu')
 | |
|         memory = p.get('memory')
 | |
|         state = p.get('state')
 | |
|         if state == 'absent' and (cpu or memory):
 | |
|             return self.module.fail_json(
 | |
|                 msg='\'absent\' state is not supported for \'cpu\' and \'memory\' arguments')
 | |
| 
 | |
|         server_ids = p['server_ids']
 | |
|         if not isinstance(server_ids, list):
 | |
|             return self.module.fail_json(
 | |
|                 msg='server_ids needs to be a list of instances to modify: %s' %
 | |
|                 server_ids)
 | |
| 
 | |
|         (changed, server_dict_array, changed_server_ids) = self._modify_servers(
 | |
|             server_ids=server_ids)
 | |
| 
 | |
|         self.module.exit_json(
 | |
|             changed=changed,
 | |
|             server_ids=changed_server_ids,
 | |
|             servers=server_dict_array)
 | |
| 
 | |
|     @staticmethod
 | |
|     def _define_module_argument_spec():
 | |
|         """
 | |
|         Define the argument spec for the ansible module
 | |
|         :return: argument spec dictionary
 | |
|         """
 | |
|         argument_spec = dict(
 | |
|             server_ids=dict(type='list', required=True, elements='str'),
 | |
|             state=dict(default='present', choices=['present', 'absent']),
 | |
|             cpu=dict(),
 | |
|             memory=dict(),
 | |
|             anti_affinity_policy_id=dict(),
 | |
|             anti_affinity_policy_name=dict(),
 | |
|             alert_policy_id=dict(),
 | |
|             alert_policy_name=dict(),
 | |
|             wait=dict(type='bool', default=True)
 | |
|         )
 | |
|         mutually_exclusive = [
 | |
|             ['anti_affinity_policy_id', 'anti_affinity_policy_name'],
 | |
|             ['alert_policy_id', 'alert_policy_name']
 | |
|         ]
 | |
|         return {"argument_spec": argument_spec,
 | |
|                 "mutually_exclusive": mutually_exclusive}
 | |
| 
 | |
|     def _set_clc_credentials_from_env(self):
 | |
|         """
 | |
|         Set the CLC Credentials on the sdk by reading environment variables
 | |
|         :return: none
 | |
|         """
 | |
|         env = os.environ
 | |
|         v2_api_token = env.get('CLC_V2_API_TOKEN', False)
 | |
|         v2_api_username = env.get('CLC_V2_API_USERNAME', False)
 | |
|         v2_api_passwd = env.get('CLC_V2_API_PASSWD', False)
 | |
|         clc_alias = env.get('CLC_ACCT_ALIAS', False)
 | |
|         api_url = env.get('CLC_V2_API_URL', False)
 | |
| 
 | |
|         if api_url:
 | |
|             self.clc.defaults.ENDPOINT_URL_V2 = api_url
 | |
| 
 | |
|         if v2_api_token and clc_alias:
 | |
|             self.clc._LOGIN_TOKEN_V2 = v2_api_token
 | |
|             self.clc._V2_ENABLED = True
 | |
|             self.clc.ALIAS = clc_alias
 | |
|         elif v2_api_username and v2_api_passwd:
 | |
|             self.clc.v2.SetCredentials(
 | |
|                 api_username=v2_api_username,
 | |
|                 api_passwd=v2_api_passwd)
 | |
|         else:
 | |
|             return self.module.fail_json(
 | |
|                 msg="You must set the CLC_V2_API_USERNAME and CLC_V2_API_PASSWD "
 | |
|                     "environment variables")
 | |
| 
 | |
|     def _get_servers_from_clc(self, server_list, message):
 | |
|         """
 | |
|         Internal function to fetch list of CLC server objects from a list of server ids
 | |
|         :param server_list: The list of server ids
 | |
|         :param message: the error message to throw in case of any error
 | |
|         :return the list of CLC server objects
 | |
|         """
 | |
|         try:
 | |
|             return self.clc.v2.Servers(server_list).servers
 | |
|         except CLCException as ex:
 | |
|             return self.module.fail_json(msg=message + ': %s' % ex.message)
 | |
| 
 | |
|     def _modify_servers(self, server_ids):
 | |
|         """
 | |
|         modify the servers configuration on the provided list
 | |
|         :param server_ids: list of servers to modify
 | |
|         :return: a list of dictionaries with server information about the servers that were modified
 | |
|         """
 | |
|         p = self.module.params
 | |
|         state = p.get('state')
 | |
|         server_params = {
 | |
|             'cpu': p.get('cpu'),
 | |
|             'memory': p.get('memory'),
 | |
|             'anti_affinity_policy_id': p.get('anti_affinity_policy_id'),
 | |
|             'anti_affinity_policy_name': p.get('anti_affinity_policy_name'),
 | |
|             'alert_policy_id': p.get('alert_policy_id'),
 | |
|             'alert_policy_name': p.get('alert_policy_name'),
 | |
|         }
 | |
|         changed = False
 | |
|         server_changed = False
 | |
|         aa_changed = False
 | |
|         ap_changed = False
 | |
|         server_dict_array = []
 | |
|         result_server_ids = []
 | |
|         request_list = []
 | |
|         changed_servers = []
 | |
| 
 | |
|         if not isinstance(server_ids, list) or len(server_ids) < 1:
 | |
|             return self.module.fail_json(
 | |
|                 msg='server_ids should be a list of servers, aborting')
 | |
| 
 | |
|         servers = self._get_servers_from_clc(
 | |
|             server_ids,
 | |
|             'Failed to obtain server list from the CLC API')
 | |
|         for server in servers:
 | |
|             if state == 'present':
 | |
|                 server_changed, server_result = self._ensure_server_config(
 | |
|                     server, server_params)
 | |
|                 if server_result:
 | |
|                     request_list.append(server_result)
 | |
|                 aa_changed = self._ensure_aa_policy_present(
 | |
|                     server,
 | |
|                     server_params)
 | |
|                 ap_changed = self._ensure_alert_policy_present(
 | |
|                     server,
 | |
|                     server_params)
 | |
|             elif state == 'absent':
 | |
|                 aa_changed = self._ensure_aa_policy_absent(
 | |
|                     server,
 | |
|                     server_params)
 | |
|                 ap_changed = self._ensure_alert_policy_absent(
 | |
|                     server,
 | |
|                     server_params)
 | |
|             if server_changed or aa_changed or ap_changed:
 | |
|                 changed_servers.append(server)
 | |
|                 changed = True
 | |
| 
 | |
|         self._wait_for_requests(self.module, request_list)
 | |
|         self._refresh_servers(self.module, changed_servers)
 | |
| 
 | |
|         for server in changed_servers:
 | |
|             server_dict_array.append(server.data)
 | |
|             result_server_ids.append(server.id)
 | |
| 
 | |
|         return changed, server_dict_array, result_server_ids
 | |
| 
 | |
|     def _ensure_server_config(
 | |
|             self, server, server_params):
 | |
|         """
 | |
|         ensures the server is updated with the provided cpu and memory
 | |
|         :param server: the CLC server object
 | |
|         :param server_params: the dictionary of server parameters
 | |
|         :return: (changed, group) -
 | |
|             changed: Boolean whether a change was made
 | |
|             result: The result from the CLC API call
 | |
|         """
 | |
|         cpu = server_params.get('cpu')
 | |
|         memory = server_params.get('memory')
 | |
|         changed = False
 | |
|         result = None
 | |
| 
 | |
|         if not cpu:
 | |
|             cpu = server.cpu
 | |
|         if not memory:
 | |
|             memory = server.memory
 | |
|         if memory != server.memory or cpu != server.cpu:
 | |
|             if not self.module.check_mode:
 | |
|                 result = self._modify_clc_server(
 | |
|                     self.clc,
 | |
|                     self.module,
 | |
|                     server.id,
 | |
|                     cpu,
 | |
|                     memory)
 | |
|             changed = True
 | |
|         return changed, result
 | |
| 
 | |
|     @staticmethod
 | |
|     def _modify_clc_server(clc, module, server_id, cpu, memory):
 | |
|         """
 | |
|         Modify the memory or CPU of a clc server.
 | |
|         :param clc: the clc-sdk instance to use
 | |
|         :param module: the AnsibleModule object
 | |
|         :param server_id: id of the server to modify
 | |
|         :param cpu: the new cpu value
 | |
|         :param memory: the new memory value
 | |
|         :return: the result of CLC API call
 | |
|         """
 | |
|         result = None
 | |
|         acct_alias = clc.v2.Account.GetAlias()
 | |
|         try:
 | |
|             # Update the server configuration
 | |
|             job_obj = clc.v2.API.Call('PATCH',
 | |
|                                       'servers/%s/%s' % (acct_alias,
 | |
|                                                          server_id),
 | |
|                                       json.dumps([{"op": "set",
 | |
|                                                    "member": "memory",
 | |
|                                                    "value": memory},
 | |
|                                                   {"op": "set",
 | |
|                                                    "member": "cpu",
 | |
|                                                    "value": cpu}]))
 | |
|             result = clc.v2.Requests(job_obj)
 | |
|         except APIFailedResponse as ex:
 | |
|             module.fail_json(
 | |
|                 msg='Unable to update the server configuration for server : "{0}". {1}'.format(
 | |
|                     server_id, str(ex.response_text)))
 | |
|         return result
 | |
| 
 | |
|     @staticmethod
 | |
|     def _wait_for_requests(module, request_list):
 | |
|         """
 | |
|         Block until server provisioning requests are completed.
 | |
|         :param module: the AnsibleModule object
 | |
|         :param request_list: a list of clc-sdk.Request instances
 | |
|         :return: none
 | |
|         """
 | |
|         wait = module.params.get('wait')
 | |
|         if wait:
 | |
|             # Requests.WaitUntilComplete() returns the count of failed requests
 | |
|             failed_requests_count = sum(
 | |
|                 [request.WaitUntilComplete() for request in request_list])
 | |
| 
 | |
|             if failed_requests_count > 0:
 | |
|                 module.fail_json(
 | |
|                     msg='Unable to process modify server request')
 | |
| 
 | |
|     @staticmethod
 | |
|     def _refresh_servers(module, servers):
 | |
|         """
 | |
|         Loop through a list of servers and refresh them.
 | |
|         :param module: the AnsibleModule object
 | |
|         :param servers: list of clc-sdk.Server instances to refresh
 | |
|         :return: none
 | |
|         """
 | |
|         for server in servers:
 | |
|             try:
 | |
|                 server.Refresh()
 | |
|             except CLCException as ex:
 | |
|                 module.fail_json(msg='Unable to refresh the server {0}. {1}'.format(
 | |
|                     server.id, ex.message
 | |
|                 ))
 | |
| 
 | |
|     def _ensure_aa_policy_present(
 | |
|             self, server, server_params):
 | |
|         """
 | |
|         ensures the server is updated with the provided anti affinity policy
 | |
|         :param server: the CLC server object
 | |
|         :param server_params: the dictionary of server parameters
 | |
|         :return: (changed, group) -
 | |
|             changed: Boolean whether a change was made
 | |
|             result: The result from the CLC API call
 | |
|         """
 | |
|         changed = False
 | |
|         acct_alias = self.clc.v2.Account.GetAlias()
 | |
| 
 | |
|         aa_policy_id = server_params.get('anti_affinity_policy_id')
 | |
|         aa_policy_name = server_params.get('anti_affinity_policy_name')
 | |
|         if not aa_policy_id and aa_policy_name:
 | |
|             aa_policy_id = self._get_aa_policy_id_by_name(
 | |
|                 self.clc,
 | |
|                 self.module,
 | |
|                 acct_alias,
 | |
|                 aa_policy_name)
 | |
|         current_aa_policy_id = self._get_aa_policy_id_of_server(
 | |
|             self.clc,
 | |
|             self.module,
 | |
|             acct_alias,
 | |
|             server.id)
 | |
| 
 | |
|         if aa_policy_id and aa_policy_id != current_aa_policy_id:
 | |
|             self._modify_aa_policy(
 | |
|                 self.clc,
 | |
|                 self.module,
 | |
|                 acct_alias,
 | |
|                 server.id,
 | |
|                 aa_policy_id)
 | |
|             changed = True
 | |
|         return changed
 | |
| 
 | |
|     def _ensure_aa_policy_absent(
 | |
|             self, server, server_params):
 | |
|         """
 | |
|         ensures the provided anti affinity policy is removed from the server
 | |
|         :param server: the CLC server object
 | |
|         :param server_params: the dictionary of server parameters
 | |
|         :return: (changed, group) -
 | |
|             changed: Boolean whether a change was made
 | |
|             result: The result from the CLC API call
 | |
|         """
 | |
|         changed = False
 | |
|         acct_alias = self.clc.v2.Account.GetAlias()
 | |
|         aa_policy_id = server_params.get('anti_affinity_policy_id')
 | |
|         aa_policy_name = server_params.get('anti_affinity_policy_name')
 | |
|         if not aa_policy_id and aa_policy_name:
 | |
|             aa_policy_id = self._get_aa_policy_id_by_name(
 | |
|                 self.clc,
 | |
|                 self.module,
 | |
|                 acct_alias,
 | |
|                 aa_policy_name)
 | |
|         current_aa_policy_id = self._get_aa_policy_id_of_server(
 | |
|             self.clc,
 | |
|             self.module,
 | |
|             acct_alias,
 | |
|             server.id)
 | |
| 
 | |
|         if aa_policy_id and aa_policy_id == current_aa_policy_id:
 | |
|             self._delete_aa_policy(
 | |
|                 self.clc,
 | |
|                 self.module,
 | |
|                 acct_alias,
 | |
|                 server.id)
 | |
|             changed = True
 | |
|         return changed
 | |
| 
 | |
|     @staticmethod
 | |
|     def _modify_aa_policy(clc, module, acct_alias, server_id, aa_policy_id):
 | |
|         """
 | |
|         modifies the anti affinity policy of the CLC server
 | |
|         :param clc: the clc-sdk instance to use
 | |
|         :param module: the AnsibleModule object
 | |
|         :param acct_alias: the CLC account alias
 | |
|         :param server_id: the CLC server id
 | |
|         :param aa_policy_id: the anti affinity policy id
 | |
|         :return: result: The result from the CLC API call
 | |
|         """
 | |
|         result = None
 | |
|         if not module.check_mode:
 | |
|             try:
 | |
|                 result = clc.v2.API.Call('PUT',
 | |
|                                          'servers/%s/%s/antiAffinityPolicy' % (
 | |
|                                              acct_alias,
 | |
|                                              server_id),
 | |
|                                          json.dumps({"id": aa_policy_id}))
 | |
|             except APIFailedResponse as ex:
 | |
|                 module.fail_json(
 | |
|                     msg='Unable to modify anti affinity policy to server : "{0}". {1}'.format(
 | |
|                         server_id, str(ex.response_text)))
 | |
|         return result
 | |
| 
 | |
|     @staticmethod
 | |
|     def _delete_aa_policy(clc, module, acct_alias, server_id):
 | |
|         """
 | |
|         Delete the anti affinity policy of the CLC server
 | |
|         :param clc: the clc-sdk instance to use
 | |
|         :param module: the AnsibleModule object
 | |
|         :param acct_alias: the CLC account alias
 | |
|         :param server_id: the CLC server id
 | |
|         :return: result: The result from the CLC API call
 | |
|         """
 | |
|         result = None
 | |
|         if not module.check_mode:
 | |
|             try:
 | |
|                 result = clc.v2.API.Call('DELETE',
 | |
|                                          'servers/%s/%s/antiAffinityPolicy' % (
 | |
|                                              acct_alias,
 | |
|                                              server_id),
 | |
|                                          json.dumps({}))
 | |
|             except APIFailedResponse as ex:
 | |
|                 module.fail_json(
 | |
|                     msg='Unable to delete anti affinity policy to server : "{0}". {1}'.format(
 | |
|                         server_id, str(ex.response_text)))
 | |
|         return result
 | |
| 
 | |
|     @staticmethod
 | |
|     def _get_aa_policy_id_by_name(clc, module, alias, aa_policy_name):
 | |
|         """
 | |
|         retrieves the anti affinity policy id of the server based on the name of the policy
 | |
|         :param clc: the clc-sdk instance to use
 | |
|         :param module: the AnsibleModule object
 | |
|         :param alias: the CLC account alias
 | |
|         :param aa_policy_name: the anti affinity policy name
 | |
|         :return: aa_policy_id: The anti affinity policy id
 | |
|         """
 | |
|         aa_policy_id = None
 | |
|         try:
 | |
|             aa_policies = clc.v2.API.Call(method='GET',
 | |
|                                           url='antiAffinityPolicies/%s' % alias)
 | |
|         except APIFailedResponse as ex:
 | |
|             return module.fail_json(
 | |
|                 msg='Unable to fetch anti affinity policies from account alias : "{0}". {1}'.format(
 | |
|                     alias, str(ex.response_text)))
 | |
|         for aa_policy in aa_policies.get('items'):
 | |
|             if aa_policy.get('name') == aa_policy_name:
 | |
|                 if not aa_policy_id:
 | |
|                     aa_policy_id = aa_policy.get('id')
 | |
|                 else:
 | |
|                     return module.fail_json(
 | |
|                         msg='multiple anti affinity policies were found with policy name : %s' % aa_policy_name)
 | |
|         if not aa_policy_id:
 | |
|             module.fail_json(
 | |
|                 msg='No anti affinity policy was found with policy name : %s' % aa_policy_name)
 | |
|         return aa_policy_id
 | |
| 
 | |
|     @staticmethod
 | |
|     def _get_aa_policy_id_of_server(clc, module, alias, server_id):
 | |
|         """
 | |
|         retrieves the anti affinity policy id of the server based on the CLC server id
 | |
|         :param clc: the clc-sdk instance to use
 | |
|         :param module: the AnsibleModule object
 | |
|         :param alias: the CLC account alias
 | |
|         :param server_id: the CLC server id
 | |
|         :return: aa_policy_id: The anti affinity policy id
 | |
|         """
 | |
|         aa_policy_id = None
 | |
|         try:
 | |
|             result = clc.v2.API.Call(
 | |
|                 method='GET', url='servers/%s/%s/antiAffinityPolicy' %
 | |
|                 (alias, server_id))
 | |
|             aa_policy_id = result.get('id')
 | |
|         except APIFailedResponse as ex:
 | |
|             if ex.response_status_code != 404:
 | |
|                 module.fail_json(msg='Unable to fetch anti affinity policy for server "{0}". {1}'.format(
 | |
|                     server_id, str(ex.response_text)))
 | |
|         return aa_policy_id
 | |
| 
 | |
|     def _ensure_alert_policy_present(
 | |
|             self, server, server_params):
 | |
|         """
 | |
|         ensures the server is updated with the provided alert policy
 | |
|         :param server: the CLC server object
 | |
|         :param server_params: the dictionary of server parameters
 | |
|         :return: (changed, group) -
 | |
|             changed: Boolean whether a change was made
 | |
|             result: The result from the CLC API call
 | |
|         """
 | |
|         changed = False
 | |
|         acct_alias = self.clc.v2.Account.GetAlias()
 | |
|         alert_policy_id = server_params.get('alert_policy_id')
 | |
|         alert_policy_name = server_params.get('alert_policy_name')
 | |
|         if not alert_policy_id and alert_policy_name:
 | |
|             alert_policy_id = self._get_alert_policy_id_by_name(
 | |
|                 self.clc,
 | |
|                 self.module,
 | |
|                 acct_alias,
 | |
|                 alert_policy_name)
 | |
|         if alert_policy_id and not self._alert_policy_exists(
 | |
|                 server, alert_policy_id):
 | |
|             self._add_alert_policy_to_server(
 | |
|                 self.clc,
 | |
|                 self.module,
 | |
|                 acct_alias,
 | |
|                 server.id,
 | |
|                 alert_policy_id)
 | |
|             changed = True
 | |
|         return changed
 | |
| 
 | |
|     def _ensure_alert_policy_absent(
 | |
|             self, server, server_params):
 | |
|         """
 | |
|         ensures the alert policy is removed from the server
 | |
|         :param server: the CLC server object
 | |
|         :param server_params: the dictionary of server parameters
 | |
|         :return: (changed, group) -
 | |
|             changed: Boolean whether a change was made
 | |
|             result: The result from the CLC API call
 | |
|         """
 | |
|         changed = False
 | |
| 
 | |
|         acct_alias = self.clc.v2.Account.GetAlias()
 | |
|         alert_policy_id = server_params.get('alert_policy_id')
 | |
|         alert_policy_name = server_params.get('alert_policy_name')
 | |
|         if not alert_policy_id and alert_policy_name:
 | |
|             alert_policy_id = self._get_alert_policy_id_by_name(
 | |
|                 self.clc,
 | |
|                 self.module,
 | |
|                 acct_alias,
 | |
|                 alert_policy_name)
 | |
| 
 | |
|         if alert_policy_id and self._alert_policy_exists(
 | |
|                 server, alert_policy_id):
 | |
|             self._remove_alert_policy_to_server(
 | |
|                 self.clc,
 | |
|                 self.module,
 | |
|                 acct_alias,
 | |
|                 server.id,
 | |
|                 alert_policy_id)
 | |
|             changed = True
 | |
|         return changed
 | |
| 
 | |
|     @staticmethod
 | |
|     def _add_alert_policy_to_server(
 | |
|             clc, module, acct_alias, server_id, alert_policy_id):
 | |
|         """
 | |
|         add the alert policy to CLC server
 | |
|         :param clc: the clc-sdk instance to use
 | |
|         :param module: the AnsibleModule object
 | |
|         :param acct_alias: the CLC account alias
 | |
|         :param server_id: the CLC server id
 | |
|         :param alert_policy_id: the alert policy id
 | |
|         :return: result: The result from the CLC API call
 | |
|         """
 | |
|         result = None
 | |
|         if not module.check_mode:
 | |
|             try:
 | |
|                 result = clc.v2.API.Call('POST',
 | |
|                                          'servers/%s/%s/alertPolicies' % (
 | |
|                                              acct_alias,
 | |
|                                              server_id),
 | |
|                                          json.dumps({"id": alert_policy_id}))
 | |
|             except APIFailedResponse as ex:
 | |
|                 module.fail_json(msg='Unable to set alert policy to the server : "{0}". {1}'.format(
 | |
|                     server_id, str(ex.response_text)))
 | |
|         return result
 | |
| 
 | |
|     @staticmethod
 | |
|     def _remove_alert_policy_to_server(
 | |
|             clc, module, acct_alias, server_id, alert_policy_id):
 | |
|         """
 | |
|         remove the alert policy to the CLC server
 | |
|         :param clc: the clc-sdk instance to use
 | |
|         :param module: the AnsibleModule object
 | |
|         :param acct_alias: the CLC account alias
 | |
|         :param server_id: the CLC server id
 | |
|         :param alert_policy_id: the alert policy id
 | |
|         :return: result: The result from the CLC API call
 | |
|         """
 | |
|         result = None
 | |
|         if not module.check_mode:
 | |
|             try:
 | |
|                 result = clc.v2.API.Call('DELETE',
 | |
|                                          'servers/%s/%s/alertPolicies/%s'
 | |
|                                          % (acct_alias, server_id, alert_policy_id))
 | |
|             except APIFailedResponse as ex:
 | |
|                 module.fail_json(msg='Unable to remove alert policy from the server : "{0}". {1}'.format(
 | |
|                     server_id, str(ex.response_text)))
 | |
|         return result
 | |
| 
 | |
|     @staticmethod
 | |
|     def _get_alert_policy_id_by_name(clc, module, alias, alert_policy_name):
 | |
|         """
 | |
|         retrieves the alert policy id of the server based on the name of the policy
 | |
|         :param clc: the clc-sdk instance to use
 | |
|         :param module: the AnsibleModule object
 | |
|         :param alias: the CLC account alias
 | |
|         :param alert_policy_name: the alert policy name
 | |
|         :return: alert_policy_id: The alert policy id
 | |
|         """
 | |
|         alert_policy_id = None
 | |
|         try:
 | |
|             alert_policies = clc.v2.API.Call(method='GET',
 | |
|                                              url='alertPolicies/%s' % alias)
 | |
|         except APIFailedResponse as ex:
 | |
|             return module.fail_json(msg='Unable to fetch alert policies for account : "{0}". {1}'.format(
 | |
|                 alias, str(ex.response_text)))
 | |
|         for alert_policy in alert_policies.get('items'):
 | |
|             if alert_policy.get('name') == alert_policy_name:
 | |
|                 if not alert_policy_id:
 | |
|                     alert_policy_id = alert_policy.get('id')
 | |
|                 else:
 | |
|                     return module.fail_json(
 | |
|                         msg='multiple alert policies were found with policy name : %s' % alert_policy_name)
 | |
|         return alert_policy_id
 | |
| 
 | |
|     @staticmethod
 | |
|     def _alert_policy_exists(server, alert_policy_id):
 | |
|         """
 | |
|         Checks if the alert policy exists for the server
 | |
|         :param server: the clc server object
 | |
|         :param alert_policy_id: the alert policy
 | |
|         :return: True: if the given alert policy id associated to the server, False otherwise
 | |
|         """
 | |
|         result = False
 | |
|         alert_policies = server.alertPolicies
 | |
|         if alert_policies:
 | |
|             for alert_policy in alert_policies:
 | |
|                 if alert_policy.get('id') == alert_policy_id:
 | |
|                     result = True
 | |
|         return result
 | |
| 
 | |
|     @staticmethod
 | |
|     def _set_user_agent(clc):
 | |
|         if hasattr(clc, 'SetRequestsSession'):
 | |
|             agent_string = "ClcAnsibleModule/" + __version__
 | |
|             ses = requests.Session()
 | |
|             ses.headers.update({"Api-Client": agent_string})
 | |
|             ses.headers['User-Agent'] += " " + agent_string
 | |
|             clc.SetRequestsSession(ses)
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     """
 | |
|     The main function.  Instantiates the module and calls process_request.
 | |
|     :return: none
 | |
|     """
 | |
| 
 | |
|     argument_dict = ClcModifyServer._define_module_argument_spec()
 | |
|     module = AnsibleModule(supports_check_mode=True, **argument_dict)
 | |
|     clc_modify_server = ClcModifyServer(module)
 | |
|     clc_modify_server.process_request()
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     main()
 |