#!/usr/bin/python # -*- coding: utf-8 -*- # # Copyright (c) 2017 F5 Networks Inc. # GNU General Public License v3.0 (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} DOCUMENTATION = ''' --- module: bigip_hostname short_description: Manage the hostname of a BIG-IP. description: - Manage the hostname of a BIG-IP. version_added: "2.3" options: hostname: description: - Hostname of the BIG-IP host. required: True notes: - Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk. extends_documentation_fragment: f5 requirements: - f5-sdk author: - Tim Rupp (@caphrim007) - Matthew Lam (@mryanlam) ''' EXAMPLES = ''' - name: Set the hostname of the BIG-IP bigip_hostname: hostname: "bigip.localhost.localdomain" password: "admin" server: "bigip.localhost.localdomain" user: "admin" delegate_to: localhost ''' RETURN = ''' hostname: description: The new hostname of the device returned: changed type: string sample: "big-ip01.internal" ''' from ansible.module_utils.f5_utils import ( AnsibleF5Client, AnsibleF5Parameters, HAS_F5SDK, F5ModuleError, iControlUnexpectedHTTPError ) class Parameters(AnsibleF5Parameters): api_attributes = ['hostname'] updatables = ['hostname'] returnables = ['hostname'] def to_return(self): result = {} for returnable in self.returnables: result[returnable] = getattr(self, returnable) result = self._filter_params(result) return result def api_params(self): result = {} for api_attribute in self.api_attributes: if self.api_map is not None and api_attribute in self.api_map: result[api_attribute] = getattr(self, self.api_map[api_attribute]) else: result[api_attribute] = getattr(self, api_attribute) result = self._filter_params(result) return result @property def hostname(self): if self._values['hostname'] is None: return None return str(self._values['hostname']) class ModuleManager(object): def __init__(self, client): self.client = client self.have = None self.want = Parameters(self.client.module.params) self.changes = Parameters() def _set_changed_options(self): changed = {} for key in Parameters.returnables: if getattr(self.want, key) is not None: changed[key] = getattr(self.want, key) if changed: self.changes = Parameters(changed) def _update_changed_options(self): changed = {} for key in Parameters.updatables: if getattr(self.want, key) is not None: attr1 = getattr(self.want, key) attr2 = getattr(self.have, key) if attr1 != attr2: changed[key] = attr1 self.changes = Parameters(changed) if changed: return True return False def exec_module(self): result = dict() try: changed = self.update() except iControlUnexpectedHTTPError as e: raise F5ModuleError(str(e)) changes = self.changes.to_return() result.update(**changes) result.update(dict(changed=changed)) return result def read_current_from_device(self): resource = self.client.api.tm.sys.global_settings.load() result = resource.attrs return Parameters(result) def update(self): self.have = self.read_current_from_device() if not self.should_update(): return False if self.client.check_mode: return True self.update_on_device() return True def should_update(self): result = self._update_changed_options() if result: return True return False def update_on_device(self): params = self.want.api_params() resource = self.client.api.tm.sys.global_settings.load() resource.modify(**params) self.client.api.tm.cm.devices.exec_cmd( 'mv', name=self.have.hostname, target=self.want.hostname ) class ArgumentSpec(object): def __init__(self): self.supports_check_mode = True self.argument_spec = dict( hostname=dict( required=True, default=None, type='str' ) ) self.f5_product_name = 'bigip' def main(): if not HAS_F5SDK: raise F5ModuleError("The python f5-sdk module is required") spec = ArgumentSpec() client = AnsibleF5Client( argument_spec=spec.argument_spec, supports_check_mode=spec.supports_check_mode, f5_product_name=spec.f5_product_name ) try: mm = ModuleManager(client) results = mm.exec_module() client.module.exit_json(**results) except F5ModuleError as e: client.module.fail_json(msg=str(e)) if __name__ == '__main__': main()