diff options
-rw-r--r-- | lib/ansible/modules/network/f5/bigip_vcmp_guest.py | 44 | ||||
-rw-r--r-- | test/units/modules/network/f5/test_bigip_vcmp_guest.py | 61 |
2 files changed, 102 insertions, 3 deletions
diff --git a/lib/ansible/modules/network/f5/bigip_vcmp_guest.py b/lib/ansible/modules/network/f5/bigip_vcmp_guest.py index 22221856f5..9aab8105df 100644 --- a/lib/ansible/modules/network/f5/bigip_vcmp_guest.py +++ b/lib/ansible/modules/network/f5/bigip_vcmp_guest.py @@ -42,6 +42,12 @@ options: hypervisor instance and any licensed BIG-IP modules onto the guest's virtual disk. When creating a new guest, this parameter is required. type: str + initial_hotfix: + description: + - Specifies the hotfix ISO image file which will be applied on top of the base + image. + type: str + version_added: 2.9 mgmt_network: description: - Specifies the method by which the management address is used in the vCMP guest. @@ -250,6 +256,7 @@ class Parameters(AnsibleF5Parameters): 'managementNetwork': 'mgmt_network', 'managementIp': 'mgmt_address', 'initialImage': 'initial_image', + 'initialHotfix': 'initial_hotfix', 'virtualDisk': 'virtual_disk', 'coresPerSlot': 'cores_per_slot', 'slots': 'number_of_slots', @@ -262,6 +269,7 @@ class Parameters(AnsibleF5Parameters): 'managementNetwork', 'managementIp', 'initialImage', + 'initialHotfix', 'managementGw', 'state', 'coresPerSlot', @@ -275,6 +283,7 @@ class Parameters(AnsibleF5Parameters): 'mgmt_network', 'mgmt_address', 'initial_image', + 'initial_hotfix', 'mgmt_route', 'name', 'cores_per_slot', @@ -288,6 +297,7 @@ class Parameters(AnsibleF5Parameters): 'mgmt_network', 'mgmt_address', 'initial_image', + 'initial_hotfix', 'mgmt_route', 'state', 'cores_per_slot', @@ -312,7 +322,7 @@ class ModuleParameters(Parameters): return self._values['mgmt_route'] else: raise F5ModuleError( - "The specified 'mgmt_route' is not a valid IP address" + "The specified 'mgmt_route' is not a valid IP address." ) @property @@ -324,7 +334,7 @@ class ModuleParameters(Parameters): return str(addr.with_prefixlen) except ValueError: raise F5ModuleError( - "The specified 'mgmt_address' is not a valid IP address" + "The specified 'mgmt_address' is not a valid IP address." ) @property @@ -367,7 +377,17 @@ class ModuleParameters(Parameters): if self.initial_image_exists(self._values['initial_image']): return self._values['initial_image'] raise F5ModuleError( - "The specified 'initial_image' does not exist on the remote device" + "The specified 'initial_image' does not exist on the remote device." + ) + + @property + def initial_hotfix(self): + if self._values['initial_hotfix'] is None: + return None + if self.initial_hotfix_exists(self._values['initial_hotfix']): + return self._values['initial_hotfix'] + raise F5ModuleError( + "The specified 'initial_hotfix' does not exist on the remote device." ) def initial_image_exists(self, image): @@ -387,6 +407,23 @@ class ModuleParameters(Parameters): return True return False + def initial_hotfix_exists(self, hotfix): + uri = "https://{0}:{1}/mgmt/tm/sys/software/hotfix/".format( + self.client.provider['server'], + self.client.provider['server_port'], + ) + resp = self.client.api.get(uri) + try: + response = resp.json() + except ValueError: + return False + if resp.status == 404 or 'code' in response and response['code'] == 404: + return False + for resource in response['items']: + if resource['name'].startswith(hotfix): + return True + return False + @property def allowed_slots(self): if self._values['allowed_slots'] is None: @@ -933,6 +970,7 @@ class ArgumentSpec(object): mgmt_address=dict(), mgmt_route=dict(), initial_image=dict(), + initial_hotfix=dict(), state=dict( default='present', choices=['configured', 'disabled', 'provisioned', 'absent', 'present'] diff --git a/test/units/modules/network/f5/test_bigip_vcmp_guest.py b/test/units/modules/network/f5/test_bigip_vcmp_guest.py index 8c266aad92..72230b05c2 100644 --- a/test/units/modules/network/f5/test_bigip_vcmp_guest.py +++ b/test/units/modules/network/f5/test_bigip_vcmp_guest.py @@ -149,6 +149,28 @@ class TestParameters(unittest.TestCase): assert '/Common/vlan1' in p.vlans assert '/Common/vlan2' in p.vlans + def test_api_parameters_with_hotfix(self): + args = dict( + initialImage="BIGIP-14.1.0.3-0.0.6.iso", + initialHotfix="Hotfix-BIGIP-14.1.0.3.0.5.6-ENG.iso", + managementGw="2.2.2.2", + managementIp="1.1.1.1/24", + managementNetwork="bridged", + state="deployed", + vlans=[ + "/Common/vlan1", + "/Common/vlan2" + ] + ) + + p = ApiParameters(params=args) + assert p.initial_image == 'BIGIP-14.1.0.3-0.0.6.iso' + assert p.initial_hotfix == 'Hotfix-BIGIP-14.1.0.3.0.5.6-ENG.iso' + assert p.mgmt_route == '2.2.2.2' + assert p.mgmt_address == '1.1.1.1/24' + assert '/Common/vlan1' in p.vlans + assert '/Common/vlan2' in p.vlans + class TestManager(unittest.TestCase): def setUp(self): @@ -160,14 +182,21 @@ class TestManager(unittest.TestCase): self.p1 = patch('library.modules.bigip_vcmp_guest.ModuleParameters.initial_image_exists') self.m1 = self.p1.start() self.m1.return_value = True + self.p2 = patch('library.modules.bigip_vcmp_guest.ModuleParameters.initial_hotfix_exists') + self.m2 = self.p2.start() + self.m2.return_value = True except Exception: self.p1 = patch('ansible.modules.network.f5.bigip_vcmp_guest.ModuleParameters.initial_image_exists') self.m1 = self.p1.start() self.m1.return_value = True + self.p2 = patch('ansible.modules.network.f5.bigip_vcmp_guest.ModuleParameters.initial_hotfix_exists') + self.m2 = self.p2.start() + self.m2.return_value = True def tearDown(self): self.patcher1.stop() self.p1.stop() + self.p2.stop() def test_create_vcmpguest(self, *args): set_module_args(dict( @@ -199,3 +228,35 @@ class TestManager(unittest.TestCase): assert results['changed'] is True assert results['name'] == 'guest1' + + def test_create_vcmpguest_with_hotfix(self, *args): + set_module_args(dict( + name="guest2", + mgmt_network="bridged", + mgmt_address="10.10.10.10/24", + initial_image="BIGIP-14.1.0.3-0.0.6.iso", + initial_hotfix="Hotfix-BIGIP-14.1.0.3.0.5.6-ENG.iso", + provider=dict( + server='localhost', + password='password', + user='admin' + ) + )) + + module = AnsibleModule( + argument_spec=self.spec.argument_spec, + supports_check_mode=self.spec.supports_check_mode, + required_if=self.spec.required_if + ) + + # Override methods to force specific logic in the module to happen + mm = ModuleManager(module=module) + mm.create_on_device = Mock(return_value=True) + mm.exists = Mock(return_value=False) + mm.is_deployed = Mock(side_effect=[False, True, True, True, True]) + mm.deploy_on_device = Mock(return_value=True) + + results = mm.exec_module() + + assert results['changed'] is True + assert results['name'] == 'guest2' |