diff options
28 files changed, 1424 insertions, 1251 deletions
| diff --git a/plugins/module_utils/network/vyos/argspec/facts/facts.py b/plugins/module_utils/network/vyos/argspec/facts/facts.py index 456c8bd..e660ef2 100644 --- a/plugins/module_utils/network/vyos/argspec/facts/facts.py +++ b/plugins/module_utils/network/vyos/argspec/facts/facts.py @@ -7,6 +7,7 @@ The arg spec for the vyos facts module.  from __future__ import absolute_import, division, print_function +  __metaclass__ = type @@ -17,15 +18,9 @@ class FactsArgs(object):  # pylint: disable=R0903      def __init__(self, **kwargs):          pass -    choices = [ -        'all', -        'interfaces', -        '!interfaces', -        'l3_interfaces', -        '!l3_interfaces' -    ] +    choices = ["all", "interfaces", "!interfaces", "l3_interfaces", "!l3_interfaces"]      argument_spec = { -        'gather_subset': dict(default=['!config'], type='list'), -        'gather_network_resources': dict(choices=choices, type='list'), +        "gather_subset": dict(default=["!config"], type="list"), +        "gather_network_resources": dict(choices=choices, type="list"),      } diff --git a/plugins/module_utils/network/vyos/argspec/interfaces/interfaces.py b/plugins/module_utils/network/vyos/argspec/interfaces/interfaces.py index d6ab446..3542cb1 100644 --- a/plugins/module_utils/network/vyos/argspec/interfaces/interfaces.py +++ b/plugins/module_utils/network/vyos/argspec/interfaces/interfaces.py @@ -24,6 +24,7 @@ The arg spec for the vyos_interfaces module  """  from __future__ import absolute_import, division, print_function +  __metaclass__ = type @@ -34,34 +35,35 @@ class InterfacesArgs(object):  # pylint: disable=R0903      def __init__(self, **kwargs):          pass -    argument_spec = \ -        { -            'config': { -                'elements': 'dict', -                'options': { -                    'description': {'type': 'str'}, -                    'duplex': {'choices': ['full', 'half', 'auto']}, -                    'enabled': {'default': True, 'type': 'bool'}, -                    'mtu': {'type': 'int'}, -                    'name': {'required': True, 'type': 'str'}, -                    'speed': {'choices': ['auto', '10', '100', '1000', '2500', -                                          '10000'], -                              'type': 'str'}, -                    'vifs': { -                        'elements': 'dict', -                        'options': { -                            'vlan_id': {'type': 'int'}, -                            'description': {'type': 'str'}, -                            'enabled': {'default': True, 'type': 'bool'}, -                            'mtu': {'type': 'int'} -                        }, -                        'type': 'list' +    argument_spec = { +        "config": { +            "elements": "dict", +            "options": { +                "description": {"type": "str"}, +                "duplex": {"choices": ["full", "half", "auto"]}, +                "enabled": {"default": True, "type": "bool"}, +                "mtu": {"type": "int"}, +                "name": {"required": True, "type": "str"}, +                "speed": { +                    "choices": ["auto", "10", "100", "1000", "2500", "10000"], +                    "type": "str", +                }, +                "vifs": { +                    "elements": "dict", +                    "options": { +                        "vlan_id": {"type": "int"}, +                        "description": {"type": "str"}, +                        "enabled": {"default": True, "type": "bool"}, +                        "mtu": {"type": "int"},                      }, +                    "type": "list",                  }, -                'type': 'list'              }, -            'state': {'choices': ['merged', 'replaced', -                                  'overridden', 'deleted'], -                      'default': 'merged', -                      'type': 'str'} -        }  # pylint: disable=C0301 +            "type": "list", +        }, +        "state": { +            "choices": ["merged", "replaced", "overridden", "deleted"], +            "default": "merged", +            "type": "str", +        }, +    }  # pylint: disable=C0301 diff --git a/plugins/module_utils/network/vyos/argspec/l3_interfaces/l3_interfaces.py b/plugins/module_utils/network/vyos/argspec/l3_interfaces/l3_interfaces.py index e5785a8..91434e4 100644 --- a/plugins/module_utils/network/vyos/argspec/l3_interfaces/l3_interfaces.py +++ b/plugins/module_utils/network/vyos/argspec/l3_interfaces/l3_interfaces.py @@ -27,6 +27,7 @@ The arg spec for the vyos_l3_interfaces module  from __future__ import absolute_import, division, print_function +  __metaclass__ = type @@ -38,64 +39,43 @@ class L3_interfacesArgs(object):  # pylint: disable=R0903          pass      argument_spec = { -        'config': { -            'elements': 'dict', -            'options': { -                'ipv4': { -                    'elements': 'dict', -                    'options': { -                        'address': { -                            'type': 'str' -                        } -                    }, -                    'type': 'list' -                }, -                'ipv6': { -                    'elements': 'dict', -                    'options': { -                        'address': { -                            'type': 'str' -                        } -                    }, -                    'type': 'list' +        "config": { +            "elements": "dict", +            "options": { +                "ipv4": { +                    "elements": "dict", +                    "options": {"address": {"type": "str"}}, +                    "type": "list",                  }, -                'name': { -                    'required': True, -                    'type': 'str' +                "ipv6": { +                    "elements": "dict", +                    "options": {"address": {"type": "str"}}, +                    "type": "list",                  }, -                'vifs': { -                    'elements': 'dict', -                    'options': { -                        'ipv4': { -                            'elements': 'dict', -                            'options': { -                                'address': { -                                    'type': 'str' -                                } -                            }, -                            'type': 'list' +                "name": {"required": True, "type": "str"}, +                "vifs": { +                    "elements": "dict", +                    "options": { +                        "ipv4": { +                            "elements": "dict", +                            "options": {"address": {"type": "str"}}, +                            "type": "list",                          }, -                        'ipv6': { -                            'elements': 'dict', -                            'options': { -                                'address': { -                                    'type': 'str' -                                } -                            }, -                            'type': 'list' +                        "ipv6": { +                            "elements": "dict", +                            "options": {"address": {"type": "str"}}, +                            "type": "list",                          }, -                        'vlan_id': { -                            'type': 'int' -                        } +                        "vlan_id": {"type": "int"},                      }, -                    'type': 'list' -                } +                    "type": "list", +                },              }, -            'type': 'list' +            "type": "list", +        }, +        "state": { +            "choices": ["merged", "replaced", "overridden", "deleted"], +            "default": "merged", +            "type": "str",          }, -        'state': { -            'choices': ['merged', 'replaced', 'overridden', 'deleted'], -            'default': 'merged', -            'type': 'str' -        }      }  # pylint: disable=C0301 diff --git a/plugins/module_utils/network/vyos/config/interfaces/interfaces.py b/plugins/module_utils/network/vyos/config/interfaces/interfaces.py index b17971c..1b6584b 100644 --- a/plugins/module_utils/network/vyos/config/interfaces/interfaces.py +++ b/plugins/module_utils/network/vyos/config/interfaces/interfaces.py @@ -10,6 +10,7 @@ created  """  from __future__ import absolute_import, division, print_function +  __metaclass__ = type @@ -17,12 +18,15 @@ from copy import deepcopy  from ansible.module_utils.network.common.cfg.base import ConfigBase  from ansible.module_utils.network.common.utils import to_list, dict_diff, remove_empties  from ansible.module_utils.six import iteritems -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.facts.facts import Facts - -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.utils.utils import search_obj_in_list, get_interface_type, dict_delete +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import ( +    Facts, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import ( +    search_obj_in_list, +    get_interface_type, +    dict_delete, +)  class Interfaces(ConfigBase): @@ -30,14 +34,9 @@ class Interfaces(ConfigBase):      The vyos_interfaces class      """ -    gather_subset = [ -        '!all', -        '!min', -    ] +    gather_subset = ["!all", "!min"] -    gather_network_resources = [ -        'interfaces' -    ] +    gather_network_resources = ["interfaces"]      def __init__(self, module):          super(Interfaces, self).__init__(module) @@ -48,9 +47,10 @@ class Interfaces(ConfigBase):          :rtype: A dictionary          :returns: The current configuration as a dictionary          """ -        facts, _warnings = Facts(self._module).get_facts(self.gather_subset, -                                                         self.gather_network_resources) -        interfaces_facts = facts['ansible_network_resources'].get('interfaces') +        facts, _warnings = Facts(self._module).get_facts( +            self.gather_subset, self.gather_network_resources +        ) +        interfaces_facts = facts["ansible_network_resources"].get("interfaces")          if not interfaces_facts:              return []          return interfaces_facts @@ -60,7 +60,7 @@ class Interfaces(ConfigBase):           :rtype: A dictionary          :returns: The result from module execution          """ -        result = {'changed': False} +        result = {"changed": False}          commands = list()          warnings = list() @@ -71,20 +71,20 @@ class Interfaces(ConfigBase):                  resp = self._connection.edit_config(commands, commit=False)              else:                  resp = self._connection.edit_config(commands) -            result['changed'] = True +            result["changed"] = True -        result['commands'] = commands +        result["commands"] = commands          if self._module._diff: -            result['diff'] = resp['diff'] if result['changed'] else None +            result["diff"] = resp["diff"] if result["changed"] else None          changed_interfaces_facts = self.get_interfaces_facts() -        result['before'] = existing_interfaces_facts -        if result['changed']: -            result['after'] = changed_interfaces_facts +        result["before"] = existing_interfaces_facts +        if result["changed"]: +            result["after"] = changed_interfaces_facts -        result['warnings'] = warnings +        result["warnings"] = warnings          return result      def set_config(self, existing_interfaces_facts): @@ -95,7 +95,7 @@ class Interfaces(ConfigBase):          :returns: the commands necessary to migrate the current configuration                    to the desired configuration          """ -        want = self._module.params['config'] +        want = self._module.params["config"]          have = existing_interfaces_facts          resp = self.set_state(want, have)          return to_list(resp) @@ -110,48 +110,31 @@ class Interfaces(ConfigBase):                    to the desired configuration          """          commands = [] -        state = self._module.params['state'] -        if state == 'overridden': +        state = self._module.params["state"] +        if state == "overridden":              commands.extend(self._state_overridden(want=want, have=have)) -        elif state == 'deleted': +        elif state == "deleted":              if not want:                  for intf in have: -                    commands.extend( -                        self._state_deleted( -                            {'name': intf['name']}, -                            intf -                        ) -                    ) +                    commands.extend(self._state_deleted({"name": intf["name"]}, intf))              else:                  for item in want: -                    obj_in_have = search_obj_in_list(item['name'], have) -                    commands.extend( -                        self._state_deleted( -                            item, obj_in_have -                        ) -                    ) +                    obj_in_have = search_obj_in_list(item["name"], have) +                    commands.extend(self._state_deleted(item, obj_in_have))          else:              for item in want: -                name = item['name'] +                name = item["name"]                  obj_in_have = search_obj_in_list(name, have)                  if not obj_in_have: -                    obj_in_have = {'name': item['name']} +                    obj_in_have = {"name": item["name"]} -                elif state == 'merged': -                    commands.extend( -                        self._state_merged( -                            item, obj_in_have -                        ) -                    ) +                elif state == "merged": +                    commands.extend(self._state_merged(item, obj_in_have)) -                elif state == 'replaced': -                    commands.extend( -                        self._state_replaced( -                            item, obj_in_have -                        ) -                    ) +                elif state == "replaced": +                    commands.extend(self._state_replaced(item, obj_in_have))          return commands @@ -180,12 +163,12 @@ class Interfaces(ConfigBase):          commands = []          for intf in have: -            intf_in_want = search_obj_in_list(intf['name'], want) +            intf_in_want = search_obj_in_list(intf["name"], want)              if not intf_in_want: -                commands.extend(self._state_deleted({'name': intf['name']}, intf)) +                commands.extend(self._state_deleted({"name": intf["name"]}, intf))          for intf in want: -            intf_in_have = search_obj_in_list(intf['name'], have) +            intf_in_have = search_obj_in_list(intf["name"], have)              commands.extend(self._state_replaced(intf, intf_in_have))          return commands @@ -201,25 +184,38 @@ class Interfaces(ConfigBase):          want_copy = deepcopy(remove_empties(want))          have_copy = deepcopy(have) -        want_vifs = want_copy.pop('vifs', []) -        have_vifs = have_copy.pop('vifs', []) +        want_vifs = want_copy.pop("vifs", []) +        have_vifs = have_copy.pop("vifs", [])          updates = dict_diff(have_copy, want_copy)          if updates:              for key, value in iteritems(updates): -                commands.append(self._compute_commands(key=key, value=value, interface=want_copy['name'])) +                commands.append( +                    self._compute_commands( +                        key=key, value=value, interface=want_copy["name"] +                    ) +                )          if want_vifs:              for want_vif in want_vifs: -                have_vif = search_obj_in_list(want_vif['vlan_id'], have_vifs, key='vlan_id') +                have_vif = search_obj_in_list( +                    want_vif["vlan_id"], have_vifs, key="vlan_id" +                )                  if not have_vif: -                    have_vif = {'vlan_id': want_vif['vlan_id'], 'enabled': True} +                    have_vif = {"vlan_id": want_vif["vlan_id"], "enabled": True}                  vif_updates = dict_diff(have_vif, want_vif)                  if vif_updates:                      for key, value in iteritems(vif_updates): -                        commands.append(self._compute_commands(key=key, value=value, interface=want_copy['name'], vif=want_vif['vlan_id'])) +                        commands.append( +                            self._compute_commands( +                                key=key, +                                value=value, +                                interface=want_copy["name"], +                                vif=want_vif["vlan_id"], +                            ) +                        )          return commands @@ -235,41 +231,67 @@ class Interfaces(ConfigBase):          want_copy = deepcopy(remove_empties(want))          have_copy = deepcopy(have) -        want_vifs = want_copy.pop('vifs', []) -        have_vifs = have_copy.pop('vifs', []) +        want_vifs = want_copy.pop("vifs", []) +        have_vifs = have_copy.pop("vifs", [])          for key in dict_delete(have_copy, want_copy).keys(): -            if key == 'enabled': +            if key == "enabled":                  continue -            commands.append(self._compute_commands(key=key, interface=want_copy['name'], remove=True)) -        if have_copy['enabled'] is False: -            commands.append(self._compute_commands(key='enabled', value=True, interface=want_copy['name'])) +            commands.append( +                self._compute_commands( +                    key=key, interface=want_copy["name"], remove=True +                ) +            ) +        if have_copy["enabled"] is False: +            commands.append( +                self._compute_commands( +                    key="enabled", value=True, interface=want_copy["name"] +                ) +            )          if have_vifs:              for have_vif in have_vifs: -                want_vif = search_obj_in_list(have_vif['vlan_id'], want_vifs, key='vlan_id') +                want_vif = search_obj_in_list( +                    have_vif["vlan_id"], want_vifs, key="vlan_id" +                )                  if not want_vif: -                    want_vif = {'vlan_id': have_vif['vlan_id'], 'enabled': True} +                    want_vif = {"vlan_id": have_vif["vlan_id"], "enabled": True}                  for key in dict_delete(have_vif, want_vif).keys(): -                    if key == 'enabled': +                    if key == "enabled":                          continue -                    commands.append(self._compute_commands(key=key, interface=want_copy['name'], vif=want_vif['vlan_id'], remove=True)) -                if have_vif['enabled'] is False: -                    commands.append(self._compute_commands(key='enabled', value=True, interface=want_copy['name'], vif=want_vif['vlan_id'])) +                    commands.append( +                        self._compute_commands( +                            key=key, +                            interface=want_copy["name"], +                            vif=want_vif["vlan_id"], +                            remove=True, +                        ) +                    ) +                if have_vif["enabled"] is False: +                    commands.append( +                        self._compute_commands( +                            key="enabled", +                            value=True, +                            interface=want_copy["name"], +                            vif=want_vif["vlan_id"], +                        ) +                    )          return commands      def _compute_commands(self, interface, key, vif=None, value=None, remove=False): -        intf_context = 'interfaces {0} {1}'.format(get_interface_type(interface), interface) -        set_cmd = 'set {0}'.format(intf_context) -        del_cmd = 'delete {0}'.format(intf_context) +        intf_context = "interfaces {0} {1}".format( +            get_interface_type(interface), interface +        ) +        set_cmd = "set {0}".format(intf_context) +        del_cmd = "delete {0}".format(intf_context)          if vif: -            set_cmd = set_cmd + (' vif {0}'.format(vif)) -            del_cmd = del_cmd + (' vif {0}'.format(vif)) +            set_cmd = set_cmd + (" vif {0}".format(vif)) +            del_cmd = del_cmd + (" vif {0}".format(vif)) -        if key == 'enabled': +        if key == "enabled":              if not value:                  command = "{0} disable".format(set_cmd)              else: diff --git a/plugins/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py b/plugins/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py index 9027c84..4260f35 100644 --- a/plugins/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py +++ b/plugins/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py @@ -12,6 +12,7 @@ created  """  from __future__ import absolute_import, division, print_function +  __metaclass__ = type @@ -19,12 +20,15 @@ from copy import deepcopy  from ansible.module_utils.network.common.cfg.base import ConfigBase  from ansible.module_utils.network.common.utils import to_list, remove_empties  from ansible.module_utils.six import iteritems -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.facts.facts import Facts - -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.utils.utils import search_obj_in_list, get_interface_type, diff_list_of_dicts +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import ( +    Facts, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import ( +    search_obj_in_list, +    get_interface_type, +    diff_list_of_dicts, +)  class L3_interfaces(ConfigBase): @@ -32,14 +36,9 @@ class L3_interfaces(ConfigBase):      The vyos_l3_interfaces class      """ -    gather_subset = [ -        '!all', -        '!min', -    ] +    gather_subset = ["!all", "!min"] -    gather_network_resources = [ -        'l3_interfaces', -    ] +    gather_network_resources = ["l3_interfaces"]      def __init__(self, module):          super(L3_interfaces, self).__init__(module) @@ -50,8 +49,10 @@ class L3_interfaces(ConfigBase):          :rtype: A dictionary          :returns: The current configuration as a dictionary          """ -        facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources) -        l3_interfaces_facts = facts['ansible_network_resources'].get('l3_interfaces') +        facts, _warnings = Facts(self._module).get_facts( +            self.gather_subset, self.gather_network_resources +        ) +        l3_interfaces_facts = facts["ansible_network_resources"].get("l3_interfaces")          if not l3_interfaces_facts:              return []          return l3_interfaces_facts @@ -62,7 +63,7 @@ class L3_interfaces(ConfigBase):          :rtype: A dictionary          :returns: The result from module execution          """ -        result = {'changed': False} +        result = {"changed": False}          warnings = list()          commands = list() @@ -73,20 +74,20 @@ class L3_interfaces(ConfigBase):                  resp = self._connection.edit_config(commands, commit=False)              else:                  resp = self._connection.edit_config(commands) -            result['changed'] = True +            result["changed"] = True -        result['commands'] = commands +        result["commands"] = commands          if self._module._diff: -            result['diff'] = resp['diff'] if result['changed'] else None +            result["diff"] = resp["diff"] if result["changed"] else None          changed_l3_interfaces_facts = self.get_l3_interfaces_facts() -        result['before'] = existing_l3_interfaces_facts -        if result['changed']: -            result['after'] = changed_l3_interfaces_facts +        result["before"] = existing_l3_interfaces_facts +        if result["changed"]: +            result["after"] = changed_l3_interfaces_facts -        result['warnings'] = warnings +        result["warnings"] = warnings          return result      def set_config(self, existing_l3_interfaces_facts): @@ -97,7 +98,7 @@ class L3_interfaces(ConfigBase):          :returns: the commands necessary to migrate the current configuration                    to the desired configuration          """ -        want = self._module.params['config'] +        want = self._module.params["config"]          have = existing_l3_interfaces_facts          resp = self.set_state(want, have)          return to_list(resp) @@ -112,48 +113,31 @@ class L3_interfaces(ConfigBase):                    to the desired configuration          """          commands = [] -        state = self._module.params['state'] -        if state == 'overridden': +        state = self._module.params["state"] +        if state == "overridden":              commands.extend(self._state_overridden(want=want, have=have)) -        elif state == 'deleted': +        elif state == "deleted":              if not want:                  for intf in have: -                    commands.extend( -                        self._state_deleted( -                            {'name': intf['name']}, -                            intf -                        ) -                    ) +                    commands.extend(self._state_deleted({"name": intf["name"]}, intf))              else:                  for item in want: -                    obj_in_have = search_obj_in_list(item['name'], have) -                    commands.extend( -                        self._state_deleted( -                            item, obj_in_have -                        ) -                    ) +                    obj_in_have = search_obj_in_list(item["name"], have) +                    commands.extend(self._state_deleted(item, obj_in_have))          else:              for item in want: -                name = item['name'] +                name = item["name"]                  obj_in_have = search_obj_in_list(name, have)                  if not obj_in_have: -                    obj_in_have = {'name': item['name']} +                    obj_in_have = {"name": item["name"]} -                if state == 'merged': -                    commands.extend( -                        self._state_merged( -                            item, obj_in_have -                        ) -                    ) +                if state == "merged": +                    commands.extend(self._state_merged(item, obj_in_have)) -                elif state == 'replaced': -                    commands.extend( -                        self._state_replaced( -                            item, obj_in_have -                        ) -                    ) +                elif state == "replaced": +                    commands.extend(self._state_replaced(item, obj_in_have))          return commands @@ -182,12 +166,12 @@ class L3_interfaces(ConfigBase):          commands = []          for intf in have: -            intf_in_want = search_obj_in_list(intf['name'], want) +            intf_in_want = search_obj_in_list(intf["name"], want)              if not intf_in_want: -                commands.extend(self._state_deleted({'name': intf['name']}, intf)) +                commands.extend(self._state_deleted({"name": intf["name"]}, intf))          for intf in want: -            intf_in_have = search_obj_in_list(intf['name'], have) +            intf_in_have = search_obj_in_list(intf["name"], have)              commands.extend(self._state_replaced(intf, intf_in_have))          return commands @@ -203,22 +187,35 @@ class L3_interfaces(ConfigBase):          want_copy = deepcopy(remove_empties(want))          have_copy = deepcopy(remove_empties(have)) -        want_vifs = want_copy.pop('vifs', []) -        have_vifs = have_copy.pop('vifs', []) +        want_vifs = want_copy.pop("vifs", []) +        have_vifs = have_copy.pop("vifs", [])          for update in self._get_updates(want_copy, have_copy):              for key, value in iteritems(update): -                commands.append(self._compute_commands(key=key, value=value, interface=want_copy['name'])) +                commands.append( +                    self._compute_commands( +                        key=key, value=value, interface=want_copy["name"] +                    ) +                )          if want_vifs:              for want_vif in want_vifs: -                have_vif = search_obj_in_list(want_vif['vlan_id'], have_vifs, key='vlan_id') +                have_vif = search_obj_in_list( +                    want_vif["vlan_id"], have_vifs, key="vlan_id" +                )                  if not have_vif:                      have_vif = {}                  for update in self._get_updates(want_vif, have_vif):                      for key, value in iteritems(update): -                        commands.append(self._compute_commands(key=key, value=value, interface=want_copy['name'], vif=want_vif['vlan_id'])) +                        commands.append( +                            self._compute_commands( +                                key=key, +                                value=value, +                                interface=want_copy["name"], +                                vif=want_vif["vlan_id"], +                            ) +                        )          return commands @@ -233,33 +230,49 @@ class L3_interfaces(ConfigBase):          want_copy = deepcopy(remove_empties(want))          have_copy = deepcopy(have) -        want_vifs = want_copy.pop('vifs', []) -        have_vifs = have_copy.pop('vifs', []) +        want_vifs = want_copy.pop("vifs", []) +        have_vifs = have_copy.pop("vifs", [])          for update in self._get_updates(have_copy, want_copy):              for key, value in iteritems(update): -                commands.append(self._compute_commands(key=key, value=value, interface=want_copy['name'], remove=True)) +                commands.append( +                    self._compute_commands( +                        key=key, value=value, interface=want_copy["name"], remove=True +                    ) +                )          if have_vifs:              for have_vif in have_vifs: -                want_vif = search_obj_in_list(have_vif['vlan_id'], want_vifs, key='vlan_id') +                want_vif = search_obj_in_list( +                    have_vif["vlan_id"], want_vifs, key="vlan_id" +                )                  if not want_vif: -                    want_vif = {'vlan_id': have_vif['vlan_id']} +                    want_vif = {"vlan_id": have_vif["vlan_id"]}                  for update in self._get_updates(have_vif, want_vif):                      for key, value in iteritems(update): -                        commands.append(self._compute_commands(key=key, interface=want_copy['name'], value=value, vif=want_vif['vlan_id'], remove=True)) +                        commands.append( +                            self._compute_commands( +                                key=key, +                                interface=want_copy["name"], +                                value=value, +                                vif=want_vif["vlan_id"], +                                remove=True, +                            ) +                        )          return commands      def _compute_commands(self, interface, key, vif=None, value=None, remove=False): -        intf_context = 'interfaces {0} {1}'.format(get_interface_type(interface), interface) -        set_cmd = 'set {0}'.format(intf_context) -        del_cmd = 'delete {0}'.format(intf_context) +        intf_context = "interfaces {0} {1}".format( +            get_interface_type(interface), interface +        ) +        set_cmd = "set {0}".format(intf_context) +        del_cmd = "delete {0}".format(intf_context)          if vif: -            set_cmd = set_cmd + (' vif {0}'.format(vif)) -            del_cmd = del_cmd + (' vif {0}'.format(vif)) +            set_cmd = set_cmd + (" vif {0}".format(vif)) +            del_cmd = del_cmd + (" vif {0}".format(vif))          if remove:              command = "{0} {1} '{2}'".format(del_cmd, key, value) @@ -271,7 +284,7 @@ class L3_interfaces(ConfigBase):      def _get_updates(self, want, have):          updates = [] -        updates = diff_list_of_dicts(want.get('ipv4', []), have.get('ipv4', [])) -        updates.extend(diff_list_of_dicts(want.get('ipv6', []), have.get('ipv6', []))) +        updates = diff_list_of_dicts(want.get("ipv4", []), have.get("ipv4", [])) +        updates.extend(diff_list_of_dicts(want.get("ipv6", []), have.get("ipv6", [])))          return updates diff --git a/plugins/module_utils/network/vyos/facts/facts.py b/plugins/module_utils/network/vyos/facts/facts.py index a065eaf..f92c761 100644 --- a/plugins/module_utils/network/vyos/facts/facts.py +++ b/plugins/module_utils/network/vyos/facts/facts.py @@ -8,34 +8,35 @@ calls the appropriate facts gathering function  """  from __future__ import absolute_import, division, print_function +  __metaclass__ = type -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.argspec.facts.facts import FactsArgs +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.facts.facts import ( +    FactsArgs, +)  from ansible.module_utils.network.common.facts.facts import FactsBase -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.facts.interfaces.interfaces import InterfacesFacts +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.interfaces.interfaces import ( +    InterfacesFacts, +) -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.facts.l3_interfaces.l3_interfaces import L3_interfacesFacts +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.l3_interfaces.l3_interfaces import ( +    L3_interfacesFacts, +) -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.facts.legacy.base import Default, Neighbors, Config +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.legacy.base import ( +    Default, +    Neighbors, +    Config, +) -from ansible.module_utils. \ -    network.vyos.vyos import run_commands, get_capabilities +from ansible.module_utils.network.vyos.vyos import run_commands, get_capabilities -FACT_LEGACY_SUBSETS = dict( -    default=Default, -    neighbors=Neighbors, -    config=Config -) +FACT_LEGACY_SUBSETS = dict(default=Default, neighbors=Neighbors, config=Config)  FACT_RESOURCE_SUBSETS = dict( -    interfaces=InterfacesFacts, -    l3_interfaces=L3_interfacesFacts +    interfaces=InterfacesFacts, l3_interfaces=L3_interfacesFacts  ) @@ -58,10 +59,13 @@ class Facts(FactsBase):          :rtype: dict          :return: the facts gathered          """ -        netres_choices = FactsArgs.argument_spec['gather_network_resources'].get('choices', []) +        netres_choices = FactsArgs.argument_spec["gather_network_resources"].get( +            "choices", [] +        )          if self.VALID_RESOURCE_SUBSETS: -            self.get_network_resources_facts(netres_choices, FACT_RESOURCE_SUBSETS, -                                             resource_facts_type, data) +            self.get_network_resources_facts( +                netres_choices, FACT_RESOURCE_SUBSETS, resource_facts_type, data +            )          if self.VALID_LEGACY_GATHER_SUBSETS:              self.get_network_legacy_facts(FACT_LEGACY_SUBSETS, legacy_facts_type) diff --git a/plugins/module_utils/network/vyos/facts/interfaces/interfaces.py b/plugins/module_utils/network/vyos/facts/interfaces/interfaces.py index cc89e4f..9d8d008 100644 --- a/plugins/module_utils/network/vyos/facts/interfaces/interfaces.py +++ b/plugins/module_utils/network/vyos/facts/interfaces/interfaces.py @@ -11,22 +11,23 @@ based on the configuration.  """  from __future__ import absolute_import, division, print_function +  __metaclass__ = type  from re import findall, M  from copy import deepcopy  from ansible.module_utils.network.common import utils -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.argspec.interfaces.interfaces import InterfacesArgs - +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.interfaces.interfaces import ( +    InterfacesArgs, +)  class InterfacesFacts(object):      """ The vyos interfaces fact class      """ -    def __init__(self, module, subspec='config', options='options'): +    def __init__(self, module, subspec="config", options="options"):          self._module = module          self.argument_spec = InterfacesArgs.argument_spec          spec = deepcopy(self.argument_spec) @@ -49,27 +50,30 @@ class InterfacesFacts(object):          :returns: facts          """          if not data: -            data = connection.get_config(flags=['| grep interfaces']) +            data = connection.get_config(flags=["| grep interfaces"])          objs = [] -        interface_names = findall(r'^set interfaces (?:ethernet|bonding|vti|loopback|vxlan) (?:\'*)(\S+)(?:\'*)', -                                  data, M) +        interface_names = findall( +            r"^set interfaces (?:ethernet|bonding|vti|loopback|vxlan) (?:\'*)(\S+)(?:\'*)", +            data, +            M, +        )          if interface_names:              for interface in set(interface_names): -                intf_regex = r' %s .+$' % interface.strip("'") +                intf_regex = r" %s .+$" % interface.strip("'")                  cfg = findall(intf_regex, data, M)                  obj = self.render_config(cfg) -                obj['name'] = interface.strip("'") +                obj["name"] = interface.strip("'")                  if obj:                      objs.append(obj)          facts = {}          if objs: -            facts['interfaces'] = [] -            params = utils.validate_config(self.argument_spec, {'config': objs}) -            for cfg in params['config']: -                facts['interfaces'].append(utils.remove_empties(cfg)) +            facts["interfaces"] = [] +            params = utils.validate_config(self.argument_spec, {"config": objs}) +            for cfg in params["config"]: +                facts["interfaces"].append(utils.remove_empties(cfg)) -        ansible_facts['ansible_network_resources'].update(facts) +        ansible_facts["ansible_network_resources"].update(facts)          return ansible_facts      def render_config(self, conf): @@ -82,28 +86,27 @@ class InterfacesFacts(object):          :rtype: dictionary          :returns: The generated config          """ -        vif_conf = '\n'.join(filter(lambda x: ('vif' in x), conf)) -        eth_conf = '\n'.join(filter(lambda x: ('vif' not in x), conf)) -        config = self.parse_attribs( -            ['description', 'speed', 'mtu', 'duplex'], eth_conf) -        config['vifs'] = self.parse_vifs(vif_conf) +        vif_conf = "\n".join(filter(lambda x: ("vif" in x), conf)) +        eth_conf = "\n".join(filter(lambda x: ("vif" not in x), conf)) +        config = self.parse_attribs(["description", "speed", "mtu", "duplex"], eth_conf) +        config["vifs"] = self.parse_vifs(vif_conf)          return utils.remove_empties(config)      def parse_vifs(self, conf): -        vif_names = findall(r'vif (?:\'*)(\d+)(?:\'*)', conf, M) +        vif_names = findall(r"vif (?:\'*)(\d+)(?:\'*)", conf, M)          vifs_list = None          if vif_names:              vifs_list = []              for vif in set(vif_names): -                vif_regex = r' %s .+$' % vif -                cfg = '\n'.join(findall(vif_regex, conf, M)) -                obj = self.parse_attribs(['description', 'mtu'], cfg) -                obj['vlan_id'] = int(vif) +                vif_regex = r" %s .+$" % vif +                cfg = "\n".join(findall(vif_regex, conf, M)) +                obj = self.parse_attribs(["description", "mtu"], cfg) +                obj["vlan_id"] = int(vif)                  if obj:                      vifs_list.append(obj) -            vifs_list = sorted(vifs_list, key=lambda i: i['vlan_id']) +            vifs_list = sorted(vifs_list, key=lambda i: i["vlan_id"])          return vifs_list @@ -111,15 +114,15 @@ class InterfacesFacts(object):          config = {}          for item in attribs:              value = utils.parse_conf_arg(conf, item) -            if value and item == 'mtu': +            if value and item == "mtu":                  config[item] = int(value.strip("'"))              elif value:                  config[item] = value.strip("'")              else:                  config[item] = None -        if 'disable' in conf: -            config['enabled'] = False +        if "disable" in conf: +            config["enabled"] = False          else: -            config['enabled'] = True +            config["enabled"] = True          return utils.remove_empties(config) diff --git a/plugins/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py b/plugins/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py index 61f635b..306a73b 100644 --- a/plugins/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py +++ b/plugins/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py @@ -11,6 +11,7 @@ based on the configuration.  """  from __future__ import absolute_import, division, print_function +  __metaclass__ = type @@ -19,16 +20,16 @@ from copy import deepcopy  from ansible.module_utils.network.common import utils  from ansible.module_utils.six import iteritems  from ansible.module_utils.compat import ipaddress -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.argspec.l3_interfaces.l3_interfaces import L3_interfacesArgs - +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.l3_interfaces.l3_interfaces import ( +    L3_interfacesArgs, +)  class L3_interfacesFacts(object):      """ The vyos l3_interfaces fact class      """ -    def __init__(self, module, subspec='config', options='options'): +    def __init__(self, module, subspec="config", options="options"):          self._module = module          self.argument_spec = L3_interfacesArgs.argument_spec          spec = deepcopy(self.argument_spec) @@ -55,25 +56,29 @@ class L3_interfacesFacts(object):          # operate on a collection of resource x          objs = [] -        interface_names = re.findall(r'set interfaces (?:ethernet|bonding|vti|vxlan) (?:\'*)(\S+)(?:\'*)', data, re.M) +        interface_names = re.findall( +            r"set interfaces (?:ethernet|bonding|vti|vxlan) (?:\'*)(\S+)(?:\'*)", +            data, +            re.M, +        )          if interface_names:              for interface in set(interface_names): -                intf_regex = r' %s .+$' % interface +                intf_regex = r" %s .+$" % interface                  cfg = re.findall(intf_regex, data, re.M)                  obj = self.render_config(cfg) -                obj['name'] = interface.strip("'") +                obj["name"] = interface.strip("'")                  if obj:                      objs.append(obj) -        ansible_facts['ansible_network_resources'].pop('l3_interfaces', None) +        ansible_facts["ansible_network_resources"].pop("l3_interfaces", None)          facts = {}          if objs: -            facts['l3_interfaces'] = [] -            params = utils.validate_config(self.argument_spec, {'config': objs}) -            for cfg in params['config']: -                facts['l3_interfaces'].append(utils.remove_empties(cfg)) +            facts["l3_interfaces"] = [] +            params = utils.validate_config(self.argument_spec, {"config": objs}) +            for cfg in params["config"]: +                facts["l3_interfaces"].append(utils.remove_empties(cfg)) -        ansible_facts['ansible_network_resources'].update(facts) +        ansible_facts["ansible_network_resources"].update(facts)          return ansible_facts      def render_config(self, conf): @@ -84,23 +89,23 @@ class L3_interfacesFacts(object):          :rtype: dictionary          :returns: The generated config          """ -        vif_conf = '\n'.join(filter(lambda x: ('vif' in x), conf)) -        eth_conf = '\n'.join(filter(lambda x: ('vif' not in x), conf)) +        vif_conf = "\n".join(filter(lambda x: ("vif" in x), conf)) +        eth_conf = "\n".join(filter(lambda x: ("vif" not in x), conf))          config = self.parse_attribs(eth_conf) -        config['vifs'] = self.parse_vifs(vif_conf) +        config["vifs"] = self.parse_vifs(vif_conf)          return utils.remove_empties(config)      def parse_vifs(self, conf): -        vif_names = re.findall(r'vif (\d+)', conf, re.M) +        vif_names = re.findall(r"vif (\d+)", conf, re.M)          vifs_list = None          if vif_names:              vifs_list = []              for vif in set(vif_names): -                vif_regex = r' %s .+$' % vif -                cfg = '\n'.join(re.findall(vif_regex, conf, re.M)) +                vif_regex = r" %s .+$" % vif +                cfg = "\n".join(re.findall(vif_regex, conf, re.M))                  obj = self.parse_attribs(cfg) -                obj['vlan_id'] = vif +                obj["vlan_id"] = vif                  if obj:                      vifs_list.append(obj) @@ -108,22 +113,22 @@ class L3_interfacesFacts(object):      def parse_attribs(self, conf):          config = {} -        ipaddrs = re.findall(r'address (\S+)', conf, re.M) -        config['ipv4'] = [] -        config['ipv6'] = [] +        ipaddrs = re.findall(r"address (\S+)", conf, re.M) +        config["ipv4"] = [] +        config["ipv6"] = []          for item in ipaddrs:              item = item.strip("'") -            if item == 'dhcp': -                config['ipv4'].append({'address': item}) -            elif item == 'dhcpv6': -                config['ipv6'].append({'address': item}) +            if item == "dhcp": +                config["ipv4"].append({"address": item}) +            elif item == "dhcpv6": +                config["ipv6"].append({"address": item})              else:                  ip_version = ipaddress.ip_address(item.split("/")[0]).version                  if ip_version == 4: -                    config['ipv4'].append({'address': item}) +                    config["ipv4"].append({"address": item})                  else: -                    config['ipv6'].append({'address': item}) +                    config["ipv6"].append({"address": item})          for key, value in iteritems(config):              if value == []: diff --git a/plugins/module_utils/network/vyos/facts/legacy/base.py b/plugins/module_utils/network/vyos/facts/legacy/base.py index cdf0cce..a05516d 100644 --- a/plugins/module_utils/network/vyos/facts/legacy/base.py +++ b/plugins/module_utils/network/vyos/facts/legacy/base.py @@ -10,13 +10,13 @@ based on the configuration.  """  from __future__ import absolute_import, division, print_function +  __metaclass__ = type  import platform  import re -from ansible.module_utils. \ -    network.vyos.vyos import run_commands, get_capabilities +from ansible.module_utils.network.vyos.vyos import run_commands, get_capabilities  class LegacyFactsBase(object): @@ -35,18 +35,16 @@ class LegacyFactsBase(object):  class Default(LegacyFactsBase): -    COMMANDS = [ -        'show version', -    ] +    COMMANDS = ["show version"]      def populate(self):          super(Default, self).populate()          data = self.responses[0] -        self.facts['serialnum'] = self.parse_serialnum(data) +        self.facts["serialnum"] = self.parse_serialnum(data)          self.facts.update(self.platform_facts())      def parse_serialnum(self, data): -        match = re.search(r'HW S/N:\s+(\S+)', data) +        match = re.search(r"HW S/N:\s+(\S+)", data)          if match:              return match.group(1) @@ -54,80 +52,74 @@ class Default(LegacyFactsBase):          platform_facts = {}          resp = get_capabilities(self.module) -        device_info = resp['device_info'] +        device_info = resp["device_info"] -        platform_facts['system'] = device_info['network_os'] +        platform_facts["system"] = device_info["network_os"] -        for item in ('model', 'image', 'version', 'platform', 'hostname'): -            val = device_info.get('network_os_%s' % item) +        for item in ("model", "image", "version", "platform", "hostname"): +            val = device_info.get("network_os_%s" % item)              if val:                  platform_facts[item] = val -        platform_facts['api'] = resp['network_api'] -        platform_facts['python_version'] = platform.python_version() +        platform_facts["api"] = resp["network_api"] +        platform_facts["python_version"] = platform.python_version()          return platform_facts  class Config(LegacyFactsBase): -    COMMANDS = [ -        'show configuration commands', -        'show system commit', -    ] +    COMMANDS = ["show configuration commands", "show system commit"]      def populate(self):          super(Config, self).populate() -        self.facts['config'] = self.responses +        self.facts["config"] = self.responses          commits = self.responses[1]          entries = list()          entry = None -        for line in commits.split('\n'): -            match = re.match(r'(\d+)\s+(.+)by(.+)via(.+)', line) +        for line in commits.split("\n"): +            match = re.match(r"(\d+)\s+(.+)by(.+)via(.+)", line)              if match:                  if entry:                      entries.append(entry) -                entry = dict(revision=match.group(1), -                             datetime=match.group(2), -                             by=str(match.group(3)).strip(), -                             via=str(match.group(4)).strip(), -                             comment=None) +                entry = dict( +                    revision=match.group(1), +                    datetime=match.group(2), +                    by=str(match.group(3)).strip(), +                    via=str(match.group(4)).strip(), +                    comment=None, +                )              else: -                entry['comment'] = line.strip() +                entry["comment"] = line.strip() -        self.facts['commits'] = entries +        self.facts["commits"] = entries  class Neighbors(LegacyFactsBase): -    COMMANDS = [ -        'show lldp neighbors', -        'show lldp neighbors detail', -    ] +    COMMANDS = ["show lldp neighbors", "show lldp neighbors detail"]      def populate(self):          super(Neighbors, self).populate()          all_neighbors = self.responses[0] -        if 'LLDP not configured' not in all_neighbors: -            neighbors = self.parse( -                self.responses[1] -            ) -            self.facts['neighbors'] = self.parse_neighbors(neighbors) +        if "LLDP not configured" not in all_neighbors: +            neighbors = self.parse(self.responses[1]) +            self.facts["neighbors"] = self.parse_neighbors(neighbors)      def parse(self, data):          parsed = list()          values = None -        for line in data.split('\n'): +        for line in data.split("\n"):              if not line:                  continue -            elif line[0] == ' ': -                values += '\n%s' % line -            elif line.startswith('Interface'): +            elif line[0] == " ": +                values += "\n%s" % line +            elif line.startswith("Interface"):                  if values:                      parsed.append(values)                  values = line @@ -147,15 +139,15 @@ class Neighbors(LegacyFactsBase):          return facts      def parse_interface(self, data): -        match = re.search(r'^Interface:\s+(\S+),', data) +        match = re.search(r"^Interface:\s+(\S+),", data)          return match.group(1)      def parse_host(self, data): -        match = re.search(r'SysName:\s+(.+)$', data, re.M) +        match = re.search(r"SysName:\s+(.+)$", data, re.M)          if match:              return match.group(1)      def parse_port(self, data): -        match = re.search(r'PortDescr:\s+(.+)$', data, re.M) +        match = re.search(r"PortDescr:\s+(.+)$", data, re.M)          if match:              return match.group(1) diff --git a/plugins/module_utils/network/vyos/utils/utils.py b/plugins/module_utils/network/vyos/utils/utils.py index f59c24f..5fd0da2 100644 --- a/plugins/module_utils/network/vyos/utils/utils.py +++ b/plugins/module_utils/network/vyos/utils/utils.py @@ -7,10 +7,11 @@  from __future__ import absolute_import, division, print_function +  __metaclass__ = type -def search_obj_in_list(name, lst, key='name'): +def search_obj_in_list(name, lst, key="name"):      for item in lst:          if item[key] == name:              return item @@ -20,14 +21,14 @@ def search_obj_in_list(name, lst, key='name'):  def get_interface_type(interface):      """Gets the type of interface      """ -    if interface.startswith('eth'): -        return 'ethernet' -    elif interface.startswith('bond'): -        return 'bonding' -    elif interface.startswith('vti'): -        return 'vti' -    elif interface.startswith('lo'): -        return 'loopback' +    if interface.startswith("eth"): +        return "ethernet" +    elif interface.startswith("bond"): +        return "bonding" +    elif interface.startswith("vti"): +        return "vti" +    elif interface.startswith("lo"): +        return "loopback"  def dict_delete(base, comparable): diff --git a/plugins/module_utils/network/vyos/vyos.py b/plugins/module_utils/network/vyos/vyos.py index 2aa7b49..2d6a1a8 100644 --- a/plugins/module_utils/network/vyos/vyos.py +++ b/plugins/module_utils/network/vyos/vyos.py @@ -34,27 +34,23 @@ from ansible.module_utils.connection import Connection, ConnectionError  _DEVICE_CONFIGS = {}  vyos_provider_spec = { -    'host': dict(), -    'port': dict(type='int'), - -    'username': dict(fallback=(env_fallback, ['ANSIBLE_NET_USERNAME'])), -    'password': dict(fallback=(env_fallback, ['ANSIBLE_NET_PASSWORD']), no_log=True), -    'ssh_keyfile': dict(fallback=(env_fallback, ['ANSIBLE_NET_SSH_KEYFILE']), type='path'), - -    'timeout': dict(type='int'), -} -vyos_argument_spec = { -    'provider': dict(type='dict', options=vyos_provider_spec), +    "host": dict(), +    "port": dict(type="int"), +    "username": dict(fallback=(env_fallback, ["ANSIBLE_NET_USERNAME"])), +    "password": dict(fallback=(env_fallback, ["ANSIBLE_NET_PASSWORD"]), no_log=True), +    "ssh_keyfile": dict( +        fallback=(env_fallback, ["ANSIBLE_NET_SSH_KEYFILE"]), type="path" +    ), +    "timeout": dict(type="int"),  } +vyos_argument_spec = {"provider": dict(type="dict", options=vyos_provider_spec)}  vyos_top_spec = { -    'host': dict(removed_in_version=2.9), -    'port': dict(removed_in_version=2.9, type='int'), - -    'username': dict(removed_in_version=2.9), -    'password': dict(removed_in_version=2.9, no_log=True), -    'ssh_keyfile': dict(removed_in_version=2.9, type='path'), - -    'timeout': dict(removed_in_version=2.9, type='int'), +    "host": dict(removed_in_version=2.9), +    "port": dict(removed_in_version=2.9, type="int"), +    "username": dict(removed_in_version=2.9), +    "password": dict(removed_in_version=2.9, no_log=True), +    "ssh_keyfile": dict(removed_in_version=2.9, type="path"), +    "timeout": dict(removed_in_version=2.9, type="int"),  }  vyos_argument_spec.update(vyos_top_spec) @@ -64,27 +60,27 @@ def get_provider_argspec():  def get_connection(module): -    if hasattr(module, '_vyos_connection'): +    if hasattr(module, "_vyos_connection"):          return module._vyos_connection      capabilities = get_capabilities(module) -    network_api = capabilities.get('network_api') -    if network_api == 'cliconf': +    network_api = capabilities.get("network_api") +    if network_api == "cliconf":          module._vyos_connection = Connection(module._socket_path)      else: -        module.fail_json(msg='Invalid connection type %s' % network_api) +        module.fail_json(msg="Invalid connection type %s" % network_api)      return module._vyos_connection  def get_capabilities(module): -    if hasattr(module, '_vyos_capabilities'): +    if hasattr(module, "_vyos_capabilities"):          return module._vyos_capabilities      try:          capabilities = Connection(module._socket_path).get_capabilities()      except ConnectionError as exc: -        module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) +        module.fail_json(msg=to_text(exc, errors="surrogate_then_replace"))      module._vyos_capabilities = json.loads(capabilities)      return module._vyos_capabilities @@ -101,8 +97,8 @@ def get_config(module, flags=None, format=None):          try:              out = connection.get_config(flags=flags, format=format)          except ConnectionError as exc: -            module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) -        cfg = to_text(out, errors='surrogate_then_replace').strip() +            module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) +        cfg = to_text(out, errors="surrogate_then_replace").strip()          _DEVICE_CONFIGS = cfg          return cfg @@ -112,7 +108,7 @@ def run_commands(module, commands, check_rc=True):      try:          response = connection.run_commands(commands=commands, check_rc=check_rc)      except ConnectionError as exc: -        module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) +        module.fail_json(msg=to_text(exc, errors="surrogate_then_replace"))      return response @@ -120,8 +116,10 @@ def load_config(module, commands, commit=False, comment=None):      connection = get_connection(module)      try: -        response = connection.edit_config(candidate=commands, commit=commit, comment=comment) +        response = connection.edit_config( +            candidate=commands, commit=commit, comment=comment +        )      except ConnectionError as exc: -        module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) +        module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) -    return response.get('diff') +    return response.get("diff") diff --git a/plugins/modules/_vyos_interface.py b/plugins/modules/_vyos_interface.py index e4b989e..ee82107 100644 --- a/plugins/modules/_vyos_interface.py +++ b/plugins/modules/_vyos_interface.py @@ -19,9 +19,11 @@  # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.  # -ANSIBLE_METADATA = {'metadata_version': '1.1', -                    'status': ['deprecated'], -                    'supported_by': 'network'} +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": ["deprecated"], +    "supported_by": "network", +}  DOCUMENTATION = """ @@ -174,17 +176,19 @@ from ansible.module_utils._text import to_text  from ansible.module_utils.basic import AnsibleModule  from ansible.module_utils.connection import exec_command  from ansible.module_utils.network.common.utils import conditional, remove_default_spec -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import load_config, get_config - -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import vyos_argument_spec +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    load_config, +    get_config, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    vyos_argument_spec, +)  def search_obj_in_list(name, lst):      for o in lst: -        if o['name'] == name: +        if o["name"] == name:              return o      return None @@ -194,92 +198,92 @@ def map_obj_to_commands(updates):      commands = list()      want, have = updates -    params = ('speed', 'description', 'duplex', 'mtu') +    params = ("speed", "description", "duplex", "mtu")      for w in want: -        name = w['name'] -        disable = w['disable'] -        state = w['state'] +        name = w["name"] +        disable = w["disable"] +        state = w["state"]          obj_in_have = search_obj_in_list(name, have) -        set_interface = 'set interfaces ethernet ' + name -        delete_interface = 'delete interfaces ethernet ' + name +        set_interface = "set interfaces ethernet " + name +        delete_interface = "delete interfaces ethernet " + name -        if state == 'absent' and obj_in_have: +        if state == "absent" and obj_in_have:              commands.append(delete_interface) -        elif state in ('present', 'up', 'down'): +        elif state in ("present", "up", "down"):              if obj_in_have:                  for item in params:                      value = w.get(item)                      if value and value != obj_in_have.get(item): -                        if item == 'description': -                            value = "\'" + str(value) + "\'" -                        commands.append(set_interface + ' ' + item + ' ' + str(value)) - -                if disable and not obj_in_have.get('disable', False): -                    commands.append(set_interface + ' disable') -                elif not disable and obj_in_have.get('disable', False): -                    commands.append(delete_interface + ' disable') +                        if item == "description": +                            value = "'" + str(value) + "'" +                        commands.append(set_interface + " " + item + " " + str(value)) + +                if disable and not obj_in_have.get("disable", False): +                    commands.append(set_interface + " disable") +                elif not disable and obj_in_have.get("disable", False): +                    commands.append(delete_interface + " disable")              else:                  commands.append(set_interface)                  for item in params:                      value = w.get(item)                      if value: -                        if item == 'description': -                            value = "\'" + str(value) + "\'" -                        commands.append(set_interface + ' ' + item + ' ' + str(value)) +                        if item == "description": +                            value = "'" + str(value) + "'" +                        commands.append(set_interface + " " + item + " " + str(value))                  if disable: -                    commands.append(set_interface + ' disable') +                    commands.append(set_interface + " disable")      return commands  def map_config_to_obj(module): -    data = get_config(module, flags=['| grep interface']) +    data = get_config(module, flags=["| grep interface"])      obj = [] -    for line in data.split('\n'): -        if line.startswith('set interfaces ethernet'): -            match = re.search(r'set interfaces ethernet (\S+)', line, re.M) +    for line in data.split("\n"): +        if line.startswith("set interfaces ethernet"): +            match = re.search(r"set interfaces ethernet (\S+)", line, re.M)              name = match.group(1)              if name:                  interface = {}                  for item in obj: -                    if item['name'] == name: +                    if item["name"] == name:                          interface = item                          break                  if not interface: -                    interface = {'name': name} +                    interface = {"name": name}                      obj.append(interface) -                match = re.search(r'%s (\S+)' % name, line, re.M) +                match = re.search(r"%s (\S+)" % name, line, re.M)                  if match:                      param = match.group(1) -                    if param == 'description': -                        match = re.search(r'description (.+)', line, re.M) +                    if param == "description": +                        match = re.search(r"description (.+)", line, re.M)                          description = match.group(1).strip("'") -                        interface['description'] = description -                    elif param == 'speed': -                        match = re.search(r'speed (\S+)', line, re.M) +                        interface["description"] = description +                    elif param == "speed": +                        match = re.search(r"speed (\S+)", line, re.M)                          speed = match.group(1).strip("'") -                        interface['speed'] = speed -                    elif param == 'mtu': -                        match = re.search(r'mtu (\S+)', line, re.M) +                        interface["speed"] = speed +                    elif param == "mtu": +                        match = re.search(r"mtu (\S+)", line, re.M)                          mtu = match.group(1).strip("'") -                        interface['mtu'] = int(mtu) -                    elif param == 'duplex': -                        match = re.search(r'duplex (\S+)', line, re.M) +                        interface["mtu"] = int(mtu) +                    elif param == "duplex": +                        match = re.search(r"duplex (\S+)", line, re.M)                          duplex = match.group(1).strip("'") -                        interface['duplex'] = duplex -                    elif param.strip("'") == 'disable': -                        interface['disable'] = True +                        interface["duplex"] = duplex +                    elif param.strip("'") == "disable": +                        interface["disable"] = True      return obj  def map_params_to_obj(module):      obj = [] -    aggregate = module.params.get('aggregate') +    aggregate = module.params.get("aggregate")      if aggregate:          for item in aggregate:              for key in item: @@ -287,28 +291,28 @@ def map_params_to_obj(module):                      item[key] = module.params[key]              d = item.copy() -            if d['enabled']: -                d['disable'] = False +            if d["enabled"]: +                d["disable"] = False              else: -                d['disable'] = True +                d["disable"] = True              obj.append(d)      else:          params = { -            'name': module.params['name'], -            'description': module.params['description'], -            'speed': module.params['speed'], -            'mtu': module.params['mtu'], -            'duplex': module.params['duplex'], -            'delay': module.params['delay'], -            'state': module.params['state'], -            'neighbors': module.params['neighbors'] +            "name": module.params["name"], +            "description": module.params["description"], +            "speed": module.params["speed"], +            "mtu": module.params["mtu"], +            "duplex": module.params["duplex"], +            "delay": module.params["delay"], +            "state": module.params["state"], +            "neighbors": module.params["neighbors"],          } -        if module.params['enabled']: -            params.update({'disable': False}) +        if module.params["enabled"]: +            params.update({"disable": False})          else: -            params.update({'disable': True}) +            params.update({"disable": True})          obj.append(params)      return obj @@ -318,53 +322,65 @@ def check_declarative_intent_params(module, want, result):      failed_conditions = []      have_neighbors = None      for w in want: -        want_state = w.get('state') -        want_neighbors = w.get('neighbors') +        want_state = w.get("state") +        want_neighbors = w.get("neighbors") -        if want_state not in ('up', 'down') and not want_neighbors: +        if want_state not in ("up", "down") and not want_neighbors:              continue -        if result['changed']: -            sleep(w['delay']) +        if result["changed"]: +            sleep(w["delay"]) -        command = 'show interfaces ethernet %s' % w['name'] +        command = "show interfaces ethernet %s" % w["name"]          rc, out, err = exec_command(module, command)          if rc != 0: -            module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) - -        if want_state in ('up', 'down'): -            match = re.search(r'%s (\w+)' % 'state', out, re.M) +            module.fail_json( +                msg=to_text(err, errors="surrogate_then_replace"), +                command=command, +                rc=rc, +            ) + +        if want_state in ("up", "down"): +            match = re.search(r"%s (\w+)" % "state", out, re.M)              have_state = None              if match:                  have_state = match.group(1) -            if have_state is None or not conditional(want_state, have_state.strip().lower()): -                failed_conditions.append('state ' + 'eq(%s)' % want_state) +            if have_state is None or not conditional( +                want_state, have_state.strip().lower() +            ): +                failed_conditions.append("state " + "eq(%s)" % want_state)          if want_neighbors:              have_host = []              have_port = []              if have_neighbors is None: -                rc, have_neighbors, err = exec_command(module, 'show lldp neighbors detail') +                rc, have_neighbors, err = exec_command( +                    module, "show lldp neighbors detail" +                )                  if rc != 0: -                    module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc) +                    module.fail_json( +                        msg=to_text(err, errors="surrogate_then_replace"), +                        command=command, +                        rc=rc, +                    )              if have_neighbors: -                lines = have_neighbors.strip().split('Interface: ') +                lines = have_neighbors.strip().split("Interface: ")                  for line in lines: -                    field = line.split('\n') -                    if field[0].split(',')[0].strip() == w['name']: +                    field = line.split("\n") +                    if field[0].split(",")[0].strip() == w["name"]:                          for item in field: -                            if item.strip().startswith('SysName:'): -                                have_host.append(item.split(':')[1].strip()) -                            if item.strip().startswith('PortDescr:'): -                                have_port.append(item.split(':')[1].strip()) +                            if item.strip().startswith("SysName:"): +                                have_host.append(item.split(":")[1].strip()) +                            if item.strip().startswith("PortDescr:"): +                                have_port.append(item.split(":")[1].strip())              for item in want_neighbors: -                host = item.get('host') -                port = item.get('port') +                host = item.get("host") +                port = item.get("port")                  if host and host not in have_host: -                    failed_conditions.append('host ' + host) +                    failed_conditions.append("host " + host)                  if port and port not in have_port: -                    failed_conditions.append('port ' + port) +                    failed_conditions.append("port " + port)      return failed_conditions @@ -372,75 +388,73 @@ def check_declarative_intent_params(module, want, result):  def main():      """ main entry point for module execution      """ -    neighbors_spec = dict( -        host=dict(), -        port=dict() -    ) +    neighbors_spec = dict(host=dict(), port=dict())      element_spec = dict(          name=dict(),          description=dict(),          speed=dict(), -        mtu=dict(type='int'), -        duplex=dict(choices=['full', 'half', 'auto']), -        enabled=dict(default=True, type='bool'), -        neighbors=dict(type='list', elements='dict', options=neighbors_spec), -        delay=dict(default=10, type='int'), -        state=dict(default='present', -                   choices=['present', 'absent', 'up', 'down']) +        mtu=dict(type="int"), +        duplex=dict(choices=["full", "half", "auto"]), +        enabled=dict(default=True, type="bool"), +        neighbors=dict(type="list", elements="dict", options=neighbors_spec), +        delay=dict(default=10, type="int"), +        state=dict(default="present", choices=["present", "absent", "up", "down"]),      )      aggregate_spec = deepcopy(element_spec) -    aggregate_spec['name'] = dict(required=True) +    aggregate_spec["name"] = dict(required=True)      # remove default in aggregate spec, to handle common arguments      remove_default_spec(aggregate_spec)      argument_spec = dict( -        aggregate=dict(type='list', elements='dict', options=aggregate_spec), +        aggregate=dict(type="list", elements="dict", options=aggregate_spec)      )      argument_spec.update(element_spec)      argument_spec.update(vyos_argument_spec) -    required_one_of = [['name', 'aggregate']] -    mutually_exclusive = [['name', 'aggregate']] +    required_one_of = [["name", "aggregate"]] +    mutually_exclusive = [["name", "aggregate"]] -    required_together = [['speed', 'duplex']] -    module = AnsibleModule(argument_spec=argument_spec, -                           required_one_of=required_one_of, -                           mutually_exclusive=mutually_exclusive, -                           required_together=required_together, -                           supports_check_mode=True) +    required_together = [["speed", "duplex"]] +    module = AnsibleModule( +        argument_spec=argument_spec, +        required_one_of=required_one_of, +        mutually_exclusive=mutually_exclusive, +        required_together=required_together, +        supports_check_mode=True, +    )      warnings = list() -    result = {'changed': False} +    result = {"changed": False}      if warnings: -        result['warnings'] = warnings +        result["warnings"] = warnings      want = map_params_to_obj(module)      have = map_config_to_obj(module)      commands = map_obj_to_commands((want, have)) -    result['commands'] = commands +    result["commands"] = commands      if commands:          commit = not module.check_mode          diff = load_config(module, commands, commit=commit)          if diff:              if module._diff: -                result['diff'] = {'prepared': diff} -        result['changed'] = True +                result["diff"] = {"prepared": diff} +        result["changed"] = True      failed_conditions = check_declarative_intent_params(module, want, result)      if failed_conditions: -        msg = 'One or more conditional statements have not been satisfied' +        msg = "One or more conditional statements have not been satisfied"          module.fail_json(msg=msg, failed_conditions=failed_conditions)      module.exit_json(**result) -if __name__ == '__main__': +if __name__ == "__main__":      main() diff --git a/plugins/modules/_vyos_l3_interface.py b/plugins/modules/_vyos_l3_interface.py index 63f0873..430217c 100644 --- a/plugins/modules/_vyos_l3_interface.py +++ b/plugins/modules/_vyos_l3_interface.py @@ -19,9 +19,11 @@  # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.  # -ANSIBLE_METADATA = {'metadata_version': '1.1', -                    'status': ['deprecated'], -                    'supported_by': 'network'} +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": ["deprecated"], +    "supported_by": "network", +}  DOCUMENTATION = """ @@ -101,17 +103,19 @@ from copy import deepcopy  from ansible.module_utils.basic import AnsibleModule  from ansible.module_utils.network.common.utils import is_masklen, validate_ip_address  from ansible.module_utils.network.common.utils import remove_default_spec -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import load_config, run_commands - -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import vyos_argument_spec +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    load_config, +    run_commands, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    vyos_argument_spec, +)  def is_ipv4(value):      if value: -        address = value.split('/') +        address = value.split("/")          if is_masklen(address[1]) and validate_ip_address(address[0]):              return True      return False @@ -119,7 +123,7 @@ def is_ipv4(value):  def is_ipv6(value):      if value: -        address = value.split('/') +        address = value.split("/")          if 0 <= int(address[1]) <= 128:              try:                  socket.inet_pton(socket.AF_INET6, address[0]) @@ -131,7 +135,7 @@ def is_ipv6(value):  def search_obj_in_list(name, lst):      for o in lst: -        if o['name'] == name: +        if o["name"] == name:              return o      return None @@ -142,50 +146,58 @@ def map_obj_to_commands(updates, module):      want, have = updates      for w in want: -        name = w['name'] -        ipv4 = w['ipv4'] -        ipv6 = w['ipv6'] -        state = w['state'] +        name = w["name"] +        ipv4 = w["ipv4"] +        ipv6 = w["ipv6"] +        state = w["state"]          obj_in_have = search_obj_in_list(name, have) -        if state == 'absent' and obj_in_have: -            if not ipv4 and not ipv6 and (obj_in_have['ipv4'] or obj_in_have['ipv6']): +        if state == "absent" and obj_in_have: +            if not ipv4 and not ipv6 and (obj_in_have["ipv4"] or obj_in_have["ipv6"]):                  if name == "lo": -                    commands.append('delete interfaces loopback lo address') +                    commands.append("delete interfaces loopback lo address")                  else: -                    commands.append('delete interfaces ethernet ' + name + ' address') +                    commands.append("delete interfaces ethernet " + name + " address")              else: -                if ipv4 and ipv4 in obj_in_have['ipv4']: +                if ipv4 and ipv4 in obj_in_have["ipv4"]:                      if name == "lo": -                        commands.append('delete interfaces loopback lo address ' + ipv4) +                        commands.append("delete interfaces loopback lo address " + ipv4)                      else: -                        commands.append('delete interfaces ethernet ' + name + ' address ' + ipv4) -                if ipv6 and ipv6 in obj_in_have['ipv6']: +                        commands.append( +                            "delete interfaces ethernet " + name + " address " + ipv4 +                        ) +                if ipv6 and ipv6 in obj_in_have["ipv6"]:                      if name == "lo": -                        commands.append('delete interfaces loopback lo address ' + ipv6) +                        commands.append("delete interfaces loopback lo address " + ipv6)                      else: -                        commands.append('delete interfaces ethernet ' + name + ' address ' + ipv6) -        elif (state == 'present' and obj_in_have): -            if ipv4 and ipv4 not in obj_in_have['ipv4']: +                        commands.append( +                            "delete interfaces ethernet " + name + " address " + ipv6 +                        ) +        elif state == "present" and obj_in_have: +            if ipv4 and ipv4 not in obj_in_have["ipv4"]:                  if name == "lo": -                    commands.append('set interfaces loopback lo address ' + ipv4) +                    commands.append("set interfaces loopback lo address " + ipv4)                  else: -                    commands.append('set interfaces ethernet ' + name + ' address ' + ipv4) +                    commands.append( +                        "set interfaces ethernet " + name + " address " + ipv4 +                    ) -            if ipv6 and ipv6 not in obj_in_have['ipv6']: +            if ipv6 and ipv6 not in obj_in_have["ipv6"]:                  if name == "lo": -                    commands.append('set interfaces loopback lo address ' + ipv6) +                    commands.append("set interfaces loopback lo address " + ipv6)                  else: -                    commands.append('set interfaces ethernet ' + name + ' address ' + ipv6) +                    commands.append( +                        "set interfaces ethernet " + name + " address " + ipv6 +                    )      return commands  def map_config_to_obj(module):      obj = [] -    output = run_commands(module, ['show interfaces']) -    lines = re.split(r'\n[e|l]', output[0])[1:] +    output = run_commands(module, ["show interfaces"]) +    lines = re.split(r"\n[e|l]", output[0])[1:]      if len(lines) > 0:          for line in lines: @@ -195,22 +207,20 @@ def map_config_to_obj(module):                  ipv4 = []                  ipv6 = [] -                if splitted_line[0].lower().startswith('th'): -                    name = 'e' + splitted_line[0].lower() -                elif splitted_line[0].lower().startswith('o'): -                    name = 'l' + splitted_line[0].lower() +                if splitted_line[0].lower().startswith("th"): +                    name = "e" + splitted_line[0].lower() +                elif splitted_line[0].lower().startswith("o"): +                    name = "l" + splitted_line[0].lower()                  for i in splitted_line[1:]: -                    if (('.' in i or ':' in i) and '/' in i): -                        value = i.split(r'\n')[0] +                    if ("." in i or ":" in i) and "/" in i: +                        value = i.split(r"\n")[0]                          if is_ipv4(value):                              ipv4.append(value)                          elif is_ipv6(value):                              ipv6.append(value) -                obj.append({'name': name, -                            'ipv4': ipv4, -                            'ipv6': ipv6}) +                obj.append({"name": name, "ipv4": ipv4, "ipv6": ipv6})      return obj @@ -218,7 +228,7 @@ def map_config_to_obj(module):  def map_params_to_obj(module):      obj = [] -    aggregate = module.params.get('aggregate') +    aggregate = module.params.get("aggregate")      if aggregate:          for item in aggregate:              for key in item: @@ -227,12 +237,14 @@ def map_params_to_obj(module):              obj.append(item.copy())      else: -        obj.append({ -            'name': module.params['name'], -            'ipv4': module.params['ipv4'], -            'ipv6': module.params['ipv6'], -            'state': module.params['state'] -        }) +        obj.append( +            { +                "name": module.params["name"], +                "ipv4": module.params["ipv4"], +                "ipv6": module.params["ipv6"], +                "state": module.params["state"], +            } +        )      return obj @@ -244,50 +256,51 @@ def main():          name=dict(),          ipv4=dict(),          ipv6=dict(), -        state=dict(default='present', -                   choices=['present', 'absent']) +        state=dict(default="present", choices=["present", "absent"]),      )      aggregate_spec = deepcopy(element_spec) -    aggregate_spec['name'] = dict(required=True) +    aggregate_spec["name"] = dict(required=True)      # remove default in aggregate spec, to handle common arguments      remove_default_spec(aggregate_spec)      argument_spec = dict( -        aggregate=dict(type='list', elements='dict', options=aggregate_spec), +        aggregate=dict(type="list", elements="dict", options=aggregate_spec)      )      argument_spec.update(element_spec)      argument_spec.update(vyos_argument_spec) -    required_one_of = [['name', 'aggregate']] -    mutually_exclusive = [['name', 'aggregate']] -    module = AnsibleModule(argument_spec=argument_spec, -                           required_one_of=required_one_of, -                           mutually_exclusive=mutually_exclusive, -                           supports_check_mode=True) +    required_one_of = [["name", "aggregate"]] +    mutually_exclusive = [["name", "aggregate"]] +    module = AnsibleModule( +        argument_spec=argument_spec, +        required_one_of=required_one_of, +        mutually_exclusive=mutually_exclusive, +        supports_check_mode=True, +    )      warnings = list() -    result = {'changed': False} +    result = {"changed": False}      if warnings: -        result['warnings'] = warnings +        result["warnings"] = warnings      want = map_params_to_obj(module)      have = map_config_to_obj(module)      commands = map_obj_to_commands((want, have), module) -    result['commands'] = commands +    result["commands"] = commands      if commands:          commit = not module.check_mode          load_config(module, commands, commit=commit) -        result['changed'] = True +        result["changed"] = True      module.exit_json(**result) -if __name__ == '__main__': +if __name__ == "__main__":      main() diff --git a/plugins/modules/vyos_banner.py b/plugins/modules/vyos_banner.py index 1f8816a..6738624 100644 --- a/plugins/modules/vyos_banner.py +++ b/plugins/modules/vyos_banner.py @@ -19,9 +19,11 @@  # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.  # -ANSIBLE_METADATA = {'metadata_version': '1.1', -                    'status': ['preview'], -                    'supported_by': 'network'} +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": ["preview"], +    "supported_by": "network", +}  DOCUMENTATION = """  --- @@ -86,28 +88,33 @@ commands:  import re  from ansible.module_utils.basic import AnsibleModule -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import get_config, load_config - -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import vyos_argument_spec +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    get_config, +    load_config, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    vyos_argument_spec, +)  def spec_to_commands(updates, module):      commands = list()      want, have = updates -    state = module.params['state'] - -    if state == 'absent': -        if have.get('state') != 'absent' or (have.get('state') != 'absent' and -                                             'text' in have.keys() and have['text']): -            commands.append('delete system login banner %s' % module.params['banner']) - -    elif state == 'present': -        if want['text'] and want['text'].encode().decode('unicode_escape') != have.get('text'): -            banner_cmd = 'set system login banner %s ' % module.params['banner'] -            banner_cmd += want['text'].strip() +    state = module.params["state"] + +    if state == "absent": +        if have.get("state") != "absent" or ( +            have.get("state") != "absent" and "text" in have.keys() and have["text"] +        ): +            commands.append("delete system login banner %s" % module.params["banner"]) + +    elif state == "present": +        if want["text"] and want["text"].encode().decode("unicode_escape") != have.get( +            "text" +        ): +            banner_cmd = "set system login banner %s " % module.params["banner"] +            banner_cmd += want["text"].strip()              commands.append(banner_cmd)      return commands @@ -116,28 +123,28 @@ def spec_to_commands(updates, module):  def config_to_dict(module):      data = get_config(module)      output = None -    obj = {'banner': module.params['banner'], 'state': 'absent'} +    obj = {"banner": module.params["banner"], "state": "absent"} -    for line in data.split('\n'): -        if line.startswith('set system login banner %s' % obj['banner']): -            match = re.findall(r'%s (.*)' % obj['banner'], line, re.M) +    for line in data.split("\n"): +        if line.startswith("set system login banner %s" % obj["banner"]): +            match = re.findall(r"%s (.*)" % obj["banner"], line, re.M)              output = match      if output: -        obj['text'] = output[0].encode().decode('unicode_escape') -        obj['state'] = 'present' +        obj["text"] = output[0].encode().decode("unicode_escape") +        obj["state"] = "present"      return obj  def map_params_to_obj(module): -    text = module.params['text'] +    text = module.params["text"]      if text:          text = "%r" % (str(text).strip())      return { -        'banner': module.params['banner'], -        'text': text, -        'state': module.params['state'] +        "banner": module.params["banner"], +        "text": text, +        "state": module.params["state"],      } @@ -145,38 +152,38 @@ def main():      """ main entry point for module execution      """      argument_spec = dict( -        banner=dict(required=True, choices=['pre-login', 'post-login']), +        banner=dict(required=True, choices=["pre-login", "post-login"]),          text=dict(), -        state=dict(default='present', choices=['present', 'absent']) +        state=dict(default="present", choices=["present", "absent"]),      )      argument_spec.update(vyos_argument_spec) -    required_if = [('state', 'present', ('text',))] +    required_if = [("state", "present", ("text",))] -    module = AnsibleModule(argument_spec=argument_spec, -                           required_if=required_if, -                           supports_check_mode=True) +    module = AnsibleModule( +        argument_spec=argument_spec, required_if=required_if, supports_check_mode=True +    )      warnings = list() -    result = {'changed': False} +    result = {"changed": False}      if warnings: -        result['warnings'] = warnings +        result["warnings"] = warnings      want = map_params_to_obj(module)      have = config_to_dict(module)      commands = spec_to_commands((want, have), module) -    result['commands'] = commands +    result["commands"] = commands      if commands:          commit = not module.check_mode          load_config(module, commands, commit=commit) -        result['changed'] = True +        result["changed"] = True      module.exit_json(**result) -if __name__ == '__main__': +if __name__ == "__main__":      main() diff --git a/plugins/modules/vyos_command.py b/plugins/modules/vyos_command.py index 3570f20..a3593ba 100644 --- a/plugins/modules/vyos_command.py +++ b/plugins/modules/vyos_command.py @@ -16,9 +16,11 @@  # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.  # -ANSIBLE_METADATA = {'metadata_version': '1.1', -                    'status': ['preview'], -                    'supported_by': 'network'} +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": ["preview"], +    "supported_by": "network", +}  DOCUMENTATION = """ @@ -142,12 +144,13 @@ from ansible.module_utils._text import to_text  from ansible.module_utils.basic import AnsibleModule  from ansible.module_utils.network.common.parsing import Conditional  from ansible.module_utils.network.common.utils import transform_commands, to_lines -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import run_commands - -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import vyos_argument_spec +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    run_commands, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    vyos_argument_spec, +)  def parse_commands(module, warnings): @@ -155,10 +158,10 @@ def parse_commands(module, warnings):      if module.check_mode:          for item in list(commands): -            if not item['command'].startswith('show'): +            if not item["command"].startswith("show"):                  warnings.append( -                    'Only show commands are supported when using check mode, not ' -                    'executing %s' % item['command'] +                    "Only show commands are supported when using check mode, not " +                    "executing %s" % item["command"]                  )                  commands.remove(item) @@ -167,13 +170,11 @@ def parse_commands(module, warnings):  def main():      spec = dict( -        commands=dict(type='list', required=True), - -        wait_for=dict(type='list', aliases=['waitfor']), -        match=dict(default='all', choices=['all', 'any']), - -        retries=dict(default=10, type='int'), -        interval=dict(default=1, type='int') +        commands=dict(type="list", required=True), +        wait_for=dict(type="list", aliases=["waitfor"]), +        match=dict(default="all", choices=["all", "any"]), +        retries=dict(default=10, type="int"), +        interval=dict(default=1, type="int"),      )      spec.update(vyos_argument_spec) @@ -181,25 +182,25 @@ def main():      module = AnsibleModule(argument_spec=spec, supports_check_mode=True)      warnings = list() -    result = {'changed': False, 'warnings': warnings} +    result = {"changed": False, "warnings": warnings}      commands = parse_commands(module, warnings) -    wait_for = module.params['wait_for'] or list() +    wait_for = module.params["wait_for"] or list()      try:          conditionals = [Conditional(c) for c in wait_for]      except AttributeError as exc:          module.fail_json(msg=to_text(exc)) -    retries = module.params['retries'] -    interval = module.params['interval'] -    match = module.params['match'] +    retries = module.params["retries"] +    interval = module.params["interval"] +    match = module.params["match"]      for _ in range(retries):          responses = run_commands(module, commands)          for item in list(conditionals):              if item(responses): -                if match == 'any': +                if match == "any":                      conditionals = list()                      break                  conditionals.remove(item) @@ -211,16 +212,13 @@ def main():      if conditionals:          failed_conditions = [item.raw for item in conditionals] -        msg = 'One or more conditional statements have not been satisfied' +        msg = "One or more conditional statements have not been satisfied"          module.fail_json(msg=msg, failed_conditions=failed_conditions) -    result.update({ -        'stdout': responses, -        'stdout_lines': list(to_lines(responses)), -    }) +    result.update({"stdout": responses, "stdout_lines": list(to_lines(responses))})      module.exit_json(**result) -if __name__ == '__main__': +if __name__ == "__main__":      main() diff --git a/plugins/modules/vyos_config.py b/plugins/modules/vyos_config.py index 7987e14..530fdc3 100644 --- a/plugins/modules/vyos_config.py +++ b/plugins/modules/vyos_config.py @@ -16,9 +16,11 @@  # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.  # -ANSIBLE_METADATA = {'metadata_version': '1.1', -                    'status': ['preview'], -                    'supported_by': 'network'} +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": ["preview"], +    "supported_by": "network", +}  DOCUMENTATION = """ @@ -187,28 +189,32 @@ import re  from ansible.module_utils._text import to_text  from ansible.module_utils.basic import AnsibleModule  from ansible.module_utils.connection import ConnectionError -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import load_config, get_config, run_commands +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    load_config, +    get_config, +    run_commands, +) -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import vyos_argument_spec, get_connection +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    vyos_argument_spec, +    get_connection, +) - -DEFAULT_COMMENT = 'configured by vyos_config' +DEFAULT_COMMENT = "configured by vyos_config"  CONFIG_FILTERS = [ -    re.compile(r'set system login user \S+ authentication encrypted-password') +    re.compile(r"set system login user \S+ authentication encrypted-password")  ]  def get_candidate(module): -    contents = module.params['src'] or module.params['lines'] +    contents = module.params["src"] or module.params["lines"] -    if module.params['src']: +    if module.params["src"]:          contents = format_commands(contents.splitlines()) -    contents = '\n'.join(contents) +    contents = "\n".join(contents)      return contents @@ -217,25 +223,25 @@ def format_commands(commands):  def diff_config(commands, config): -    config = [str(c).replace("'", '') for c in config.splitlines()] +    config = [str(c).replace("'", "") for c in config.splitlines()]      updates = list()      visited = set()      for line in commands: -        item = str(line).replace("'", '') +        item = str(line).replace("'", "") -        if not item.startswith('set') and not item.startswith('delete'): -            raise ValueError('line must start with either `set` or `delete`') +        if not item.startswith("set") and not item.startswith("delete"): +            raise ValueError("line must start with either `set` or `delete`") -        elif item.startswith('set') and item not in config: +        elif item.startswith("set") and item not in config:              updates.append(line) -        elif item.startswith('delete'): +        elif item.startswith("delete"):              if not config:                  updates.append(line)              else: -                item = re.sub(r'delete', 'set', item) +                item = re.sub(r"delete", "set", item)                  for entry in config:                      if entry.startswith(item) and line not in visited:                          updates.append(line) @@ -245,12 +251,12 @@ def diff_config(commands, config):  def sanitize_config(config, result): -    result['filtered'] = list() +    result["filtered"] = list()      index_to_filter = list()      for regex in CONFIG_FILTERS:          for index, line in enumerate(list(config)):              if regex.search(line): -                result['filtered'].append(line) +                result["filtered"].append(line)                  index_to_filter.append(index)      # Delete all filtered configs      for filter_index in sorted(index_to_filter, reverse=True): @@ -260,7 +266,7 @@ def sanitize_config(config, result):  def run(module, result):      # get the current active config from the node or passed in via      # the config param -    config = module.params['config'] or get_config(module) +    config = module.params["config"] or get_config(module)      # create the candidate config object from the arguments      candidate = get_candidate(module) @@ -268,81 +274,78 @@ def run(module, result):      # create loadable config that includes only the configuration updates      connection = get_connection(module)      try: -        response = connection.get_diff(candidate=candidate, running=config, diff_match=module.params['match']) +        response = connection.get_diff( +            candidate=candidate, running=config, diff_match=module.params["match"] +        )      except ConnectionError as exc: -        module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) +        module.fail_json(msg=to_text(exc, errors="surrogate_then_replace")) -    commands = response.get('config_diff') +    commands = response.get("config_diff")      sanitize_config(commands, result) -    result['commands'] = commands +    result["commands"] = commands      commit = not module.check_mode -    comment = module.params['comment'] +    comment = module.params["comment"]      diff = None      if commands:          diff = load_config(module, commands, commit=commit, comment=comment) -        if result.get('filtered'): -            result['warnings'].append('Some configuration commands were ' -                                      'removed, please see the filtered key') +        if result.get("filtered"): +            result["warnings"].append( +                "Some configuration commands were " +                "removed, please see the filtered key" +            ) -        result['changed'] = True +        result["changed"] = True      if module._diff: -        result['diff'] = {'prepared': diff} +        result["diff"] = {"prepared": diff}  def main(): -    backup_spec = dict( -        filename=dict(), -        dir_path=dict(type='path') -    ) +    backup_spec = dict(filename=dict(), dir_path=dict(type="path"))      argument_spec = dict( -        src=dict(type='path'), -        lines=dict(type='list'), - -        match=dict(default='line', choices=['line', 'none']), - +        src=dict(type="path"), +        lines=dict(type="list"), +        match=dict(default="line", choices=["line", "none"]),          comment=dict(default=DEFAULT_COMMENT), -          config=dict(), - -        backup=dict(type='bool', default=False), -        backup_options=dict(type='dict', options=backup_spec), -        save=dict(type='bool', default=False), +        backup=dict(type="bool", default=False), +        backup_options=dict(type="dict", options=backup_spec), +        save=dict(type="bool", default=False),      )      argument_spec.update(vyos_argument_spec) -    mutually_exclusive = [('lines', 'src')] +    mutually_exclusive = [("lines", "src")]      module = AnsibleModule(          argument_spec=argument_spec,          mutually_exclusive=mutually_exclusive, -        supports_check_mode=True +        supports_check_mode=True,      )      warnings = list()      result = dict(changed=False, warnings=warnings) -    if module.params['backup']: -        result['__backup__'] = get_config(module=module) +    if module.params["backup"]: +        result["__backup__"] = get_config(module=module) -    if any((module.params['src'], module.params['lines'])): +    if any((module.params["src"], module.params["lines"])):          run(module, result) -    if module.params['save']: -        diff = run_commands(module, commands=['configure', 'compare saved'])[1] -        if diff != '[edit]': -            run_commands(module, commands=['save']) -            result['changed'] = True -        run_commands(module, commands=['exit']) +    if module.params["save"]: +        diff = run_commands(module, commands=["configure", "compare saved"])[1] +        if diff != "[edit]": +            run_commands(module, commands=["save"]) +            result["changed"] = True +        run_commands(module, commands=["exit"])      module.exit_json(**result) -if __name__ == '__main__': +if __name__ == "__main__":      main() diff --git a/plugins/modules/vyos_facts.py b/plugins/modules/vyos_facts.py index 5c8ac51..1e63c5d 100644 --- a/plugins/modules/vyos_facts.py +++ b/plugins/modules/vyos_facts.py @@ -8,9 +8,11 @@ The module file for vyos_facts  """ -ANSIBLE_METADATA = {'metadata_version': '1.1', -                    'status': [u'preview'], -                    'supported_by': 'network'} +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": [u"preview"], +    "supported_by": "network", +}  DOCUMENTATION = """ @@ -135,15 +137,17 @@ ansible_net_gather_network_resources:  """  from ansible.module_utils.basic import AnsibleModule -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.argspec.facts.facts import FactsArgs +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.facts.facts import ( +    FactsArgs, +) -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.facts.facts import Facts - -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import vyos_argument_spec +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import ( +    Facts, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    vyos_argument_spec, +)  def main(): @@ -156,11 +160,12 @@ def main():      argument_spec.update(vyos_argument_spec) -    module = AnsibleModule(argument_spec=argument_spec, -                           supports_check_mode=True) +    module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) -    warnings = ['default value for `gather_subset` ' -                'will be changed to `min` from `!config` v2.11 onwards'] +    warnings = [ +        "default value for `gather_subset` " +        "will be changed to `min` from `!config` v2.11 onwards" +    ]      result = Facts(module).get_facts() @@ -170,5 +175,5 @@ def main():      module.exit_json(ansible_facts=ansible_facts, warnings=warnings) -if __name__ == '__main__': +if __name__ == "__main__":      main() diff --git a/plugins/modules/vyos_interfaces.py b/plugins/modules/vyos_interfaces.py index a78a983..ca61f4d 100644 --- a/plugins/modules/vyos_interfaces.py +++ b/plugins/modules/vyos_interfaces.py @@ -27,12 +27,13 @@ The module file for vyos_interfaces  """  from __future__ import absolute_import, division, print_function +  __metaclass__ = type  ANSIBLE_METADATA = { -    'metadata_version': '1.1', -    'status': ['preview'], -    'supported_by': 'network' +    "metadata_version": "1.1", +    "status": ["preview"], +    "supported_by": "network",  }  DOCUMENTATION = """ @@ -855,12 +856,13 @@ commands:  from ansible.module_utils.basic import AnsibleModule -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.argspec.interfaces.interfaces import InterfacesArgs - -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.config.interfaces.interfaces import Interfaces +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.interfaces.interfaces import ( +    InterfacesArgs, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.interfaces.interfaces import ( +    Interfaces, +)  def main(): @@ -869,12 +871,13 @@ def main():      :returns: the result form module invocation      """ -    module = AnsibleModule(argument_spec=InterfacesArgs.argument_spec, -                           supports_check_mode=True) +    module = AnsibleModule( +        argument_spec=InterfacesArgs.argument_spec, supports_check_mode=True +    )      result = Interfaces(module).execute_module()      module.exit_json(**result) -if __name__ == '__main__': +if __name__ == "__main__":      main() diff --git a/plugins/modules/vyos_l3_interfaces.py b/plugins/modules/vyos_l3_interfaces.py index c2dd461..1a2e453 100644 --- a/plugins/modules/vyos_l3_interfaces.py +++ b/plugins/modules/vyos_l3_interfaces.py @@ -26,13 +26,14 @@  The module file for vyos_l3_interfaces  """ -from __future__ import (absolute_import, division, print_function) +from __future__ import absolute_import, division, print_function +  __metaclass__ = type  ANSIBLE_METADATA = { -    'metadata_version': '1.1', -    'status': ['preview'], -    'supported_by': 'network' +    "metadata_version": "1.1", +    "status": ["preview"], +    "supported_by": "network",  }  DOCUMENTATION = """ @@ -351,12 +352,13 @@ commands:  from ansible.module_utils.basic import AnsibleModule -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.argspec.l3_interfaces.l3_interfaces import L3_interfacesArgs - -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.config.l3_interfaces.l3_interfaces import L3_interfaces +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.l3_interfaces.l3_interfaces import ( +    L3_interfacesArgs, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.l3_interfaces.l3_interfaces import ( +    L3_interfaces, +)  def main(): @@ -365,12 +367,13 @@ def main():      :returns: the result form module invocation      """ -    module = AnsibleModule(argument_spec=L3_interfacesArgs.argument_spec, -                           supports_check_mode=True) +    module = AnsibleModule( +        argument_spec=L3_interfacesArgs.argument_spec, supports_check_mode=True +    )      result = L3_interfaces(module).execute_module()      module.exit_json(**result) -if __name__ == '__main__': +if __name__ == "__main__":      main() diff --git a/plugins/modules/vyos_linkagg.py b/plugins/modules/vyos_linkagg.py index 71f46ba..7793b6d 100644 --- a/plugins/modules/vyos_linkagg.py +++ b/plugins/modules/vyos_linkagg.py @@ -19,9 +19,11 @@  # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.  # -ANSIBLE_METADATA = {'metadata_version': '1.1', -                    'status': ['preview'], -                    'supported_by': 'network'} +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": ["preview"], +    "supported_by": "network", +}  DOCUMENTATION = """ @@ -100,17 +102,19 @@ from copy import deepcopy  from ansible.module_utils.basic import AnsibleModule  from ansible.module_utils.network.common.utils import remove_default_spec -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import load_config, run_commands - -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import vyos_argument_spec +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    load_config, +    run_commands, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    vyos_argument_spec, +)  def search_obj_in_list(name, lst):      for o in lst: -        if o['name'] == name: +        if o["name"] == name:              return o      return None @@ -121,51 +125,55 @@ def map_obj_to_commands(updates, module):      want, have = updates      for w in want: -        name = w['name'] -        members = w.get('members') or [] -        mode = w['mode'] +        name = w["name"] +        members = w.get("members") or [] +        mode = w["mode"] -        if mode == 'on': -            mode = '802.3ad' +        if mode == "on": +            mode = "802.3ad" -        state = w['state'] +        state = w["state"]          obj_in_have = search_obj_in_list(name, have) -        if state == 'absent': +        if state == "absent":              if obj_in_have: -                for m in obj_in_have['members']: -                    commands.append('delete interfaces ethernet ' + m + ' bond-group') +                for m in obj_in_have["members"]: +                    commands.append("delete interfaces ethernet " + m + " bond-group") -                commands.append('delete interfaces bonding ' + name) +                commands.append("delete interfaces bonding " + name)          else:              if not obj_in_have: -                commands.append('set interfaces bonding ' + name + ' mode ' + mode) +                commands.append("set interfaces bonding " + name + " mode " + mode)                  for m in members: -                    commands.append('set interfaces ethernet ' + m + ' bond-group ' + name) +                    commands.append( +                        "set interfaces ethernet " + m + " bond-group " + name +                    ) -                if state == 'down': -                    commands.append('set interfaces bonding ' + name + ' disable') +                if state == "down": +                    commands.append("set interfaces bonding " + name + " disable")              else: -                if mode != obj_in_have['mode']: -                    commands.append('set interfaces bonding ' + name + ' mode ' + mode) +                if mode != obj_in_have["mode"]: +                    commands.append("set interfaces bonding " + name + " mode " + mode) -                missing_members = list(set(members) - set(obj_in_have['members'])) +                missing_members = list(set(members) - set(obj_in_have["members"]))                  for m in missing_members: -                    commands.append('set interfaces ethernet ' + m + ' bond-group ' + name) +                    commands.append( +                        "set interfaces ethernet " + m + " bond-group " + name +                    ) -                if state == 'down' and obj_in_have['state'] == 'up': -                    commands.append('set interfaces bonding ' + name + ' disable') -                elif state == 'up' and obj_in_have['state'] == 'down': -                    commands.append('delete interfaces bonding ' + name + ' disable') +                if state == "down" and obj_in_have["state"] == "up": +                    commands.append("set interfaces bonding " + name + " disable") +                elif state == "up" and obj_in_have["state"] == "down": +                    commands.append("delete interfaces bonding " + name + " disable")      return commands  def map_config_to_obj(module):      obj = [] -    output = run_commands(module, ['show interfaces bonding slaves']) +    output = run_commands(module, ["show interfaces bonding slaves"])      lines = output[0].splitlines()      if len(lines) > 1: @@ -181,17 +189,14 @@ def map_config_to_obj(module):              else:                  members = [] -            obj.append({'name': name, -                        'mode': mode, -                        'members': members, -                        'state': state}) +            obj.append({"name": name, "mode": mode, "members": members, "state": state})      return obj  def map_params_to_obj(module):      obj = [] -    aggregate = module.params.get('aggregate') +    aggregate = module.params.get("aggregate")      if aggregate:          for item in aggregate:              for key in item: @@ -200,12 +205,14 @@ def map_params_to_obj(module):              obj.append(item.copy())      else: -        obj.append({ -            'name': module.params['name'], -            'mode': module.params['mode'], -            'members': module.params['members'], -            'state': module.params['state'] -        }) +        obj.append( +            { +                "name": module.params["name"], +                "mode": module.params["mode"], +                "members": module.params["members"], +                "state": module.params["state"], +            } +        )      return obj @@ -215,55 +222,65 @@ def main():      """      element_spec = dict(          name=dict(), -        mode=dict(choices=['802.3ad', 'active-backup', 'broadcast', -                           'round-robin', 'transmit-load-balance', -                           'adaptive-load-balance', 'xor-hash', 'on'], -                  default='802.3ad'), -        members=dict(type='list'), -        state=dict(default='present', -                   choices=['present', 'absent', 'up', 'down']) +        mode=dict( +            choices=[ +                "802.3ad", +                "active-backup", +                "broadcast", +                "round-robin", +                "transmit-load-balance", +                "adaptive-load-balance", +                "xor-hash", +                "on", +            ], +            default="802.3ad", +        ), +        members=dict(type="list"), +        state=dict(default="present", choices=["present", "absent", "up", "down"]),      )      aggregate_spec = deepcopy(element_spec) -    aggregate_spec['name'] = dict(required=True) +    aggregate_spec["name"] = dict(required=True)      # remove default in aggregate spec, to handle common arguments      remove_default_spec(aggregate_spec)      argument_spec = dict( -        aggregate=dict(type='list', elements='dict', options=aggregate_spec), +        aggregate=dict(type="list", elements="dict", options=aggregate_spec)      )      argument_spec.update(element_spec)      argument_spec.update(vyos_argument_spec) -    required_one_of = [['name', 'aggregate']] -    mutually_exclusive = [['name', 'aggregate']] -    module = AnsibleModule(argument_spec=argument_spec, -                           required_one_of=required_one_of, -                           mutually_exclusive=mutually_exclusive, -                           supports_check_mode=True) +    required_one_of = [["name", "aggregate"]] +    mutually_exclusive = [["name", "aggregate"]] +    module = AnsibleModule( +        argument_spec=argument_spec, +        required_one_of=required_one_of, +        mutually_exclusive=mutually_exclusive, +        supports_check_mode=True, +    )      warnings = list() -    result = {'changed': False} +    result = {"changed": False}      if warnings: -        result['warnings'] = warnings +        result["warnings"] = warnings      want = map_params_to_obj(module)      have = map_config_to_obj(module)      commands = map_obj_to_commands((want, have), module) -    result['commands'] = commands +    result["commands"] = commands      if commands:          commit = not module.check_mode          load_config(module, commands, commit=commit) -        result['changed'] = True +        result["changed"] = True      module.exit_json(**result) -if __name__ == '__main__': +if __name__ == "__main__":      main() diff --git a/plugins/modules/vyos_lldp.py b/plugins/modules/vyos_lldp.py index fa1ac03..69a62a3 100644 --- a/plugins/modules/vyos_lldp.py +++ b/plugins/modules/vyos_lldp.py @@ -19,9 +19,11 @@  # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.  # -ANSIBLE_METADATA = {'metadata_version': '1.1', -                    'status': ['preview'], -                    'supported_by': 'network'} +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": ["preview"], +    "supported_by": "network", +}  DOCUMENTATION = """ @@ -63,18 +65,20 @@ commands:      - set service lldp  """  from ansible.module_utils.basic import AnsibleModule -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import get_config, load_config - -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import vyos_argument_spec +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    get_config, +    load_config, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    vyos_argument_spec, +)  def has_lldp(module):      config = get_config(module).splitlines() -    if "set service 'lldp'" in config or 'set service lldp' in config: +    if "set service 'lldp'" in config or "set service lldp" in config:          return True      else:          return False @@ -84,42 +88,41 @@ def main():      """ main entry point for module execution      """      argument_spec = dict( -        interfaces=dict(type='list'), -        state=dict(default='present', -                   choices=['present', 'absent', -                            'enabled', 'disabled']) +        interfaces=dict(type="list"), +        state=dict( +            default="present", choices=["present", "absent", "enabled", "disabled"] +        ),      )      argument_spec.update(vyos_argument_spec) -    module = AnsibleModule(argument_spec=argument_spec, -                           supports_check_mode=True) +    module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)      warnings = list() -    result = {'changed': False} +    result = {"changed": False}      if warnings: -        result['warnings'] = warnings +        result["warnings"] = warnings      HAS_LLDP = has_lldp(module)      commands = [] -    if module.params['state'] == 'absent' and HAS_LLDP: -        commands.append('delete service lldp') -    elif module.params['state'] == 'present' and not HAS_LLDP: -        commands.append('set service lldp') +    if module.params["state"] == "absent" and HAS_LLDP: +        commands.append("delete service lldp") +    elif module.params["state"] == "present" and not HAS_LLDP: +        commands.append("set service lldp") -    result['commands'] = commands +    result["commands"] = commands      if commands:          commit = not module.check_mode          load_config(module, commands, commit=commit) -        result['changed'] = True +        result["changed"] = True      module.exit_json(**result) -if __name__ == '__main__': +if __name__ == "__main__":      main() diff --git a/plugins/modules/vyos_lldp_interface.py b/plugins/modules/vyos_lldp_interface.py index 86a64e3..23d1eab 100644 --- a/plugins/modules/vyos_lldp_interface.py +++ b/plugins/modules/vyos_lldp_interface.py @@ -19,9 +19,11 @@  # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.  # -ANSIBLE_METADATA = {'metadata_version': '1.1', -                    'status': ['preview'], -                    'supported_by': 'network'} +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": ["preview"], +    "supported_by": "network", +}  DOCUMENTATION = """ @@ -93,17 +95,19 @@ from copy import deepcopy  from ansible.module_utils.basic import AnsibleModule  from ansible.module_utils.network.common.utils import remove_default_spec -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import get_config, load_config - -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import vyos_argument_spec +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    get_config, +    load_config, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    vyos_argument_spec, +)  def search_obj_in_list(name, lst):      for o in lst: -        if o['name'] == name: +        if o["name"] == name:              return o      return None @@ -114,24 +118,28 @@ def map_obj_to_commands(updates, module):      want, have = updates      for w in want: -        name = w['name'] -        state = w['state'] +        name = w["name"] +        state = w["state"]          obj_in_have = search_obj_in_list(name, have) -        if state == 'absent' and obj_in_have: -            commands.append('delete service lldp interface ' + name) -        elif state in ('present', 'enabled'): +        if state == "absent" and obj_in_have: +            commands.append("delete service lldp interface " + name) +        elif state in ("present", "enabled"):              if not obj_in_have: -                commands.append('set service lldp interface ' + name) -            elif obj_in_have and obj_in_have['state'] == 'disabled' and state == 'enabled': -                commands.append('delete service lldp interface ' + name + ' disable') -        elif state == 'disabled': +                commands.append("set service lldp interface " + name) +            elif ( +                obj_in_have +                and obj_in_have["state"] == "disabled" +                and state == "enabled" +            ): +                commands.append("delete service lldp interface " + name + " disable") +        elif state == "disabled":              if not obj_in_have: -                commands.append('set service lldp interface ' + name) -                commands.append('set service lldp interface ' + name + ' disable') -            elif obj_in_have and obj_in_have['state'] != 'disabled': -                commands.append('set service lldp interface ' + name + ' disable') +                commands.append("set service lldp interface " + name) +                commands.append("set service lldp interface " + name + " disable") +            elif obj_in_have and obj_in_have["state"] != "disabled": +                commands.append("set service lldp interface " + name + " disable")      return commands @@ -146,13 +154,13 @@ def map_config_to_obj(module):          splitted_line = i.split()          if len(splitted_line) > 5: -            new_obj = {'name': splitted_line[4]} +            new_obj = {"name": splitted_line[4]}              if splitted_line[5] == "'disable'": -                new_obj['state'] = 'disabled' +                new_obj["state"] = "disabled"          else: -            new_obj = {'name': splitted_line[4][1:-1]} -            new_obj['state'] = 'present' +            new_obj = {"name": splitted_line[4][1:-1]} +            new_obj["state"] = "present"          obj.append(new_obj) @@ -162,7 +170,7 @@ def map_config_to_obj(module):  def map_params_to_obj(module):      obj = [] -    aggregate = module.params.get('aggregate') +    aggregate = module.params.get("aggregate")      if aggregate:          for item in aggregate:              for key in item: @@ -171,7 +179,7 @@ def map_params_to_obj(module):              obj.append(item.copy())      else: -        obj.append({'name': module.params['name'], 'state': module.params['state']}) +        obj.append({"name": module.params["name"], "state": module.params["state"]})      return obj @@ -181,52 +189,54 @@ def main():      """      element_spec = dict(          name=dict(), -        state=dict(default='present', -                   choices=['present', 'absent', -                            'enabled', 'disabled']) +        state=dict( +            default="present", choices=["present", "absent", "enabled", "disabled"] +        ),      )      aggregate_spec = deepcopy(element_spec) -    aggregate_spec['name'] = dict(required=True) +    aggregate_spec["name"] = dict(required=True)      # remove default in aggregate spec, to handle common arguments      remove_default_spec(aggregate_spec)      argument_spec = dict( -        aggregate=dict(type='list', elements='dict', options=aggregate_spec), +        aggregate=dict(type="list", elements="dict", options=aggregate_spec)      )      argument_spec.update(element_spec)      argument_spec.update(vyos_argument_spec) -    required_one_of = [['name', 'aggregate']] -    mutually_exclusive = [['name', 'aggregate']] +    required_one_of = [["name", "aggregate"]] +    mutually_exclusive = [["name", "aggregate"]] -    module = AnsibleModule(argument_spec=argument_spec, -                           required_one_of=required_one_of, -                           mutually_exclusive=mutually_exclusive, -                           supports_check_mode=True) +    module = AnsibleModule( +        argument_spec=argument_spec, +        required_one_of=required_one_of, +        mutually_exclusive=mutually_exclusive, +        supports_check_mode=True, +    )      warnings = list() -    result = {'changed': False} +    result = {"changed": False}      if warnings: -        result['warnings'] = warnings +        result["warnings"] = warnings      want = map_params_to_obj(module)      have = map_config_to_obj(module)      commands = map_obj_to_commands((want, have), module) -    result['commands'] = commands +    result["commands"] = commands      if commands:          commit = not module.check_mode          load_config(module, commands, commit=commit) -        result['changed'] = True +        result["changed"] = True      module.exit_json(**result) -if __name__ == '__main__': +if __name__ == "__main__":      main() diff --git a/plugins/modules/vyos_logging.py b/plugins/modules/vyos_logging.py index a94a8bd..1fd0ca2 100644 --- a/plugins/modules/vyos_logging.py +++ b/plugins/modules/vyos_logging.py @@ -19,9 +19,11 @@  # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.  # -ANSIBLE_METADATA = {'metadata_version': '1.1', -                    'status': ['preview'], -                    'supported_by': 'network'} +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": ["preview"], +    "supported_by": "network", +}  DOCUMENTATION = """  --- @@ -110,12 +112,14 @@ from copy import deepcopy  from ansible.module_utils.basic import AnsibleModule  from ansible.module_utils.network.common.utils import remove_default_spec -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import get_config, load_config - -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import vyos_argument_spec +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    get_config, +    load_config, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    vyos_argument_spec, +)  def spec_to_commands(updates, module): @@ -123,27 +127,39 @@ def spec_to_commands(updates, module):      want, have = updates      for w in want: -        dest = w['dest'] -        name = w['name'] -        facility = w['facility'] -        level = w['level'] -        state = w['state'] -        del w['state'] - -        if state == 'absent' and w in have: -            if w['name']: -                commands.append('delete system syslog {0} {1} facility {2} level {3}'.format( -                    dest, name, facility, level)) +        dest = w["dest"] +        name = w["name"] +        facility = w["facility"] +        level = w["level"] +        state = w["state"] +        del w["state"] + +        if state == "absent" and w in have: +            if w["name"]: +                commands.append( +                    "delete system syslog {0} {1} facility {2} level {3}".format( +                        dest, name, facility, level +                    ) +                )              else: -                commands.append('delete system syslog {0} facility {1} level {2}'.format( -                    dest, facility, level)) -        elif state == 'present' and w not in have: -            if w['name']: -                commands.append('set system syslog {0} {1} facility {2} level {3}'.format( -                    dest, name, facility, level)) +                commands.append( +                    "delete system syslog {0} facility {1} level {2}".format( +                        dest, facility, level +                    ) +                ) +        elif state == "present" and w not in have: +            if w["name"]: +                commands.append( +                    "set system syslog {0} {1} facility {2} level {3}".format( +                        dest, name, facility, level +                    ) +                )              else: -                commands.append('set system syslog {0} facility {1} level {2}'.format( -                    dest, facility, level)) +                commands.append( +                    "set system syslog {0} facility {1} level {2}".format( +                        dest, facility, level +                    ) +                )      return commands @@ -152,33 +168,32 @@ def config_to_dict(module):      data = get_config(module)      obj = [] -    for line in data.split('\n'): -        if line.startswith('set system syslog'): -            match = re.search(r'set system syslog (\S+)', line, re.M) +    for line in data.split("\n"): +        if line.startswith("set system syslog"): +            match = re.search(r"set system syslog (\S+)", line, re.M)              dest = match.group(1) -            if dest == 'host': -                match = re.search(r'host (\S+)', line, re.M) +            if dest == "host": +                match = re.search(r"host (\S+)", line, re.M)                  name = match.group(1) -            elif dest == 'file': -                match = re.search(r'file (\S+)', line, re.M) +            elif dest == "file": +                match = re.search(r"file (\S+)", line, re.M)                  name = match.group(1) -            elif dest == 'user': -                match = re.search(r'user (\S+)', line, re.M) +            elif dest == "user": +                match = re.search(r"user (\S+)", line, re.M)                  name = match.group(1)              else:                  name = None -            if 'facility' in line: -                match = re.search(r'facility (\S+)', line, re.M) +            if "facility" in line: +                match = re.search(r"facility (\S+)", line, re.M)                  facility = match.group(1) -            if 'level' in line: -                match = re.search(r'level (\S+)', line, re.M) +            if "level" in line: +                match = re.search(r"level (\S+)", line, re.M)                  level = match.group(1).strip("'") -                obj.append({'dest': dest, -                            'name': name, -                            'facility': facility, -                            'level': level}) +                obj.append( +                    {"dest": dest, "name": name, "facility": facility, "level": level} +                )      return obj @@ -186,7 +201,7 @@ def config_to_dict(module):  def map_params_to_obj(module, required_if=None):      obj = [] -    aggregate = module.params.get('aggregate') +    aggregate = module.params.get("aggregate")      if aggregate:          for item in aggregate:              for key in item: @@ -197,16 +212,18 @@ def map_params_to_obj(module, required_if=None):              obj.append(item.copy())      else: -        if module.params['dest'] not in ('host', 'file', 'user'): -            module.params['name'] = None - -        obj.append({ -            'dest': module.params['dest'], -            'name': module.params['name'], -            'facility': module.params['facility'], -            'level': module.params['level'], -            'state': module.params['state'] -        }) +        if module.params["dest"] not in ("host", "file", "user"): +            module.params["name"] = None + +        obj.append( +            { +                "dest": module.params["dest"], +                "name": module.params["name"], +                "facility": module.params["facility"], +                "level": module.params["level"], +                "state": module.params["state"], +            } +        )      return obj @@ -215,11 +232,11 @@ def main():      """ main entry point for module execution      """      element_spec = dict( -        dest=dict(type='str', choices=['console', 'file', 'global', 'host', 'user']), -        name=dict(type='str'), -        facility=dict(type='str'), -        level=dict(type='str'), -        state=dict(default='present', choices=['present', 'absent']), +        dest=dict(type="str", choices=["console", "file", "global", "host", "user"]), +        name=dict(type="str"), +        facility=dict(type="str"), +        level=dict(type="str"), +        state=dict(default="present", choices=["present", "absent"]),      )      aggregate_spec = deepcopy(element_spec) @@ -228,40 +245,42 @@ def main():      remove_default_spec(aggregate_spec)      argument_spec = dict( -        aggregate=dict(type='list', elements='dict', options=aggregate_spec), +        aggregate=dict(type="list", elements="dict", options=aggregate_spec)      )      argument_spec.update(element_spec)      argument_spec.update(vyos_argument_spec) -    required_if = [('dest', 'host', ['name', 'facility', 'level']), -                   ('dest', 'file', ['name', 'facility', 'level']), -                   ('dest', 'user', ['name', 'facility', 'level']), -                   ('dest', 'console', ['facility', 'level']), -                   ('dest', 'global', ['facility', 'level'])] - -    module = AnsibleModule(argument_spec=argument_spec, -                           required_if=required_if, -                           supports_check_mode=True) +    required_if = [ +        ("dest", "host", ["name", "facility", "level"]), +        ("dest", "file", ["name", "facility", "level"]), +        ("dest", "user", ["name", "facility", "level"]), +        ("dest", "console", ["facility", "level"]), +        ("dest", "global", ["facility", "level"]), +    ] + +    module = AnsibleModule( +        argument_spec=argument_spec, required_if=required_if, supports_check_mode=True +    )      warnings = list() -    result = {'changed': False} +    result = {"changed": False}      if warnings: -        result['warnings'] = warnings +        result["warnings"] = warnings      want = map_params_to_obj(module, required_if=required_if)      have = config_to_dict(module)      commands = spec_to_commands((want, have), module) -    result['commands'] = commands +    result["commands"] = commands      if commands:          commit = not module.check_mode          load_config(module, commands, commit=commit) -        result['changed'] = True +        result["changed"] = True      module.exit_json(**result) -if __name__ == '__main__': +if __name__ == "__main__":      main() diff --git a/plugins/modules/vyos_ping.py b/plugins/modules/vyos_ping.py index 762bc80..9e99d48 100644 --- a/plugins/modules/vyos_ping.py +++ b/plugins/modules/vyos_ping.py @@ -20,11 +20,14 @@  #  from __future__ import absolute_import, division, print_function +  __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', -                    'status': ['preview'], -                    'supported_by': 'community'} +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": ["preview"], +    "supported_by": "community", +}  DOCUMENTATION = """  --- @@ -130,11 +133,13 @@ rtt:  """  from ansible.module_utils.basic import AnsibleModule -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import run_commands +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    run_commands, +) -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import vyos_argument_spec +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    vyos_argument_spec, +)  import re @@ -146,9 +151,9 @@ def main():          count=dict(type="int", default=5),          dest=dict(type="str", required=True),          source=dict(type="str"), -        ttl=dict(type='int'), -        size=dict(type='int'), -        interval=dict(type='int'), +        ttl=dict(type="int"), +        size=dict(type="int"), +        interval=dict(type="int"),          state=dict(type="str", choices=["absent", "present"], default="present"),      ) @@ -176,9 +181,9 @@ def main():      rtt_info, rate_info = None, None      for line in ping_results_list: -        if line.startswith('rtt'): +        if line.startswith("rtt"):              rtt_info = line -        if line.startswith('%s packets transmitted' % count): +        if line.startswith("%s packets transmitted" % count):              rate_info = line      if rtt_info: @@ -218,9 +223,11 @@ def build_ping(dest, count, size=None, interval=None, source=None, ttl=None):  def parse_rate(rate_info):      rate_re = re.compile( -        r"(?P<tx>\d+) (?:\w+) (?:\w+), (?P<rx>\d+) (?:\w+), (?P<pkt_loss>\d+)% (?:\w+) (?:\w+), (?:\w+) (?P<time>\d+)") +        r"(?P<tx>\d+) (?:\w+) (?:\w+), (?P<rx>\d+) (?:\w+), (?P<pkt_loss>\d+)% (?:\w+) (?:\w+), (?:\w+) (?P<time>\d+)" +    )      rate_err_re = re.compile( -        r"(?P<tx>\d+) (?:\w+) (?:\w+), (?P<rx>\d+) (?:\w+), (?:[+-])(?P<err>\d+) (?:\w+), (?P<pkt_loss>\d+)% (?:\w+) (?:\w+), (?:\w+) (?P<time>\d+)") +        r"(?P<tx>\d+) (?:\w+) (?:\w+), (?P<rx>\d+) (?:\w+), (?:[+-])(?P<err>\d+) (?:\w+), (?P<pkt_loss>\d+)% (?:\w+) (?:\w+), (?:\w+) (?P<time>\d+)" +    )      if rate_re.match(rate_info):          rate = rate_re.match(rate_info) @@ -232,7 +239,8 @@ def parse_rate(rate_info):  def parse_rtt(rtt_info):      rtt_re = re.compile( -        r"rtt (?:.*)=(?:\s*)(?P<min>\d*).(?:\d*)/(?P<avg>\d*).(?:\d*)/(?P<max>\d+).(?:\d*)/(?P<mdev>\d*)") +        r"rtt (?:.*)=(?:\s*)(?P<min>\d*).(?:\d*)/(?P<avg>\d*).(?:\d*)/(?P<max>\d+).(?:\d*)/(?P<mdev>\d*)" +    )      rtt = rtt_re.match(rtt_info)      return rtt.groupdict() diff --git a/plugins/modules/vyos_static_route.py b/plugins/modules/vyos_static_route.py index 3c00bca..dfb1d21 100644 --- a/plugins/modules/vyos_static_route.py +++ b/plugins/modules/vyos_static_route.py @@ -19,9 +19,11 @@  # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.  # -ANSIBLE_METADATA = {'metadata_version': '1.1', -                    'status': ['preview'], -                    'supported_by': 'network'} +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": ["preview"], +    "supported_by": "network", +}  DOCUMENTATION = """ @@ -108,31 +110,37 @@ from copy import deepcopy  from ansible.module_utils.basic import AnsibleModule  from ansible.module_utils.network.common.utils import remove_default_spec -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import get_config, load_config - -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import vyos_argument_spec +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    get_config, +    load_config, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    vyos_argument_spec, +)  def spec_to_commands(updates, module):      commands = list()      want, have = updates      for w in want: -        prefix = w['prefix'] -        mask = w['mask'] -        next_hop = w['next_hop'] -        admin_distance = w['admin_distance'] -        state = w['state'] -        del w['state'] - -        if state == 'absent' and w in have: -            commands.append('delete protocols static route %s/%s' % (prefix, mask)) -        elif state == 'present' and w not in have: -            cmd = 'set protocols static route %s/%s next-hop %s' % (prefix, mask, next_hop) -            if admin_distance != 'None': -                cmd += ' distance %s' % (admin_distance) +        prefix = w["prefix"] +        mask = w["mask"] +        next_hop = w["next_hop"] +        admin_distance = w["admin_distance"] +        state = w["state"] +        del w["state"] + +        if state == "absent" and w in have: +            commands.append("delete protocols static route %s/%s" % (prefix, mask)) +        elif state == "present" and w not in have: +            cmd = "set protocols static route %s/%s next-hop %s" % ( +                prefix, +                mask, +                next_hop, +            ) +            if admin_distance != "None": +                cmd += " distance %s" % (admin_distance)              commands.append(cmd)      return commands @@ -142,38 +150,46 @@ def config_to_dict(module):      data = get_config(module)      obj = [] -    for line in data.split('\n'): -        if line.startswith('set protocols static route'): -            match = re.search(r'static route (\S+)', line, re.M) -            prefix = match.group(1).split('/')[0] -            mask = match.group(1).split('/')[1] -            if 'next-hop' in line: -                match_hop = re.search(r'next-hop (\S+)', line, re.M) +    for line in data.split("\n"): +        if line.startswith("set protocols static route"): +            match = re.search(r"static route (\S+)", line, re.M) +            prefix = match.group(1).split("/")[0] +            mask = match.group(1).split("/")[1] +            if "next-hop" in line: +                match_hop = re.search(r"next-hop (\S+)", line, re.M)                  next_hop = match_hop.group(1).strip("'") -                match_distance = re.search(r'distance (\S+)', line, re.M) +                match_distance = re.search(r"distance (\S+)", line, re.M)                  if match_distance is not None:                      admin_distance = match_distance.group(1)[1:-1]                  else:                      admin_distance = None                  if admin_distance is not None: -                    obj.append({'prefix': prefix, -                                'mask': mask, -                                'next_hop': next_hop, -                                'admin_distance': admin_distance}) +                    obj.append( +                        { +                            "prefix": prefix, +                            "mask": mask, +                            "next_hop": next_hop, +                            "admin_distance": admin_distance, +                        } +                    )                  else: -                    obj.append({'prefix': prefix, -                                'mask': mask, -                                'next_hop': next_hop, -                                'admin_distance': 'None'}) +                    obj.append( +                        { +                            "prefix": prefix, +                            "mask": mask, +                            "next_hop": next_hop, +                            "admin_distance": "None", +                        } +                    )      return obj  def map_params_to_obj(module, required_together=None):      obj = [] -    aggregate = module.params.get('aggregate') +    aggregate = module.params.get("aggregate")      if aggregate:          for item in aggregate:              for key in item: @@ -182,32 +198,34 @@ def map_params_to_obj(module, required_together=None):              module._check_required_together(required_together, item)              d = item.copy() -            if '/' in d['prefix']: -                d['mask'] = d['prefix'].split('/')[1] -                d['prefix'] = d['prefix'].split('/')[0] +            if "/" in d["prefix"]: +                d["mask"] = d["prefix"].split("/")[1] +                d["prefix"] = d["prefix"].split("/")[0] -            if 'admin_distance' in d: -                d['admin_distance'] = str(d['admin_distance']) +            if "admin_distance" in d: +                d["admin_distance"] = str(d["admin_distance"])              obj.append(d)      else: -        prefix = module.params['prefix'].strip() -        if '/' in prefix: -            mask = prefix.split('/')[1] -            prefix = prefix.split('/')[0] +        prefix = module.params["prefix"].strip() +        if "/" in prefix: +            mask = prefix.split("/")[1] +            prefix = prefix.split("/")[0]          else: -            mask = module.params['mask'].strip() -        next_hop = module.params['next_hop'].strip() -        admin_distance = str(module.params['admin_distance']) -        state = module.params['state'] - -        obj.append({ -            'prefix': prefix, -            'mask': mask, -            'next_hop': next_hop, -            'admin_distance': admin_distance, -            'state': state -        }) +            mask = module.params["mask"].strip() +        next_hop = module.params["next_hop"].strip() +        admin_distance = str(module.params["admin_distance"]) +        state = module.params["state"] + +        obj.append( +            { +                "prefix": prefix, +                "mask": mask, +                "next_hop": next_hop, +                "admin_distance": admin_distance, +                "state": state, +            } +        )      return obj @@ -216,54 +234,56 @@ def main():      """ main entry point for module execution      """      element_spec = dict( -        prefix=dict(type='str'), -        mask=dict(type='str'), -        next_hop=dict(type='str'), -        admin_distance=dict(type='int'), -        state=dict(default='present', choices=['present', 'absent']) +        prefix=dict(type="str"), +        mask=dict(type="str"), +        next_hop=dict(type="str"), +        admin_distance=dict(type="int"), +        state=dict(default="present", choices=["present", "absent"]),      )      aggregate_spec = deepcopy(element_spec) -    aggregate_spec['prefix'] = dict(required=True) +    aggregate_spec["prefix"] = dict(required=True)      # remove default in aggregate spec, to handle common arguments      remove_default_spec(aggregate_spec)      argument_spec = dict( -        aggregate=dict(type='list', elements='dict', options=aggregate_spec), +        aggregate=dict(type="list", elements="dict", options=aggregate_spec)      )      argument_spec.update(element_spec)      argument_spec.update(vyos_argument_spec) -    required_one_of = [['aggregate', 'prefix']] -    required_together = [['prefix', 'next_hop']] -    mutually_exclusive = [['aggregate', 'prefix']] +    required_one_of = [["aggregate", "prefix"]] +    required_together = [["prefix", "next_hop"]] +    mutually_exclusive = [["aggregate", "prefix"]] -    module = AnsibleModule(argument_spec=argument_spec, -                           required_one_of=required_one_of, -                           required_together=required_together, -                           mutually_exclusive=mutually_exclusive, -                           supports_check_mode=True) +    module = AnsibleModule( +        argument_spec=argument_spec, +        required_one_of=required_one_of, +        required_together=required_together, +        mutually_exclusive=mutually_exclusive, +        supports_check_mode=True, +    )      warnings = list() -    result = {'changed': False} +    result = {"changed": False}      if warnings: -        result['warnings'] = warnings +        result["warnings"] = warnings      want = map_params_to_obj(module, required_together=required_together)      have = config_to_dict(module)      commands = spec_to_commands((want, have), module) -    result['commands'] = commands +    result["commands"] = commands      if commands:          commit = not module.check_mode          load_config(module, commands, commit=commit) -        result['changed'] = True +        result["changed"] = True      module.exit_json(**result) -if __name__ == '__main__': +if __name__ == "__main__":      main() diff --git a/plugins/modules/vyos_system.py b/plugins/modules/vyos_system.py index 20cf907..9984154 100644 --- a/plugins/modules/vyos_system.py +++ b/plugins/modules/vyos_system.py @@ -17,9 +17,11 @@  # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.  # -ANSIBLE_METADATA = {'metadata_version': '1.1', -                    'status': ['preview'], -                    'supported_by': 'network'} +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": ["preview"], +    "supported_by": "network", +}  DOCUMENTATION = """ @@ -92,20 +94,22 @@ EXAMPLES = """  """  from ansible.module_utils.basic import AnsibleModule -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import get_config, load_config - -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import vyos_argument_spec +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    get_config, +    load_config, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    vyos_argument_spec, +)  def spec_key_to_device_key(key): -    device_key = key.replace('_', '-') +    device_key = key.replace("_", "-")      # domain-search is longer than just it's key -    if device_key == 'domain-search': -        device_key += ' domain' +    if device_key == "domain-search": +        device_key += " domain"      return device_key @@ -113,17 +117,17 @@ def spec_key_to_device_key(key):  def config_to_dict(module):      data = get_config(module) -    config = {'domain_search': [], 'name_server': []} +    config = {"domain_search": [], "name_server": []} -    for line in data.split('\n'): -        if line.startswith('set system host-name'): -            config['host_name'] = line[22:-1] -        elif line.startswith('set system domain-name'): -            config['domain_name'] = line[24:-1] -        elif line.startswith('set system domain-search domain'): -            config['domain_search'].append(line[33:-1]) -        elif line.startswith('set system name-server'): -            config['name_server'].append(line[24:-1]) +    for line in data.split("\n"): +        if line.startswith("set system host-name"): +            config["host_name"] = line[22:-1] +        elif line.startswith("set system domain-name"): +            config["domain_name"] = line[24:-1] +        elif line.startswith("set system domain-search domain"): +            config["domain_search"].append(line[33:-1]) +        elif line.startswith("set system name-server"): +            config["name_server"].append(line[24:-1])      return config @@ -131,13 +135,13 @@ def config_to_dict(module):  def spec_to_commands(want, have):      commands = [] -    state = want.pop('state') +    state = want.pop("state")      # state='absent' by itself has special meaning -    if state == 'absent' and all(v is None for v in want.values()): +    if state == "absent" and all(v is None for v in want.values()):          # Clear everything          for key in have: -            commands.append('delete system %s' % spec_key_to_device_key(key)) +            commands.append("delete system %s" % spec_key_to_device_key(key))      for key in want:          if want[key] is None: @@ -148,19 +152,19 @@ def spec_to_commands(want, have):          device_key = spec_key_to_device_key(key)          # These keys are lists which may need to  be reconciled with the device -        if key in ['domain_search', 'name_server']: +        if key in ["domain_search", "name_server"]:              if not proposed:                  # Empty list was passed, delete all values                  commands.append("delete system %s" % device_key)              for config in proposed: -                if state == 'absent' and config in current: +                if state == "absent" and config in current:                      commands.append("delete system %s '%s'" % (device_key, config)) -                elif state == 'present' and config not in current: +                elif state == "present" and config not in current:                      commands.append("set system %s '%s'" % (device_key, config))          else: -            if state == 'absent' and current and proposed: -                commands.append('delete system %s' % device_key) -            elif state == 'present' and proposed and proposed != current: +            if state == "absent" and current and proposed: +                commands.append("delete system %s" % device_key) +            elif state == "present" and proposed and proposed != current:                  commands.append("set system %s '%s'" % (device_key, proposed))      return commands @@ -168,21 +172,21 @@ def spec_to_commands(want, have):  def map_param_to_obj(module):      return { -        'host_name': module.params['host_name'], -        'domain_name': module.params['domain_name'], -        'domain_search': module.params['domain_search'], -        'name_server': module.params['name_server'], -        'state': module.params['state'] +        "host_name": module.params["host_name"], +        "domain_name": module.params["domain_name"], +        "domain_search": module.params["domain_search"], +        "name_server": module.params["name_server"], +        "state": module.params["state"],      }  def main():      argument_spec = dict( -        host_name=dict(type='str'), -        domain_name=dict(type='str'), -        domain_search=dict(type='list'), -        name_server=dict(type='list', aliases=['name_servers']), -        state=dict(type='str', default='present', choices=['present', 'absent']), +        host_name=dict(type="str"), +        domain_name=dict(type="str"), +        domain_search=dict(type="list"), +        name_server=dict(type="list", aliases=["name_servers"]), +        state=dict(type="str", default="present", choices=["present", "absent"]),      )      argument_spec.update(vyos_argument_spec) @@ -190,26 +194,26 @@ def main():      module = AnsibleModule(          argument_spec=argument_spec,          supports_check_mode=True, -        mutually_exclusive=[('domain_name', 'domain_search')], +        mutually_exclusive=[("domain_name", "domain_search")],      )      warnings = list() -    result = {'changed': False, 'warnings': warnings} +    result = {"changed": False, "warnings": warnings}      want = map_param_to_obj(module)      have = config_to_dict(module)      commands = spec_to_commands(want, have) -    result['commands'] = commands +    result["commands"] = commands      if commands:          commit = not module.check_mode          response = load_config(module, commands, commit=commit) -        result['changed'] = True +        result["changed"] = True      module.exit_json(**result) -if __name__ == '__main__': +if __name__ == "__main__":      main() diff --git a/plugins/modules/vyos_user.py b/plugins/modules/vyos_user.py index e670d55..74ec720 100644 --- a/plugins/modules/vyos_user.py +++ b/plugins/modules/vyos_user.py @@ -19,9 +19,11 @@  # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.  # -ANSIBLE_METADATA = {'metadata_version': '1.1', -                    'status': ['preview'], -                    'supported_by': 'network'} +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": ["preview"], +    "supported_by": "network", +}  DOCUMENTATION = """  --- @@ -137,60 +139,67 @@ from functools import partial  from ansible.module_utils.basic import AnsibleModule  from ansible.module_utils.network.common.utils import remove_default_spec -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import get_config, load_config +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    get_config, +    load_config, +)  from ansible.module_utils.six import iteritems -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import vyos_argument_spec - +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    vyos_argument_spec, +)  def validate_level(value, module): -    if value not in ('admin', 'operator'): -        module.fail_json(msg='level must be either admin or operator, got %s' % value) +    if value not in ("admin", "operator"): +        module.fail_json(msg="level must be either admin or operator, got %s" % value)  def spec_to_commands(updates, module):      commands = list() -    state = module.params['state'] -    update_password = module.params['update_password'] +    state = module.params["state"] +    update_password = module.params["update_password"]      def needs_update(want, have, x):          return want.get(x) and (want.get(x) != have.get(x))      def add(command, want, x): -        command.append('set system login user %s %s' % (want['name'], x)) +        command.append("set system login user %s %s" % (want["name"], x))      for update in updates:          want, have = update -        if want['state'] == 'absent': -            commands.append('delete system login user %s' % want['name']) +        if want["state"] == "absent": +            commands.append("delete system login user %s" % want["name"])              continue -        if needs_update(want, have, 'level'): -            add(commands, want, "level %s" % want['level']) +        if needs_update(want, have, "level"): +            add(commands, want, "level %s" % want["level"]) -        if needs_update(want, have, 'full_name'): -            add(commands, want, "full-name %s" % want['full_name']) +        if needs_update(want, have, "full_name"): +            add(commands, want, "full-name %s" % want["full_name"]) -        if needs_update(want, have, 'configured_password'): -            if update_password == 'always' or not have: -                add(commands, want, 'authentication plaintext-password %s' % want['configured_password']) +        if needs_update(want, have, "configured_password"): +            if update_password == "always" or not have: +                add( +                    commands, +                    want, +                    "authentication plaintext-password %s" +                    % want["configured_password"], +                )      return commands  def parse_level(data): -    match = re.search(r'level (\S+)', data, re.M) +    match = re.search(r"level (\S+)", data, re.M)      if match:          level = match.group(1)[1:-1]          return level  def parse_full_name(data): -    match = re.search(r'full-name (\S+)', data, re.M) +    match = re.search(r"full-name (\S+)", data, re.M)      if match:          full_name = match.group(1)[1:-1]          return full_name @@ -199,22 +208,22 @@ def parse_full_name(data):  def config_to_dict(module):      data = get_config(module) -    match = re.findall(r'^set system login user (\S+)', data, re.M) +    match = re.findall(r"^set system login user (\S+)", data, re.M)      if not match:          return list()      instances = list()      for user in set(match): -        regex = r' %s .+$' % user +        regex = r" %s .+$" % user          cfg = re.findall(regex, data, re.M) -        cfg = '\n'.join(cfg) +        cfg = "\n".join(cfg)          obj = { -            'name': user, -            'state': 'present', -            'configured_password': None, -            'level': parse_level(cfg), -            'full_name': parse_full_name(cfg) +            "name": user, +            "state": "present", +            "configured_password": None, +            "level": parse_level(cfg), +            "full_name": parse_full_name(cfg),          }          instances.append(obj) @@ -227,7 +236,7 @@ def get_param_value(key, item, module):          value = module.params[key]      # validate the param value (if validator func exists) -    validator = globals().get('validate_%s' % key) +    validator = globals().get("validate_%s" % key)      if all((value, validator)):          validator(value, module) @@ -235,17 +244,17 @@ def get_param_value(key, item, module):  def map_params_to_obj(module): -    aggregate = module.params['aggregate'] +    aggregate = module.params["aggregate"]      if not aggregate: -        if not module.params['name'] and module.params['purge']: +        if not module.params["name"] and module.params["purge"]:              return list()          else: -            users = [{'name': module.params['name']}] +            users = [{"name": module.params["name"]}]      else:          users = list()          for item in aggregate:              if not isinstance(item, dict): -                users.append({'name': item}) +                users.append({"name": item})              else:                  users.append(item) @@ -253,10 +262,10 @@ def map_params_to_obj(module):      for item in users:          get_value = partial(get_param_value, item=item, module=module) -        item['configured_password'] = get_value('configured_password') -        item['full_name'] = get_value('full_name') -        item['level'] = get_value('level') -        item['state'] = get_value('state') +        item["configured_password"] = get_value("configured_password") +        item["full_name"] = get_value("full_name") +        item["level"] = get_value("level") +        item["state"] = get_value("state")          objects.append(item)      return objects @@ -265,7 +274,7 @@ def map_params_to_obj(module):  def update_objects(want, have):      updates = list()      for entry in want: -        item = next((i for i in have if i['name'] == entry['name']), None) +        item = next((i for i in have if i["name"] == entry["name"]), None)          if item is None:              updates.append((entry, {}))          elif item: @@ -280,65 +289,69 @@ def main():      """      element_spec = dict(          name=dict(), -          full_name=dict(), -        level=dict(aliases=['role']), - +        level=dict(aliases=["role"]),          configured_password=dict(no_log=True), -        update_password=dict(default='always', choices=['on_create', 'always']), - -        state=dict(default='present', choices=['present', 'absent']) +        update_password=dict(default="always", choices=["on_create", "always"]), +        state=dict(default="present", choices=["present", "absent"]),      )      aggregate_spec = deepcopy(element_spec) -    aggregate_spec['name'] = dict(required=True) +    aggregate_spec["name"] = dict(required=True)      # remove default in aggregate spec, to handle common arguments      remove_default_spec(aggregate_spec)      argument_spec = dict( -        aggregate=dict(type='list', elements='dict', options=aggregate_spec, aliases=['users', 'collection']), -        purge=dict(type='bool', default=False) +        aggregate=dict( +            type="list", +            elements="dict", +            options=aggregate_spec, +            aliases=["users", "collection"], +        ), +        purge=dict(type="bool", default=False),      )      argument_spec.update(element_spec)      argument_spec.update(vyos_argument_spec) -    mutually_exclusive = [('name', 'aggregate')] -    module = AnsibleModule(argument_spec=argument_spec, -                           mutually_exclusive=mutually_exclusive, -                           supports_check_mode=True) +    mutually_exclusive = [("name", "aggregate")] +    module = AnsibleModule( +        argument_spec=argument_spec, +        mutually_exclusive=mutually_exclusive, +        supports_check_mode=True, +    )      warnings = list() -    if module.params['password'] and not module.params['configured_password']: +    if module.params["password"] and not module.params["configured_password"]:          warnings.append( -            'The "password" argument is used to authenticate the current connection. ' + -            'To set a user password use "configured_password" instead.' +            'The "password" argument is used to authenticate the current connection. ' +            + 'To set a user password use "configured_password" instead.'          ) -    result = {'changed': False} +    result = {"changed": False}      if warnings: -        result['warnings'] = warnings +        result["warnings"] = warnings      want = map_params_to_obj(module)      have = config_to_dict(module)      commands = spec_to_commands(update_objects(want, have), module) -    if module.params['purge']: -        want_users = [x['name'] for x in want] -        have_users = [x['name'] for x in have] +    if module.params["purge"]: +        want_users = [x["name"] for x in want] +        have_users = [x["name"] for x in have]          for item in set(have_users).difference(want_users): -            commands.append('delete system login user %s' % item) +            commands.append("delete system login user %s" % item) -    result['commands'] = commands +    result["commands"] = commands      if commands:          commit = not module.check_mode          load_config(module, commands, commit=commit) -        result['changed'] = True +        result["changed"] = True      module.exit_json(**result) -if __name__ == '__main__': +if __name__ == "__main__":      main() diff --git a/plugins/modules/vyos_vlan.py b/plugins/modules/vyos_vlan.py index 88ab71b..983a50a 100644 --- a/plugins/modules/vyos_vlan.py +++ b/plugins/modules/vyos_vlan.py @@ -5,12 +5,15 @@  # 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 +  __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', -                    'status': ['preview'], -                    'supported_by': 'network'} +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": ["preview"], +    "supported_by": "network", +}  DOCUMENTATION = """  --- @@ -122,18 +125,20 @@ from copy import deepcopy  from ansible.module_utils.basic import AnsibleModule  from ansible.module_utils.network.common.utils import remove_default_spec -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import load_config, run_commands - -from ansible_collections.vyos.vyos.plugins.module_utils.network. \ -  vyos.vyos import vyos_argument_spec +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    load_config, +    run_commands, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    vyos_argument_spec, +)  def search_obj_in_list(vlan_id, lst):      obj = list()      for o in lst: -        if o['vlan_id'] == vlan_id: +        if o["vlan_id"] == vlan_id:              obj.append(o)      return obj @@ -141,48 +146,52 @@ def search_obj_in_list(vlan_id, lst):  def map_obj_to_commands(updates, module):      commands = list()      want, have = updates -    purge = module.params['purge'] +    purge = module.params["purge"]      for w in want: -        vlan_id = w['vlan_id'] -        name = w['name'] -        address = w['address'] -        state = w['state'] -        interfaces = w['interfaces'] +        vlan_id = w["vlan_id"] +        name = w["name"] +        address = w["address"] +        state = w["state"] +        interfaces = w["interfaces"]          obj_in_have = search_obj_in_list(vlan_id, have) -        if state == 'absent': +        if state == "absent":              if obj_in_have:                  for obj in obj_in_have: -                    for i in obj['interfaces']: -                        commands.append('delete interfaces ethernet {0} vif {1}'.format(i, vlan_id)) +                    for i in obj["interfaces"]: +                        commands.append( +                            "delete interfaces ethernet {0} vif {1}".format(i, vlan_id) +                        ) -        elif state == 'present': +        elif state == "present":              if not obj_in_have: -                if w['interfaces'] and w['vlan_id']: -                    for i in w['interfaces']: -                        cmd = 'set interfaces ethernet {0} vif {1}'.format(i, vlan_id) -                        if w['name']: -                            commands.append(cmd + ' description {0}'.format(name)) -                        elif w['address']: -                            commands.append(cmd + ' address {0}'.format(address)) +                if w["interfaces"] and w["vlan_id"]: +                    for i in w["interfaces"]: +                        cmd = "set interfaces ethernet {0} vif {1}".format(i, vlan_id) +                        if w["name"]: +                            commands.append(cmd + " description {0}".format(name)) +                        elif w["address"]: +                            commands.append(cmd + " address {0}".format(address))                          else:                              commands.append(cmd)      if purge:          for h in have: -            obj_in_want = search_obj_in_list(h['vlan_id'], want) +            obj_in_want = search_obj_in_list(h["vlan_id"], want)              if not obj_in_want: -                for i in h['interfaces']: -                    commands.append('delete interfaces ethernet {0} vif {1}'.format(i, h['vlan_id'])) +                for i in h["interfaces"]: +                    commands.append( +                        "delete interfaces ethernet {0} vif {1}".format(i, h["vlan_id"]) +                    )      return commands  def map_params_to_obj(module):      obj = [] -    aggregate = module.params.get('aggregate') +    aggregate = module.params.get("aggregate")      if aggregate:          for item in aggregate:              for key in item: @@ -191,22 +200,24 @@ def map_params_to_obj(module):              d = item.copy() -            if not d['vlan_id']: -                module.fail_json(msg='vlan_id is required') +            if not d["vlan_id"]: +                module.fail_json(msg="vlan_id is required") -            d['vlan_id'] = str(d['vlan_id']) +            d["vlan_id"] = str(d["vlan_id"])              module._check_required_one_of(module.required_one_of, item)              obj.append(d)      else: -        obj.append({ -            'vlan_id': str(module.params['vlan_id']), -            'name': module.params['name'], -            'address': module.params['address'], -            'state': module.params['state'], -            'interfaces': module.params['interfaces'], -            'associated_interfaces': module.params['associated_interfaces'] -        }) +        obj.append( +            { +                "vlan_id": str(module.params["vlan_id"]), +                "name": module.params["name"], +                "address": module.params["address"], +                "state": module.params["state"], +                "interfaces": module.params["interfaces"], +                "associated_interfaces": module.params["associated_interfaces"], +            } +        )      return obj @@ -215,30 +226,30 @@ def map_config_to_obj(module):      objs = []      interfaces = list() -    output = run_commands(module, 'show interfaces') +    output = run_commands(module, "show interfaces")      lines = output[0].strip().splitlines()[3:]      for l in lines: -        splitted_line = re.split(r'\s{2,}', l.strip()) +        splitted_line = re.split(r"\s{2,}", l.strip())          obj = {}          eth = splitted_line[0].strip("'") -        if eth.startswith('eth'): -            obj['interfaces'] = [] -            if '.' in eth: -                interface = eth.split('.')[0] -                obj['interfaces'].append(interface) -                obj['vlan_id'] = eth.split('.')[-1] +        if eth.startswith("eth"): +            obj["interfaces"] = [] +            if "." in eth: +                interface = eth.split(".")[0] +                obj["interfaces"].append(interface) +                obj["vlan_id"] = eth.split(".")[-1]              else: -                obj['interfaces'].append(eth) -                obj['vlan_id'] = None +                obj["interfaces"].append(eth) +                obj["vlan_id"] = None -            if splitted_line[1].strip("'") != '-': -                obj['address'] = splitted_line[1].strip("'") +            if splitted_line[1].strip("'") != "-": +                obj["address"] = splitted_line[1].strip("'")              if len(splitted_line) > 3: -                obj['name'] = splitted_line[3].strip("'") -            obj['state'] = 'present' +                obj["name"] = splitted_line[3].strip("'") +            obj["state"] = "present"              objs.append(obj)      return objs @@ -251,41 +262,44 @@ def check_declarative_intent_params(want, module, result):      is_delay = False      for w in want: -        if w.get('associated_interfaces') is None: +        if w.get("associated_interfaces") is None:              continue -        if result['changed'] and not is_delay: -            time.sleep(module.params['delay']) +        if result["changed"] and not is_delay: +            time.sleep(module.params["delay"])              is_delay = True          if have is None:              have = map_config_to_obj(module) -        obj_in_have = search_obj_in_list(w['vlan_id'], have) +        obj_in_have = search_obj_in_list(w["vlan_id"], have)          if obj_in_have:              for obj in obj_in_have: -                obj_interface.extend(obj['interfaces']) +                obj_interface.extend(obj["interfaces"])      for w in want: -        if w.get('associated_interfaces') is None: +        if w.get("associated_interfaces") is None:              continue -        for i in w['associated_interfaces']: -            if (set(obj_interface) - set(w['associated_interfaces'])) != set([]): -                module.fail_json(msg='Interface {0} not configured on vlan {1}'.format(i, w['vlan_id'])) +        for i in w["associated_interfaces"]: +            if (set(obj_interface) - set(w["associated_interfaces"])) != set([]): +                module.fail_json( +                    msg="Interface {0} not configured on vlan {1}".format( +                        i, w["vlan_id"] +                    ) +                )  def main():      """ main entry point for module execution      """      element_spec = dict( -        vlan_id=dict(type='int'), +        vlan_id=dict(type="int"),          name=dict(),          address=dict(), -        interfaces=dict(type='list'), -        associated_interfaces=dict(type='list'), -        delay=dict(default=10, type='int'), -        state=dict(default='present', -                   choices=['present', 'absent']) +        interfaces=dict(type="list"), +        associated_interfaces=dict(type="list"), +        delay=dict(default=10, type="int"), +        state=dict(default="present", choices=["present", "absent"]),      )      aggregate_spec = deepcopy(element_spec) @@ -294,43 +308,47 @@ def main():      remove_default_spec(aggregate_spec)      argument_spec = dict( -        aggregate=dict(type='list', elements='dict', options=aggregate_spec), -        purge=dict(default=False, type='bool') +        aggregate=dict(type="list", elements="dict", options=aggregate_spec), +        purge=dict(default=False, type="bool"),      )      argument_spec.update(element_spec)      argument_spec.update(vyos_argument_spec) -    required_one_of = [['vlan_id', 'aggregate'], -                       ['aggregate', 'interfaces', 'associated_interfaces']] - -    mutually_exclusive = [['vlan_id', 'aggregate']] -    module = AnsibleModule(argument_spec=argument_spec, -                           supports_check_mode=True, -                           required_one_of=required_one_of, -                           mutually_exclusive=mutually_exclusive) +    required_one_of = [ +        ["vlan_id", "aggregate"], +        ["aggregate", "interfaces", "associated_interfaces"], +    ] + +    mutually_exclusive = [["vlan_id", "aggregate"]] +    module = AnsibleModule( +        argument_spec=argument_spec, +        supports_check_mode=True, +        required_one_of=required_one_of, +        mutually_exclusive=mutually_exclusive, +    )      warnings = list() -    result = {'changed': False} +    result = {"changed": False}      if warnings: -        result['warnings'] = warnings +        result["warnings"] = warnings      want = map_params_to_obj(module)      have = map_config_to_obj(module)      commands = map_obj_to_commands((want, have), module) -    result['commands'] = commands +    result["commands"] = commands      if commands:          commit = not module.check_mode          load_config(module, commands, commit=commit) -        result['changed'] = True +        result["changed"] = True      check_declarative_intent_params(want, module, result)      module.exit_json(**result) -if __name__ == '__main__': +if __name__ == "__main__":      main() | 
