Fixes and features for bigip_provision (#33480)
* Fixes and features for bigip_provision Adds support for dedicated modules. Fixes bug in minimum name. Adds wrappers around checking for up-ness so that they will contribute to the watch loop * Fixes upstream errors
This commit is contained in:
parent
2b1f056881
commit
e3419fce87
2 changed files with 54 additions and 17 deletions
|
@ -48,7 +48,7 @@ options:
|
|||
level for one module may require modifying the level of another module.
|
||||
For example, changing one module to C(dedicated) requires setting all
|
||||
others to C(none). Setting the level of a module to C(none) means that
|
||||
the module is not run.
|
||||
the module is not activated.
|
||||
default: nominal
|
||||
choices:
|
||||
- dedicated
|
||||
|
@ -113,6 +113,7 @@ from ansible.module_utils.f5_utils import HAS_F5SDK
|
|||
from ansible.module_utils.f5_utils import F5ModuleError
|
||||
|
||||
try:
|
||||
from f5.bigip.contexts import TransactionContextManager
|
||||
from f5.sdk_exception import LazyAttributesRequired
|
||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
||||
except ImportError:
|
||||
|
@ -228,6 +229,27 @@ class ModuleManager(object):
|
|||
return False
|
||||
|
||||
def update_on_device(self):
|
||||
if self.want.level == 'dedicated':
|
||||
self.provision_dedicated_on_device()
|
||||
else:
|
||||
self.provision_non_dedicated_on_device()
|
||||
|
||||
def provision_dedicated_on_device(self):
|
||||
params = self.want.api_params()
|
||||
tx = self.client.api.tm.transactions.transaction
|
||||
collection = self.client.api.tm.sys.provision.get_collection()
|
||||
resources = [x['name'] for x in collection if x['name'] != self.want.module]
|
||||
with TransactionContextManager(tx) as api:
|
||||
provision = api.tm.sys.provision
|
||||
for resource in resources:
|
||||
resource = getattr(provision, resource)
|
||||
resource = resource.load()
|
||||
resource.update(level='none')
|
||||
resource = getattr(provision, self.want.module)
|
||||
resource = resource.load()
|
||||
resource.update(**params)
|
||||
|
||||
def provision_non_dedicated_on_device(self):
|
||||
params = self.want.api_params()
|
||||
provision = self.client.api.tm.sys.provision
|
||||
resource = getattr(provision, self.want.module)
|
||||
|
@ -286,18 +308,30 @@ class ModuleManager(object):
|
|||
nops = 0
|
||||
except Exception:
|
||||
# This can be caused by restjavad restarting.
|
||||
try:
|
||||
self.client.reconnect()
|
||||
except Exception:
|
||||
pass
|
||||
time.sleep(5)
|
||||
|
||||
def _is_mprov_running_on_device(self):
|
||||
# /usr/libexec/qemu-kvm is added here to prevent vcmp provisioning
|
||||
# from never allowing the mprov provisioning to succeed.
|
||||
#
|
||||
# It turns out that the 'mprov' string is found when enabling vcmp. The
|
||||
# qemu-kvm command that is run includes it.
|
||||
#
|
||||
# For example,
|
||||
# /usr/libexec/qemu-kvm -rt-usecs 880 ... -mem-path /dev/mprov/vcmp -f5-tracing ...
|
||||
#
|
||||
try:
|
||||
output = self.client.api.tm.util.bash.exec_cmd(
|
||||
'run',
|
||||
utilCmdArgs='-c "ps aux | grep \'[m]prov\'"'
|
||||
utilCmdArgs='-c "ps aux | grep \'[m]prov\' | grep -v /usr/libexec/qemu-kvm"'
|
||||
)
|
||||
try:
|
||||
if hasattr(output, 'commandResult'):
|
||||
return True
|
||||
except LazyAttributesRequired:
|
||||
except Exception:
|
||||
pass
|
||||
return False
|
||||
|
||||
|
@ -317,19 +351,19 @@ class ModuleManager(object):
|
|||
nops += 1
|
||||
else:
|
||||
nops = 0
|
||||
except Exception:
|
||||
except Exception as ex:
|
||||
pass
|
||||
time.sleep(5)
|
||||
|
||||
def _get_last_reboot(self):
|
||||
try:
|
||||
output = self.client.api.tm.util.bash.exec_cmd(
|
||||
'run',
|
||||
utilCmdArgs='-c "/usr/bin/last reboot | head -1"'
|
||||
)
|
||||
try:
|
||||
if hasattr(output, 'commandResult'):
|
||||
return str(output.commandResult)
|
||||
except LazyAttributesRequired:
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
@ -343,6 +377,7 @@ class ModuleManager(object):
|
|||
|
||||
while nops < 6:
|
||||
try:
|
||||
self.client.reconnect()
|
||||
next_reboot = self._get_last_reboot()
|
||||
if next_reboot is None:
|
||||
nops = 0
|
||||
|
@ -350,7 +385,7 @@ class ModuleManager(object):
|
|||
nops = 0
|
||||
else:
|
||||
nops += 1
|
||||
except Exception:
|
||||
except Exception as ex:
|
||||
# This can be caused by restjavad restarting.
|
||||
pass
|
||||
time.sleep(10)
|
||||
|
@ -371,7 +406,7 @@ class ArgumentSpec(object):
|
|||
),
|
||||
level=dict(
|
||||
default='nominal',
|
||||
choices=['nominal', 'dedicated', 'minimal']
|
||||
choices=['nominal', 'dedicated', 'minimum']
|
||||
),
|
||||
state=dict(
|
||||
default='present',
|
||||
|
|
|
@ -15,21 +15,23 @@ if sys.version_info < (2, 7):
|
|||
raise SkipTest("F5 Ansible modules require Python >= 2.7")
|
||||
|
||||
from ansible.compat.tests import unittest
|
||||
from ansible.compat.tests.mock import patch, Mock
|
||||
from ansible.compat.tests.mock import Mock
|
||||
from ansible.compat.tests.mock import patch
|
||||
from ansible.module_utils.f5_utils import AnsibleF5Client
|
||||
from units.modules.utils import set_module_args
|
||||
|
||||
try:
|
||||
from library.bigip_provision import Parameters
|
||||
from library.bigip_provision import ModuleManager
|
||||
from library.bigip_provision import ArgumentSpec
|
||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
||||
from test.unit.modules.utils import set_module_args
|
||||
except ImportError:
|
||||
try:
|
||||
from ansible.modules.network.f5.bigip_provision import Parameters
|
||||
from ansible.modules.network.f5.bigip_provision import ModuleManager
|
||||
from ansible.modules.network.f5.bigip_provision import ArgumentSpec
|
||||
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
|
||||
from units.modules.utils import set_module_args
|
||||
except ImportError:
|
||||
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
|
||||
|
||||
|
|
Loading…
Reference in a new issue