We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
onyx_pfc_interface throws exception when using onyx version 3.6.6000
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and devel branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest -->
 - Bug Report

##### COMPONENT NAME
<!---
Name of the module, plugin, task or feature
Do not include extra details here, e.g. "vyos_command" not "the network module vyos_command" or the full path
-->
onyx_pfc_interface.py

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.6.0 (devel c1008d693c) last updated 2018/03/12 15:51:01 (GMT +000)
  python version = 2.7.5 (default, Nov  6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]
```

##### CONFIGURATION
<!---
If using Ansible 2.4 or above, paste the results of "ansible-config dump --only-changed"
Otherwise, mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->

##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say "N/A" for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.
-->
N/A

##### SUMMARY
<!--- Explain the problem briefly -->
when running command onyx_pfc_interface on onyx network device with version 3.6.6000 or later, there is an exception.

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->
run any playbook with onyx_pfc_interface

<!--- Paste example playbooks or commands between quotes below -->
```yaml
- name: Disable Lag members PFC
  onyx_pfc_interface:
    aggregate:
      - name: Eth1/15
      - name: Eth1/16
    state: disabled
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
pfc interface will be configured

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->
Command failed with exception
<!--- Paste verbatim command output between quotes below -->
```
<swi60> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1520431892.25-242550331138460/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_gof89B/ansible_module_onyx_pfc_interface.py", line 205, in <module>
    main()
  File "/tmp/ansible_gof89B/ansible_module_onyx_pfc_interface.py", line 201, in main
    OnyxPfcInterfaceModule.main()
  File "/tmp/ansible_gof89B/ansible_modlib.zip/ansible/module_utils/network/onyx/onyx.py", line 229, in main
  File "/tmp/ansible_gof89B/ansible_modlib.zip/ansible/module_utils/network/onyx/onyx.py", line 207, in run
  File "/tmp/ansible_gof89B/ansible_module_onyx_pfc_interface.py", line 149, in load_current_config
    for if_name, if_pfc_data in iteritems(pfc_config):
  File "/tmp/ansible_gof89B/ansible_modlib.zip/ansible/module_utils/six/__init__.py", line 610, in iteritems
AttributeError: 'list' object has no attribute 'iteritems'
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lib/ansible/modules/network/onyx/onyx_pfc_interface.py`
Content:
```
1 #!/usr/bin/python
2 #
3 # Copyright: Ansible Project
4 # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
5 
6 from __future__ import absolute_import, division, print_function
7 __metaclass__ = type
8 
9 ANSIBLE_METADATA = {'metadata_version': '1.1',
10                     'status': ['preview'],
11                     'supported_by': 'community'}
12 
13 DOCUMENTATION = """
14 ---
15 module: onyx_pfc_interface
16 version_added: "2.5"
17 author: "Samer Deeb (@samerd)"
18 short_description: Manage priority flow control on ONYX network devices
19 description:
20   - This module provides declarative management of priority flow control (PFC)
21     on interfaces of Mellanox ONYX network devices.
22 notes:
23   - Tested on ONYX 3.6.4000
24 options:
25   name:
26     description:
27       - Name of the interface PFC should be configured on.
28   aggregate:
29     description: List of interfaces PFC should be configured on.
30   purge:
31     description:
32       - Purge interfaces not defined in the aggregate parameter.
33     type: bool
34     default: false
35   state:
36     description:
37       - State of the PFC configuration.
38     default: enabled
39     choices: ['enabled', 'disabled']
40 """
41 
42 EXAMPLES = """
43 - name: configure PFC
44   onyx_pfc_interface:
45     name: Eth1/1
46     state: enabled
47 """
48 
49 RETURN = """
50 commands:
51   description: The list of configuration mode commands to send to the device.
52   returned: always
53   type: list
54   sample:
55     - interface ethernet 1/17 dcb priority-flow-control mode on
56 """
57 from copy import deepcopy
58 import re
59 
60 from ansible.module_utils.basic import AnsibleModule
61 from ansible.module_utils.network.common.utils import remove_default_spec
62 from ansible.module_utils.six import iteritems
63 
64 from ansible.module_utils.network.onyx.onyx import BaseOnyxModule
65 from ansible.module_utils.network.onyx.onyx import show_cmd
66 
67 
68 class OnyxPfcInterfaceModule(BaseOnyxModule):
69     PFC_IF_REGEX = re.compile(
70         r"^(Eth\d+\/\d+)|(Eth\d+\/\d+\/\d+)|(Po\d+)|(Mpo\d+)$")
71 
72     _purge = False
73 
74     @classmethod
75     def _get_element_spec(cls):
76         return dict(
77             name=dict(type='str'),
78             state=dict(default='enabled',
79                        choices=['enabled', 'disabled']),
80         )
81 
82     @classmethod
83     def _get_aggregate_spec(cls, element_spec):
84         aggregate_spec = deepcopy(element_spec)
85         aggregate_spec['name'] = dict(required=True)
86 
87         # remove default in aggregate spec, to handle common arguments
88         remove_default_spec(aggregate_spec)
89         return aggregate_spec
90 
91     def init_module(self):
92         """ module initialization
93         """
94         element_spec = self._get_element_spec()
95         aggregate_spec = self._get_aggregate_spec(element_spec)
96         argument_spec = dict(
97             aggregate=dict(type='list', elements='dict',
98                            options=aggregate_spec),
99             purge=dict(default=False, type='bool'),
100         )
101         argument_spec.update(element_spec)
102         required_one_of = [['name', 'aggregate']]
103         mutually_exclusive = [['name', 'aggregate']]
104         self._module = AnsibleModule(
105             argument_spec=argument_spec,
106             required_one_of=required_one_of,
107             mutually_exclusive=mutually_exclusive,
108             supports_check_mode=True)
109 
110     def get_required_config(self):
111         self._required_config = list()
112         module_params = self._module.params
113         aggregate = module_params.get('aggregate')
114         self._purge = module_params.get('purge', False)
115         if aggregate:
116             for item in aggregate:
117                 for key in item:
118                     if item.get(key) is None:
119                         item[key] = module_params[key]
120                 self.validate_param_values(item, item)
121                 req_item = item.copy()
122                 self._required_config.append(req_item)
123         else:
124             params = {
125                 'name': module_params['name'],
126                 'state': module_params['state'],
127             }
128             self.validate_param_values(params)
129             self._required_config.append(params)
130 
131     def _create_if_pfc_data(self, if_name, if_pfc_data):
132         state = self.get_config_attr(if_pfc_data, "PFC oper")
133         state = state.lower()
134         return dict(
135             name=if_name,
136             state=state)
137 
138     def _get_pfc_config(self):
139         return show_cmd(self._module, "show dcb priority-flow-control")
140 
141     def load_current_config(self):
142         # called in base class in run function
143         self._current_config = dict()
144         pfc_config = self._get_pfc_config()
145         if not pfc_config:
146             return
147         if 'Table 2' in pfc_config:
148             pfc_config = pfc_config['Table 2']
149         for if_name, if_pfc_data in iteritems(pfc_config):
150             match = self.PFC_IF_REGEX.match(if_name)
151             if not match:
152                 continue
153             if if_pfc_data:
154                 if_pfc_data = if_pfc_data[0]
155                 self._current_config[if_name] = \
156                     self._create_if_pfc_data(if_name, if_pfc_data)
157 
158     def _get_interface_cmd_name(self, if_name):
159         if if_name.startswith('Eth'):
160             return if_name.replace("Eth", "ethernet ")
161         if if_name.startswith('Po'):
162             return if_name.replace("Po", "port-channel ")
163         if if_name.startswith('Mpo'):
164             return if_name.replace("Mpo", "mlag-port-channel ")
165         self._module.fail_json(
166             msg='invalid interface name: %s' % if_name)
167 
168     def _add_if_pfc_commands(self, if_name, req_state):
169         cmd_prefix = "interface %s " % self._get_interface_cmd_name(if_name)
170 
171         if req_state == 'disabled':
172             pfc_cmd = 'no dcb priority-flow-control mode force'
173         else:
174             pfc_cmd = 'dcb priority-flow-control mode on force'
175         self._commands.append(cmd_prefix + pfc_cmd)
176 
177     def _gen_pfc_commands(self, if_name, curr_conf, req_state):
178         curr_state = curr_conf.get('state', 'disabled')
179         if curr_state != req_state:
180             self._add_if_pfc_commands(if_name, req_state)
181 
182     def generate_commands(self):
183         req_interfaces = set()
184         for req_conf in self._required_config:
185             req_state = req_conf['state']
186             if_name = req_conf['name']
187             if req_state == 'enabled':
188                 req_interfaces.add(if_name)
189             curr_conf = self._current_config.get(if_name, {})
190             self._gen_pfc_commands(if_name, curr_conf, req_state)
191         if self._purge:
192             for if_name, curr_conf in iteritems(self._current_config):
193                 if if_name not in req_interfaces:
194                     req_state = 'disabled'
195                     self._gen_pfc_commands(if_name, curr_conf, req_state)
196 
197 
198 def main():
199     """ main entry point for module execution
200     """
201     OnyxPfcInterfaceModule.main()
202 
203 
204 if __name__ == '__main__':
205     main()
206
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/lib/ansible/modules/network/onyx/onyx_pfc_interface.py b/lib/ansible/modules/network/onyx/onyx_pfc_interface.py
--- a/lib/ansible/modules/network/onyx/onyx_pfc_interface.py
+++ b/lib/ansible/modules/network/onyx/onyx_pfc_interface.py
@@ -140,12 +140,20 @@
 
     def load_current_config(self):
         # called in base class in run function
+        self._os_version = self._get_os_version()
         self._current_config = dict()
         pfc_config = self._get_pfc_config()
         if not pfc_config:
             return
-        if 'Table 2' in pfc_config:
-            pfc_config = pfc_config['Table 2']
+        if self._os_version >= self.ONYX_API_VERSION:
+            if len(pfc_config) >= 3:
+                pfc_config = pfc_config[2]
+            else:
+                pfc_config = dict()
+        else:
+            if 'Table 2' in pfc_config:
+                pfc_config = pfc_config['Table 2']
+
         for if_name, if_pfc_data in iteritems(pfc_config):
             match = self.PFC_IF_REGEX.match(if_name)
             if not match:

{"golden_diff": "diff --git a/lib/ansible/modules/network/onyx/onyx_pfc_interface.py b/lib/ansible/modules/network/onyx/onyx_pfc_interface.py\n--- a/lib/ansible/modules/network/onyx/onyx_pfc_interface.py\n+++ b/lib/ansible/modules/network/onyx/onyx_pfc_interface.py\n@@ -140,12 +140,20 @@\n \n     def load_current_config(self):\n         # called in base class in run function\n+        self._os_version = self._get_os_version()\n         self._current_config = dict()\n         pfc_config = self._get_pfc_config()\n         if not pfc_config:\n             return\n-        if 'Table 2' in pfc_config:\n-            pfc_config = pfc_config['Table 2']\n+        if self._os_version >= self.ONYX_API_VERSION:\n+            if len(pfc_config) >= 3:\n+                pfc_config = pfc_config[2]\n+            else:\n+                pfc_config = dict()\n+        else:\n+            if 'Table 2' in pfc_config:\n+                pfc_config = pfc_config['Table 2']\n+\n         for if_name, if_pfc_data in iteritems(pfc_config):\n             match = self.PFC_IF_REGEX.match(if_name)\n             if not match:\n", "issue": "onyx_pfc_interface throws exception when using onyx version 3.6.6000\n<!---\r\nVerify first that your issue/request is not already reported on GitHub.\r\nAlso test if the latest release, and devel branch are affected too.\r\n-->\r\n\r\n##### ISSUE TYPE\r\n<!--- Pick one below and delete the rest -->\r\n - Bug Report\r\n\r\n##### COMPONENT NAME\r\n<!---\r\nName of the module, plugin, task or feature\r\nDo not include extra details here, e.g. \"vyos_command\" not \"the network module vyos_command\" or the full path\r\n-->\r\nonyx_pfc_interface.py\r\n\r\n##### ANSIBLE VERSION\r\n<!--- Paste verbatim output from \"ansible --version\" between quotes below -->\r\n```\r\nansible 2.6.0 (devel c1008d693c) last updated 2018/03/12 15:51:01 (GMT +000)\r\n  python version = 2.7.5 (default, Nov  6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]\r\n```\r\n\r\n##### CONFIGURATION\r\n<!---\r\nIf using Ansible 2.4 or above, paste the results of \"ansible-config dump --only-changed\"\r\nOtherwise, mention any settings you have changed/added/removed in ansible.cfg\r\n(or using the ANSIBLE_* environment variables).\r\n-->\r\n\r\n##### OS / ENVIRONMENT\r\n<!---\r\nMention the OS you are running Ansible from, and the OS you are\r\nmanaging, or say \"N/A\" for anything that is not platform-specific.\r\nAlso mention the specific version of what you are trying to control,\r\ne.g. if this is a network bug the version of firmware on the network device.\r\n-->\r\nN/A\r\n\r\n##### SUMMARY\r\n<!--- Explain the problem briefly -->\r\nwhen running command onyx_pfc_interface on onyx network device with version 3.6.6000 or later, there is an exception.\r\n\r\n##### STEPS TO REPRODUCE\r\n<!---\r\nFor bugs, show exactly how to reproduce the problem, using a minimal test-case.\r\nFor new features, show how the feature would be used.\r\n-->\r\nrun any playbook with onyx_pfc_interface\r\n\r\n<!--- Paste example playbooks or commands between quotes below -->\r\n```yaml\r\n- name: Disable Lag members PFC\r\n  onyx_pfc_interface:\r\n    aggregate:\r\n      - name: Eth1/15\r\n      - name: Eth1/16\r\n    state: disabled\r\n```\r\n\r\n<!--- You can also paste gist.github.com links for larger files -->\r\n\r\n##### EXPECTED RESULTS\r\n<!--- What did you expect to happen when running the steps above? -->\r\npfc interface will be configured\r\n\r\n##### ACTUAL RESULTS\r\n<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->\r\nCommand failed with exception\r\n<!--- Paste verbatim command output between quotes below -->\r\n```\r\n<swi60> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1520431892.25-242550331138460/ > /dev/null 2>&1 && sleep 0'\r\nThe full traceback is:\r\nTraceback (most recent call last):\r\n  File \"/tmp/ansible_gof89B/ansible_module_onyx_pfc_interface.py\", line 205, in <module>\r\n    main()\r\n  File \"/tmp/ansible_gof89B/ansible_module_onyx_pfc_interface.py\", line 201, in main\r\n    OnyxPfcInterfaceModule.main()\r\n  File \"/tmp/ansible_gof89B/ansible_modlib.zip/ansible/module_utils/network/onyx/onyx.py\", line 229, in main\r\n  File \"/tmp/ansible_gof89B/ansible_modlib.zip/ansible/module_utils/network/onyx/onyx.py\", line 207, in run\r\n  File \"/tmp/ansible_gof89B/ansible_module_onyx_pfc_interface.py\", line 149, in load_current_config\r\n    for if_name, if_pfc_data in iteritems(pfc_config):\r\n  File \"/tmp/ansible_gof89B/ansible_modlib.zip/ansible/module_utils/six/__init__.py\", line 610, in iteritems\r\nAttributeError: 'list' object has no attribute 'iteritems'\r\n```\r\n\n", "before_files": [{"content": "#!/usr/bin/python\n#\n# Copyright: Ansible Project\n# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)\n\nfrom __future__ import absolute_import, division, print_function\n__metaclass__ = type\n\nANSIBLE_METADATA = {'metadata_version': '1.1',\n                    'status': ['preview'],\n                    'supported_by': 'community'}\n\nDOCUMENTATION = \"\"\"\n---\nmodule: onyx_pfc_interface\nversion_added: \"2.5\"\nauthor: \"Samer Deeb (@samerd)\"\nshort_description: Manage priority flow control on ONYX network devices\ndescription:\n  - This module provides declarative management of priority flow control (PFC)\n    on interfaces of Mellanox ONYX network devices.\nnotes:\n  - Tested on ONYX 3.6.4000\noptions:\n  name:\n    description:\n      - Name of the interface PFC should be configured on.\n  aggregate:\n    description: List of interfaces PFC should be configured on.\n  purge:\n    description:\n      - Purge interfaces not defined in the aggregate parameter.\n    type: bool\n    default: false\n  state:\n    description:\n      - State of the PFC configuration.\n    default: enabled\n    choices: ['enabled', 'disabled']\n\"\"\"\n\nEXAMPLES = \"\"\"\n- name: configure PFC\n  onyx_pfc_interface:\n    name: Eth1/1\n    state: enabled\n\"\"\"\n\nRETURN = \"\"\"\ncommands:\n  description: The list of configuration mode commands to send to the device.\n  returned: always\n  type: list\n  sample:\n    - interface ethernet 1/17 dcb priority-flow-control mode on\n\"\"\"\nfrom copy import deepcopy\nimport re\n\nfrom ansible.module_utils.basic import AnsibleModule\nfrom ansible.module_utils.network.common.utils import remove_default_spec\nfrom ansible.module_utils.six import iteritems\n\nfrom ansible.module_utils.network.onyx.onyx import BaseOnyxModule\nfrom ansible.module_utils.network.onyx.onyx import show_cmd\n\n\nclass OnyxPfcInterfaceModule(BaseOnyxModule):\n    PFC_IF_REGEX = re.compile(\n        r\"^(Eth\\d+\\/\\d+)|(Eth\\d+\\/\\d+\\/\\d+)|(Po\\d+)|(Mpo\\d+)$\")\n\n    _purge = False\n\n    @classmethod\n    def _get_element_spec(cls):\n        return dict(\n            name=dict(type='str'),\n            state=dict(default='enabled',\n                       choices=['enabled', 'disabled']),\n        )\n\n    @classmethod\n    def _get_aggregate_spec(cls, element_spec):\n        aggregate_spec = deepcopy(element_spec)\n        aggregate_spec['name'] = dict(required=True)\n\n        # remove default in aggregate spec, to handle common arguments\n        remove_default_spec(aggregate_spec)\n        return aggregate_spec\n\n    def init_module(self):\n        \"\"\" module initialization\n        \"\"\"\n        element_spec = self._get_element_spec()\n        aggregate_spec = self._get_aggregate_spec(element_spec)\n        argument_spec = dict(\n            aggregate=dict(type='list', elements='dict',\n                           options=aggregate_spec),\n            purge=dict(default=False, type='bool'),\n        )\n        argument_spec.update(element_spec)\n        required_one_of = [['name', 'aggregate']]\n        mutually_exclusive = [['name', 'aggregate']]\n        self._module = AnsibleModule(\n            argument_spec=argument_spec,\n            required_one_of=required_one_of,\n            mutually_exclusive=mutually_exclusive,\n            supports_check_mode=True)\n\n    def get_required_config(self):\n        self._required_config = list()\n        module_params = self._module.params\n        aggregate = module_params.get('aggregate')\n        self._purge = module_params.get('purge', False)\n        if aggregate:\n            for item in aggregate:\n                for key in item:\n                    if item.get(key) is None:\n                        item[key] = module_params[key]\n                self.validate_param_values(item, item)\n                req_item = item.copy()\n                self._required_config.append(req_item)\n        else:\n            params = {\n                'name': module_params['name'],\n                'state': module_params['state'],\n            }\n            self.validate_param_values(params)\n            self._required_config.append(params)\n\n    def _create_if_pfc_data(self, if_name, if_pfc_data):\n        state = self.get_config_attr(if_pfc_data, \"PFC oper\")\n        state = state.lower()\n        return dict(\n            name=if_name,\n            state=state)\n\n    def _get_pfc_config(self):\n        return show_cmd(self._module, \"show dcb priority-flow-control\")\n\n    def load_current_config(self):\n        # called in base class in run function\n        self._current_config = dict()\n        pfc_config = self._get_pfc_config()\n        if not pfc_config:\n            return\n        if 'Table 2' in pfc_config:\n            pfc_config = pfc_config['Table 2']\n        for if_name, if_pfc_data in iteritems(pfc_config):\n            match = self.PFC_IF_REGEX.match(if_name)\n            if not match:\n                continue\n            if if_pfc_data:\n                if_pfc_data = if_pfc_data[0]\n                self._current_config[if_name] = \\\n                    self._create_if_pfc_data(if_name, if_pfc_data)\n\n    def _get_interface_cmd_name(self, if_name):\n        if if_name.startswith('Eth'):\n            return if_name.replace(\"Eth\", \"ethernet \")\n        if if_name.startswith('Po'):\n            return if_name.replace(\"Po\", \"port-channel \")\n        if if_name.startswith('Mpo'):\n            return if_name.replace(\"Mpo\", \"mlag-port-channel \")\n        self._module.fail_json(\n            msg='invalid interface name: %s' % if_name)\n\n    def _add_if_pfc_commands(self, if_name, req_state):\n        cmd_prefix = \"interface %s \" % self._get_interface_cmd_name(if_name)\n\n        if req_state == 'disabled':\n            pfc_cmd = 'no dcb priority-flow-control mode force'\n        else:\n            pfc_cmd = 'dcb priority-flow-control mode on force'\n        self._commands.append(cmd_prefix + pfc_cmd)\n\n    def _gen_pfc_commands(self, if_name, curr_conf, req_state):\n        curr_state = curr_conf.get('state', 'disabled')\n        if curr_state != req_state:\n            self._add_if_pfc_commands(if_name, req_state)\n\n    def generate_commands(self):\n        req_interfaces = set()\n        for req_conf in self._required_config:\n            req_state = req_conf['state']\n            if_name = req_conf['name']\n            if req_state == 'enabled':\n                req_interfaces.add(if_name)\n            curr_conf = self._current_config.get(if_name, {})\n            self._gen_pfc_commands(if_name, curr_conf, req_state)\n        if self._purge:\n            for if_name, curr_conf in iteritems(self._current_config):\n                if if_name not in req_interfaces:\n                    req_state = 'disabled'\n                    self._gen_pfc_commands(if_name, curr_conf, req_state)\n\n\ndef main():\n    \"\"\" main entry point for module execution\n    \"\"\"\n    OnyxPfcInterfaceModule.main()\n\n\nif __name__ == '__main__':\n    main()\n", "path": "lib/ansible/modules/network/onyx/onyx_pfc_interface.py"}], "after_files": [{"content": "#!/usr/bin/python\n#\n# Copyright: Ansible Project\n# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)\n\nfrom __future__ import absolute_import, division, print_function\n__metaclass__ = type\n\nANSIBLE_METADATA = {'metadata_version': '1.1',\n                    'status': ['preview'],\n                    'supported_by': 'community'}\n\nDOCUMENTATION = \"\"\"\n---\nmodule: onyx_pfc_interface\nversion_added: \"2.5\"\nauthor: \"Samer Deeb (@samerd)\"\nshort_description: Manage priority flow control on ONYX network devices\ndescription:\n  - This module provides declarative management of priority flow control (PFC)\n    on interfaces of Mellanox ONYX network devices.\nnotes:\n  - Tested on ONYX 3.6.4000\noptions:\n  name:\n    description:\n      - Name of the interface PFC should be configured on.\n  aggregate:\n    description: List of interfaces PFC should be configured on.\n  purge:\n    description:\n      - Purge interfaces not defined in the aggregate parameter.\n    type: bool\n    default: false\n  state:\n    description:\n      - State of the PFC configuration.\n    default: enabled\n    choices: ['enabled', 'disabled']\n\"\"\"\n\nEXAMPLES = \"\"\"\n- name: configure PFC\n  onyx_pfc_interface:\n    name: Eth1/1\n    state: enabled\n\"\"\"\n\nRETURN = \"\"\"\ncommands:\n  description: The list of configuration mode commands to send to the device.\n  returned: always\n  type: list\n  sample:\n    - interface ethernet 1/17 dcb priority-flow-control mode on\n\"\"\"\nfrom copy import deepcopy\nimport re\n\nfrom ansible.module_utils.basic import AnsibleModule\nfrom ansible.module_utils.network.common.utils import remove_default_spec\nfrom ansible.module_utils.six import iteritems\n\nfrom ansible.module_utils.network.onyx.onyx import BaseOnyxModule\nfrom ansible.module_utils.network.onyx.onyx import show_cmd\n\n\nclass OnyxPfcInterfaceModule(BaseOnyxModule):\n    PFC_IF_REGEX = re.compile(\n        r\"^(Eth\\d+\\/\\d+)|(Eth\\d+\\/\\d+\\/\\d+)|(Po\\d+)|(Mpo\\d+)$\")\n\n    _purge = False\n\n    @classmethod\n    def _get_element_spec(cls):\n        return dict(\n            name=dict(type='str'),\n            state=dict(default='enabled',\n                       choices=['enabled', 'disabled']),\n        )\n\n    @classmethod\n    def _get_aggregate_spec(cls, element_spec):\n        aggregate_spec = deepcopy(element_spec)\n        aggregate_spec['name'] = dict(required=True)\n\n        # remove default in aggregate spec, to handle common arguments\n        remove_default_spec(aggregate_spec)\n        return aggregate_spec\n\n    def init_module(self):\n        \"\"\" module initialization\n        \"\"\"\n        element_spec = self._get_element_spec()\n        aggregate_spec = self._get_aggregate_spec(element_spec)\n        argument_spec = dict(\n            aggregate=dict(type='list', elements='dict',\n                           options=aggregate_spec),\n            purge=dict(default=False, type='bool'),\n        )\n        argument_spec.update(element_spec)\n        required_one_of = [['name', 'aggregate']]\n        mutually_exclusive = [['name', 'aggregate']]\n        self._module = AnsibleModule(\n            argument_spec=argument_spec,\n            required_one_of=required_one_of,\n            mutually_exclusive=mutually_exclusive,\n            supports_check_mode=True)\n\n    def get_required_config(self):\n        self._required_config = list()\n        module_params = self._module.params\n        aggregate = module_params.get('aggregate')\n        self._purge = module_params.get('purge', False)\n        if aggregate:\n            for item in aggregate:\n                for key in item:\n                    if item.get(key) is None:\n                        item[key] = module_params[key]\n                self.validate_param_values(item, item)\n                req_item = item.copy()\n                self._required_config.append(req_item)\n        else:\n            params = {\n                'name': module_params['name'],\n                'state': module_params['state'],\n            }\n            self.validate_param_values(params)\n            self._required_config.append(params)\n\n    def _create_if_pfc_data(self, if_name, if_pfc_data):\n        state = self.get_config_attr(if_pfc_data, \"PFC oper\")\n        state = state.lower()\n        return dict(\n            name=if_name,\n            state=state)\n\n    def _get_pfc_config(self):\n        return show_cmd(self._module, \"show dcb priority-flow-control\")\n\n    def load_current_config(self):\n        # called in base class in run function\n        self._os_version = self._get_os_version()\n        self._current_config = dict()\n        pfc_config = self._get_pfc_config()\n        if not pfc_config:\n            return\n        if self._os_version >= self.ONYX_API_VERSION:\n            if len(pfc_config) >= 3:\n                pfc_config = pfc_config[2]\n            else:\n                pfc_config = dict()\n        else:\n            if 'Table 2' in pfc_config:\n                pfc_config = pfc_config['Table 2']\n\n        for if_name, if_pfc_data in iteritems(pfc_config):\n            match = self.PFC_IF_REGEX.match(if_name)\n            if not match:\n                continue\n            if if_pfc_data:\n                if_pfc_data = if_pfc_data[0]\n                self._current_config[if_name] = \\\n                    self._create_if_pfc_data(if_name, if_pfc_data)\n\n    def _get_interface_cmd_name(self, if_name):\n        if if_name.startswith('Eth'):\n            return if_name.replace(\"Eth\", \"ethernet \")\n        if if_name.startswith('Po'):\n            return if_name.replace(\"Po\", \"port-channel \")\n        if if_name.startswith('Mpo'):\n            return if_name.replace(\"Mpo\", \"mlag-port-channel \")\n        self._module.fail_json(\n            msg='invalid interface name: %s' % if_name)\n\n    def _add_if_pfc_commands(self, if_name, req_state):\n        cmd_prefix = \"interface %s \" % self._get_interface_cmd_name(if_name)\n\n        if req_state == 'disabled':\n            pfc_cmd = 'no dcb priority-flow-control mode force'\n        else:\n            pfc_cmd = 'dcb priority-flow-control mode on force'\n        self._commands.append(cmd_prefix + pfc_cmd)\n\n    def _gen_pfc_commands(self, if_name, curr_conf, req_state):\n        curr_state = curr_conf.get('state', 'disabled')\n        if curr_state != req_state:\n            self._add_if_pfc_commands(if_name, req_state)\n\n    def generate_commands(self):\n        req_interfaces = set()\n        for req_conf in self._required_config:\n            req_state = req_conf['state']\n            if_name = req_conf['name']\n            if req_state == 'enabled':\n                req_interfaces.add(if_name)\n            curr_conf = self._current_config.get(if_name, {})\n            self._gen_pfc_commands(if_name, curr_conf, req_state)\n        if self._purge:\n            for if_name, curr_conf in iteritems(self._current_config):\n                if if_name not in req_interfaces:\n                    req_state = 'disabled'\n                    self._gen_pfc_commands(if_name, curr_conf, req_state)\n\n\ndef main():\n    \"\"\" main entry point for module execution\n    \"\"\"\n    OnyxPfcInterfaceModule.main()\n\n\nif __name__ == '__main__':\n    main()\n", "path": "lib/ansible/modules/network/onyx/onyx_pfc_interface.py"}]}