Remove sdk and deprecated features (#48016)

This removes deprecated params and the f5-sdk from the sys_global module
This commit is contained in:
Tim Rupp 2018-11-02 15:38:59 -07:00 committed by GitHub
parent 96c9d9fdaa
commit f25d9a1b30
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 220 additions and 137 deletions

View file

@ -1,7 +1,7 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# Copyright (c) 2016 F5 Networks Inc. # Copyright: (c) 2016, F5 Networks Inc.
# GNU General Public License v3.0 (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0 (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
@ -29,12 +29,12 @@ options:
off a user that is logged on. off a user that is logged on.
gui_setup: gui_setup:
description: description:
- C(enable) or C(disabled) the Setup utility in the browser-based - C(yes) or C(no) the Setup utility in the browser-based
Configuration utility. Configuration utility.
type: bool type: bool
lcd_display: lcd_display:
description: description:
- Specifies, when C(enabled), that the system menu displays on the - Specifies, when C(yes), that the system menu displays on the
LCD screen on the front of the unit. This setting has no effect LCD screen on the front of the unit. This setting has no effect
when used on the VE platform. when used on the VE platform.
type: bool type: bool
@ -45,14 +45,14 @@ options:
type: bool type: bool
net_reboot: net_reboot:
description: description:
- Specifies, when C(enabled), that the next time you reboot the system, - Specifies, when C(yes), that the next time you reboot the system,
the system boots to an ISO image on the network, rather than an the system boots to an ISO image on the network, rather than an
internal media drive. internal media drive.
type: bool type: bool
quiet_boot: quiet_boot:
description: description:
- Specifies, when C(enabled), that the system suppresses informational - Specifies, when C(yes), that the system suppresses informational
text on the console during the boot cycle. When C(disabled), the text on the console during the boot cycle. When C(no), the
system presents messages and informational text on the console during system presents messages and informational text on the console during
the boot cycle. the boot cycle.
type: bool type: bool
@ -69,20 +69,19 @@ options:
choices: choices:
- present - present
extends_documentation_fragment: f5 extends_documentation_fragment: f5
requirements:
- f5-sdk
author: author:
- Tim Rupp (@caphrim007) - Tim Rupp (@caphrim007)
- Wojciech Wypior (@wojtek0806)
''' '''
EXAMPLES = r''' EXAMPLES = r'''
- name: Disable the setup utility - name: Disable the setup utility
bigip_sys_global: bigip_sys_global:
gui_setup: no gui_setup: no
password: secret provider:
server: lb.mydomain.com password: secret
user: admin server: lb.mydomain.com
state: present user: admin
delegate_to: localhost delegate_to: localhost
''' '''
@ -102,67 +101,59 @@ console_timeout:
gui_setup: gui_setup:
description: The new setting for the Setup utility. description: The new setting for the Setup utility.
returned: changed returned: changed
type: string type: bool
sample: yes sample: yes
lcd_display: lcd_display:
description: The new setting for displaying the system menu on the LCD. description: The new setting for displaying the system menu on the LCD.
returned: changed returned: changed
type: string type: bool
sample: yes sample: yes
mgmt_dhcp: mgmt_dhcp:
description: The new setting for whether the mgmt interface should DHCP or not. description: The new setting for whether the mgmt interface should DHCP or not.
returned: changed returned: changed
type: string type: bool
sample: yes sample: yes
net_reboot: net_reboot:
description: The new setting for whether the system should boot to an ISO on the network or not. description: The new setting for whether the system should boot to an ISO on the network or not.
returned: changed returned: changed
type: string type: bool
sample: yes sample: yes
quiet_boot: quiet_boot:
description: description:
- The new setting for whether the system should suppress information to - The new setting for whether the system should suppress information to
the console during boot or not. the console during boot or not.
returned: changed returned: changed
type: string type: bool
sample: yes sample: yes
security_banner: security_banner:
description: description:
- The new setting for whether the system should display an advisory message - The new setting for whether the system should display an advisory message
on the login screen or not. on the login screen or not.
returned: changed returned: changed
type: string type: bool
sample: yes sample: yes
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.parsing.convert_bool import BOOLEANS_TRUE
from ansible.module_utils.parsing.convert_bool import BOOLEANS_FALSE
try: try:
from library.module_utils.network.f5.bigip import HAS_F5SDK from library.module_utils.network.f5.bigip import F5RestClient
from library.module_utils.network.f5.bigip import F5Client
from library.module_utils.network.f5.common import F5ModuleError from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import AnsibleF5Parameters from library.module_utils.network.f5.common import AnsibleF5Parameters
from library.module_utils.network.f5.common import cleanup_tokens from library.module_utils.network.f5.common import cleanup_tokens
from library.module_utils.network.f5.common import f5_argument_spec from library.module_utils.network.f5.common import f5_argument_spec
from library.module_utils.network.f5.common import exit_json
try: from library.module_utils.network.f5.common import fail_json
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError from library.module_utils.network.f5.common import flatten_boolean
except ImportError:
HAS_F5SDK = False
except ImportError: except ImportError:
from ansible.module_utils.network.f5.bigip import HAS_F5SDK from ansible.module_utils.network.f5.bigip import F5RestClient
from ansible.module_utils.network.f5.bigip import F5Client
from ansible.module_utils.network.f5.common import F5ModuleError from ansible.module_utils.network.f5.common import F5ModuleError
from ansible.module_utils.network.f5.common import AnsibleF5Parameters from ansible.module_utils.network.f5.common import AnsibleF5Parameters
from ansible.module_utils.network.f5.common import cleanup_tokens from ansible.module_utils.network.f5.common import cleanup_tokens
from ansible.module_utils.network.f5.common import f5_argument_spec from ansible.module_utils.network.f5.common import f5_argument_spec
from ansible.module_utils.network.f5.common import exit_json
try: from ansible.module_utils.network.f5.common import fail_json
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError from ansible.module_utils.network.f5.common import flatten_boolean
except ImportError:
HAS_F5SDK = False
class Parameters(AnsibleF5Parameters): class Parameters(AnsibleF5Parameters):
@ -174,80 +165,73 @@ class Parameters(AnsibleF5Parameters):
'mgmtDhcp': 'mgmt_dhcp', 'mgmtDhcp': 'mgmt_dhcp',
'netReboot': 'net_reboot', 'netReboot': 'net_reboot',
'quietBoot': 'quiet_boot', 'quietBoot': 'quiet_boot',
'consoleInactivityTimeout': 'console_timeout' 'consoleInactivityTimeout': 'console_timeout',
} }
api_attributes = [ api_attributes = [
'guiSecurityBanner', 'guiSecurityBannerText', 'guiSetup', 'lcdDisplay', 'guiSecurityBanner',
'mgmtDhcp', 'netReboot', 'quietBoot', 'consoleInactivityTimeout' 'guiSecurityBannerText',
'guiSetup',
'lcdDisplay',
'mgmtDhcp',
'netReboot',
'quietBoot',
'consoleInactivityTimeout',
] ]
returnables = [ returnables = [
'security_banner', 'banner_text', 'gui_setup', 'lcd_display', 'security_banner',
'mgmt_dhcp', 'net_reboot', 'quiet_boot', 'console_timeout' 'banner_text',
'gui_setup',
'lcd_display',
'mgmt_dhcp',
'net_reboot',
'quiet_boot',
'console_timeout',
] ]
updatables = [ updatables = [
'security_banner', 'banner_text', 'gui_setup', 'lcd_display', 'security_banner',
'mgmt_dhcp', 'net_reboot', 'quiet_boot', 'console_timeout' 'banner_text',
'gui_setup',
'lcd_display',
'mgmt_dhcp',
'net_reboot',
'quiet_boot',
'console_timeout',
] ]
@property
def security_banner(self):
return flatten_boolean(self._values['security_banner'])
@property
def gui_setup(self):
return flatten_boolean(self._values['gui_setup'])
@property
def lcd_display(self):
return flatten_boolean(self._values['lcd_display'])
@property
def mgmt_dhcp(self):
return flatten_boolean(self._values['mgmt_dhcp'])
@property
def net_reboot(self):
return flatten_boolean(self._values['net_reboot'])
@property
def quiet_boot(self):
return flatten_boolean(self._values['quiet_boot'])
class ApiParameters(Parameters): class ApiParameters(Parameters):
pass pass
class ModuleParameters(Parameters): class ModuleParameters(Parameters):
def _get_boolean_like_return_value(self, parameter): pass
if self._values[parameter] is None:
return None
elif self._values[parameter] in ['enabled', 'disabled']:
self._values['__warnings'].append(
dict(version='2.5', msg='enabled/disabled are deprecated. Use boolean values (true, yes, no, 1, 0) instead.')
)
true = list(BOOLEANS_TRUE) + ['True']
false = list(BOOLEANS_FALSE) + ['False']
if self._values[parameter] in true:
return 'enabled'
if self._values[parameter] in false:
return 'disabled'
else:
return str(self._values[parameter])
@property
def security_banner(self):
result = self._get_boolean_like_return_value('security_banner')
return result
@property
def gui_setup(self):
result = self._get_boolean_like_return_value('gui_setup')
return result
@property
def banner_text(self):
result = self._get_boolean_like_return_value('banner_text')
return result
@property
def lcd_display(self):
result = self._get_boolean_like_return_value('lcd_display')
return result
@property
def mgmt_dhcp(self):
result = self._get_boolean_like_return_value('mgmt_dhcp')
return result
@property
def net_reboot(self):
result = self._get_boolean_like_return_value('net_reboot')
return result
@property
def quiet_boot(self):
result = self._get_boolean_like_return_value('quiet_boot')
return result
class Changes(Parameters): class Changes(Parameters):
@ -263,11 +247,79 @@ class Changes(Parameters):
class UsableChanges(Changes): class UsableChanges(Changes):
pass @property
def security_banner(self):
if self._values['security_banner'] is None:
return None
if self._values['security_banner'] == 'yes':
return 'enabled'
return 'disabled'
@property
def gui_setup(self):
if self._values['gui_setup'] is None:
return None
if self._values['gui_setup'] == 'yes':
return 'enabled'
return 'disabled'
@property
def lcd_display(self):
if self._values['lcd_display'] is None:
return None
if self._values['lcd_display'] == 'yes':
return 'enabled'
return 'disabled'
@property
def mgmt_dhcp(self):
if self._values['mgmt_dhcp'] is None:
return None
if self._values['mgmt_dhcp'] == 'yes':
return 'enabled'
return 'disabled'
@property
def net_reboot(self):
if self._values['net_reboot'] is None:
return None
if self._values['net_reboot'] == 'yes':
return 'enabled'
return 'disabled'
@property
def quiet_boot(self):
if self._values['quiet_boot'] is None:
return None
if self._values['quiet_boot'] == 'yes':
return 'enabled'
return 'disabled'
class ReportableChanges(Changes): class ReportableChanges(Changes):
pass @property
def security_banner(self):
return flatten_boolean(self._values['security_banner'])
@property
def gui_setup(self):
return flatten_boolean(self._values['gui_setup'])
@property
def lcd_display(self):
return flatten_boolean(self._values['lcd_display'])
@property
def mgmt_dhcp(self):
return flatten_boolean(self._values['mgmt_dhcp'])
@property
def net_reboot(self):
return flatten_boolean(self._values['net_reboot'])
@property
def quiet_boot(self):
return flatten_boolean(self._values['quiet_boot'])
class Difference(object): class Difference(object):
@ -283,13 +335,13 @@ class Difference(object):
return self.__default(param) return self.__default(param)
def __default(self, param): def __default(self, param):
attr1 = getattr(self.want, param) want = getattr(self.want, param)
try: try:
attr2 = getattr(self.have, param) have = getattr(self.have, param)
if attr1 != attr2: if want != have:
return attr1 return want
except AttributeError: except AttributeError:
return attr1 return want
class ModuleManager(object): class ModuleManager(object):
@ -335,10 +387,7 @@ class ModuleManager(object):
def exec_module(self): def exec_module(self):
result = dict() result = dict()
try: changed = self.present()
changed = self.present()
except iControlUnexpectedHTTPError as e:
raise F5ModuleError(str(e))
reportable = ReportableChanges(params=self.changes.to_return()) reportable = ReportableChanges(params=self.changes.to_return())
changes = reportable.to_return() changes = reportable.to_return()
@ -358,11 +407,6 @@ class ModuleManager(object):
def present(self): def present(self):
return self.update() return self.update()
def read_current_from_device(self):
resource = self.client.api.tm.sys.global_settings.load()
result = resource.attrs
return ApiParameters(params=result)
def update(self): def update(self):
self.have = self.read_current_from_device() self.have = self.read_current_from_device()
if not self.should_update(): if not self.should_update():
@ -372,10 +416,41 @@ class ModuleManager(object):
self.update_on_device() self.update_on_device()
return True return True
def read_current_from_device(self):
uri = "https://{0}:{1}/mgmt/tm/sys/global-settings/".format(
self.client.provider['server'],
self.client.provider['server_port'],
)
resp = self.client.api.get(uri)
try:
response = resp.json()
except ValueError as ex:
raise F5ModuleError(str(ex))
if 'code' in response and response['code'] == 400:
if 'message' in response:
raise F5ModuleError(response['message'])
else:
raise F5ModuleError(resp.content)
return ApiParameters(params=response)
def update_on_device(self): def update_on_device(self):
params = self.want.api_params() params = self.changes.api_params()
resource = self.client.api.tm.sys.global_settings.load() uri = "https://{0}:{1}/mgmt/tm/sys/global-settings/".format(
resource.modify(**params) self.client.provider['server'],
self.client.provider['server_port'],
)
resp = self.client.api.patch(uri, json=params)
try:
response = resp.json()
except ValueError as ex:
raise F5ModuleError(str(ex))
if 'code' in response and response['code'] == 400:
if 'message' in response:
raise F5ModuleError(response['message'])
else:
raise F5ModuleError(resp.content)
class ArgumentSpec(object): class ArgumentSpec(object):
@ -402,8 +477,12 @@ class ArgumentSpec(object):
quiet_boot=dict( quiet_boot=dict(
type='bool' type='bool'
), ),
console_timeout=dict(required=False, type='int', default=None), console_timeout=dict(
state=dict(default='present', choices=['present']) type='int'
),
state=dict(
default='present', choices=['present']
)
) )
self.argument_spec = {} self.argument_spec = {}
self.argument_spec.update(f5_argument_spec) self.argument_spec.update(f5_argument_spec)
@ -417,18 +496,17 @@ def main():
argument_spec=spec.argument_spec, argument_spec=spec.argument_spec,
supports_check_mode=spec.supports_check_mode supports_check_mode=spec.supports_check_mode
) )
if not HAS_F5SDK:
module.fail_json(msg="The python f5-sdk module is required") client = F5RestClient(**module.params)
try: try:
client = F5Client(**module.params)
mm = ModuleManager(module=module, client=client) mm = ModuleManager(module=module, client=client)
results = mm.exec_module() results = mm.exec_module()
cleanup_tokens(client) cleanup_tokens(client)
module.exit_json(**results) exit_json(module, results, client)
except F5ModuleError as ex: except F5ModuleError as ex:
cleanup_tokens(client) cleanup_tokens(client)
module.fail_json(msg=str(ex)) fail_json(module, ex, client)
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -14,9 +14,6 @@ from nose.plugins.skip import SkipTest
if sys.version_info < (2, 7): if sys.version_info < (2, 7):
raise SkipTest("F5 Ansible modules require Python >= 2.7") raise SkipTest("F5 Ansible modules require Python >= 2.7")
from units.compat import unittest
from units.compat.mock import Mock
from units.compat.mock import patch
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
try: try:
@ -24,17 +21,25 @@ try:
from library.modules.bigip_sys_global import ModuleParameters from library.modules.bigip_sys_global import ModuleParameters
from library.modules.bigip_sys_global import ModuleManager from library.modules.bigip_sys_global import ModuleManager
from library.modules.bigip_sys_global import ArgumentSpec from library.modules.bigip_sys_global import ArgumentSpec
from library.module_utils.network.f5.common import F5ModuleError
from library.module_utils.network.f5.common import iControlUnexpectedHTTPError # In Ansible 2.8, Ansible changed import paths.
from test.unit.modules.utils import set_module_args from test.units.compat import unittest
from test.units.compat.mock import Mock
from test.units.compat.mock import patch
from test.units.modules.utils import set_module_args
except ImportError: except ImportError:
try: try:
from ansible.modules.network.f5.bigip_sys_global import ApiParameters from ansible.modules.network.f5.bigip_sys_global import ApiParameters
from ansible.modules.network.f5.bigip_sys_global import ModuleParameters from ansible.modules.network.f5.bigip_sys_global import ModuleParameters
from ansible.modules.network.f5.bigip_sys_global import ModuleManager from ansible.modules.network.f5.bigip_sys_global import ModuleManager
from ansible.modules.network.f5.bigip_sys_global import ArgumentSpec from ansible.modules.network.f5.bigip_sys_global import ArgumentSpec
from ansible.module_utils.network.f5.common import F5ModuleError
from ansible.module_utils.network.f5.common import iControlUnexpectedHTTPError # Ansible 2.8 imports
from units.compat import unittest
from units.compat.mock import Mock
from units.compat.mock import patch
from units.modules.utils import set_module_args from units.modules.utils import set_module_args
except ImportError: except ImportError:
raise SkipTest("F5 Ansible modules require the f5-sdk Python library") raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
@ -76,24 +81,24 @@ class TestParameters(unittest.TestCase):
p = ModuleParameters(params=args) p = ModuleParameters(params=args)
assert p.banner_text == 'this is a banner' assert p.banner_text == 'this is a banner'
assert p.console_timeout == 100 assert p.console_timeout == 100
assert p.gui_setup == 'enabled' assert p.gui_setup == 'yes'
assert p.lcd_display == 'enabled' assert p.lcd_display == 'yes'
assert p.mgmt_dhcp == 'enabled' assert p.mgmt_dhcp == 'yes'
assert p.net_reboot == 'enabled' assert p.net_reboot == 'yes'
assert p.quiet_boot == 'enabled' assert p.quiet_boot == 'yes'
assert p.security_banner == 'enabled' assert p.security_banner == 'yes'
def test_api_parameters(self): def test_api_parameters(self):
args = load_fixture('load_sys_global_settings.json') args = load_fixture('load_sys_global_settings.json')
p = ApiParameters(params=args) p = ApiParameters(params=args)
assert 'Welcome to the BIG-IP Configuration Utility' in p.banner_text assert 'Welcome to the BIG-IP Configuration Utility' in p.banner_text
assert p.console_timeout == 0 assert p.console_timeout == 0
assert p.gui_setup == 'disabled' assert p.gui_setup == 'no'
assert p.lcd_display == 'enabled' assert p.lcd_display == 'yes'
assert p.mgmt_dhcp == 'enabled' assert p.mgmt_dhcp == 'yes'
assert p.net_reboot == 'disabled' assert p.net_reboot == 'no'
assert p.quiet_boot == 'enabled' assert p.quiet_boot == 'yes'
assert p.security_banner == 'enabled' assert p.security_banner == 'yes'
class TestManager(unittest.TestCase): class TestManager(unittest.TestCase):