We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
nxos_vpc_interface peer_link is not idempotent
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and master 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
-->
nxos_vpc_Interface
##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.5.0 (devel 788010d0f0) last updated 2018/01/08 11:49:21 (GMT -400)
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /root/agents-ci/ansible/lib/ansible
  executable location = /root/agents-ci/ansible/bin/ansible
  python version = 2.7.6 (default, Oct 26 2016, 20:30:19) [GCC 4.8.4]
```

##### 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.
-->
Ansible Server : Ubuntu 14.04
Device: N9K running 7.0(3)I5(2)

##### SUMMARY
<!--- Explain the problem briefly -->

If we set peer_link to False, it is not idempotent. Setting it to True is ok.

Note: I will open a PR shortly to address the above issue

--- 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/nxos/nxos_vpc_interface.py`
Content:
```
1 #!/usr/bin/python
2 #
3 # This file is part of Ansible
4 #
5 # Ansible is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Ansible is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
17 #
18 
19 ANSIBLE_METADATA = {'metadata_version': '1.1',
20                     'status': ['preview'],
21                     'supported_by': 'network'}
22 
23 DOCUMENTATION = '''
24 ---
25 module: nxos_vpc_interface
26 extends_documentation_fragment: nxos
27 version_added: "2.2"
28 short_description: Manages interface VPC configuration
29 description:
30   - Manages interface VPC configuration
31 author:
32   - Jason Edelman (@jedelman8)
33   - Gabriele Gerbino (@GGabriele)
34 notes:
35   - Tested against NXOSv 7.3.(0)D1(1) on VIRL
36   - Either vpc or peer_link param is required, but not both.
37   - C(state=absent) removes whatever VPC config is on a port-channel
38     if one exists.
39   - Re-assigning a vpc or peerlink from one portchannel to another is not
40     supported.  The module will force the user to unconfigure an existing
41     vpc/pl before configuring the same value on a new portchannel
42 options:
43   portchannel:
44     description:
45       - Group number of the portchannel that will be configured.
46     required: true
47   vpc:
48     description:
49       - VPC group/id that will be configured on associated portchannel.
50     required: false
51     default: null
52   peer_link:
53     description:
54       - Set to true/false for peer link config on associated portchannel.
55     required: false
56     default: null
57   state:
58     description:
59       - Manages desired state of the resource.
60     required: true
61     choices: ['present','absent']
62 '''
63 
64 EXAMPLES = '''
65 - nxos_vpc_interface:
66     portchannel: 10
67     vpc: 100
68 '''
69 
70 RETURN = '''
71 commands:
72     description: commands sent to the device
73     returned: always
74     type: list
75     sample: ["interface port-channel100", "vpc 10"]
76 '''
77 
78 from ansible.module_utils.network.nxos.nxos import get_config, load_config, run_commands
79 from ansible.module_utils.network.nxos.nxos import nxos_argument_spec, check_args
80 from ansible.module_utils.basic import AnsibleModule
81 
82 
83 def flatten_list(command_lists):
84     flat_command_list = []
85     for command in command_lists:
86         if isinstance(command, list):
87             flat_command_list.extend(command)
88         else:
89             flat_command_list.append(command)
90     return flat_command_list
91 
92 
93 def get_portchannel_list(module):
94     portchannels = []
95     pc_list = []
96 
97     try:
98         body = run_commands(module, ['show port-channel summary | json'])[0]
99         pc_list = body['TABLE_channel']['ROW_channel']
100     except (KeyError, AttributeError, TypeError):
101         return portchannels
102 
103     if pc_list:
104         if isinstance(pc_list, dict):
105             pc_list = [pc_list]
106 
107         for pc in pc_list:
108             portchannels.append(pc['group'])
109 
110     return portchannels
111 
112 
113 def get_existing_portchannel_to_vpc_mappings(module):
114     pc_vpc_mapping = {}
115 
116     try:
117         body = run_commands(module, ['show vpc brief | json'])[0]
118         vpc_table = body['TABLE_vpc']['ROW_vpc']
119     except (KeyError, AttributeError, TypeError):
120         vpc_table = None
121 
122     if vpc_table:
123         if isinstance(vpc_table, dict):
124             vpc_table = [vpc_table]
125 
126         for vpc in vpc_table:
127             pc_vpc_mapping[str(vpc['vpc-id'])] = str(vpc['vpc-ifindex'])
128 
129     return pc_vpc_mapping
130 
131 
132 def peer_link_exists(module):
133     found = False
134     run = get_config(module, flags=['vpc'])
135 
136     vpc_list = run.split('\n')
137     for each in vpc_list:
138         if 'peer-link' in each:
139             found = True
140     return found
141 
142 
143 def get_active_vpc_peer_link(module):
144     peer_link = None
145 
146     try:
147         body = run_commands(module, ['show vpc brief | json'])[0]
148         peer_link = body['TABLE_peerlink']['ROW_peerlink']['peerlink-ifindex']
149     except (KeyError, AttributeError, TypeError):
150         return peer_link
151 
152     return peer_link
153 
154 
155 def get_portchannel_vpc_config(module, portchannel):
156     peer_link_pc = None
157     peer_link = False
158     vpc = ""
159     pc = ""
160     config = {}
161 
162     try:
163         body = run_commands(module, ['show vpc brief | json'])[0]
164         table = body['TABLE_peerlink']['ROW_peerlink']
165     except (KeyError, AttributeError, TypeError):
166         table = {}
167 
168     if table:
169         peer_link_pc = table.get('peerlink-ifindex', None)
170 
171     if peer_link_pc:
172         plpc = str(peer_link_pc[2:])
173         if portchannel == plpc:
174             config['portchannel'] = portchannel
175             config['peer-link'] = True
176             config['vpc'] = vpc
177 
178     mapping = get_existing_portchannel_to_vpc_mappings(module)
179 
180     for existing_vpc, port_channel in mapping.items():
181         port_ch = str(port_channel[2:])
182         if port_ch == portchannel:
183             pc = port_ch
184             vpc = str(existing_vpc)
185 
186             config['portchannel'] = pc
187             config['peer-link'] = peer_link
188             config['vpc'] = vpc
189 
190     return config
191 
192 
193 def get_commands_to_config_vpc_interface(portchannel, delta, config_value, existing):
194     commands = []
195 
196     if delta.get('peer-link') is False and existing.get('peer-link') is True:
197         command = 'no vpc peer-link'
198         commands.append('no vpc peer-link')
199         commands.insert(0, 'interface port-channel{0}'.format(portchannel))
200 
201     elif delta.get('peer-link') or not existing.get('vpc'):
202         command = 'vpc {0}'.format(config_value)
203         commands.append(command)
204         commands.insert(0, 'interface port-channel{0}'.format(portchannel))
205 
206     return commands
207 
208 
209 def state_present(portchannel, delta, config_value, existing):
210     commands = []
211 
212     command = get_commands_to_config_vpc_interface(
213         portchannel,
214         delta,
215         config_value,
216         existing
217     )
218     commands.append(command)
219 
220     return commands
221 
222 
223 def state_absent(portchannel, existing):
224     commands = []
225     if existing.get('vpc'):
226         command = 'no vpc'
227         commands.append(command)
228     elif existing.get('peer-link'):
229         command = 'no vpc peer-link'
230         commands.append(command)
231     if commands:
232         commands.insert(0, 'interface port-channel{0}'.format(portchannel))
233 
234     return commands
235 
236 
237 def main():
238     argument_spec = dict(
239         portchannel=dict(required=True, type='str'),
240         vpc=dict(required=False, type='str'),
241         peer_link=dict(required=False, type='bool'),
242         state=dict(choices=['absent', 'present'], default='present')
243     )
244 
245     argument_spec.update(nxos_argument_spec)
246 
247     module = AnsibleModule(argument_spec=argument_spec,
248                            mutually_exclusive=[['vpc', 'peer_link']],
249                            supports_check_mode=True)
250 
251     warnings = list()
252     commands = []
253     check_args(module, warnings)
254     results = {'changed': False, 'warnings': warnings}
255 
256     portchannel = module.params['portchannel']
257     vpc = module.params['vpc']
258     peer_link = module.params['peer_link']
259     state = module.params['state']
260 
261     args = {'portchannel': portchannel, 'vpc': vpc, 'peer-link': peer_link}
262     active_peer_link = None
263 
264     if portchannel not in get_portchannel_list(module):
265         if not portchannel.isdigit() or int(portchannel) not in get_portchannel_list(module):
266             module.fail_json(msg="The portchannel you are trying to make a"
267                                  " VPC or PL is not created yet. "
268                                  "Create it first!")
269     if vpc:
270         mapping = get_existing_portchannel_to_vpc_mappings(module)
271 
272         if vpc in mapping and portchannel != mapping[vpc].strip('Po'):
273             module.fail_json(msg="This vpc is already configured on "
274                                  "another portchannel. Remove it first "
275                                  "before trying to assign it here. ",
276                              existing_portchannel=mapping[vpc])
277 
278         for vpcid, existing_pc in mapping.items():
279             if portchannel == existing_pc.strip('Po') and vpcid != vpc:
280                 module.fail_json(msg="This portchannel already has another"
281                                      " VPC configured. Remove it first "
282                                      "before assigning this one",
283                                  existing_vpc=vpcid)
284 
285         if peer_link_exists(module):
286             active_peer_link = get_active_vpc_peer_link(module)
287             if active_peer_link[-2:] == portchannel:
288                 module.fail_json(msg="That port channel is the current "
289                                      "PEER LINK. Remove it if you want it"
290                                      " to be a VPC")
291         config_value = vpc
292 
293     elif peer_link is not None:
294         if peer_link_exists(module):
295             active_peer_link = get_active_vpc_peer_link(module)[2::]
296             if active_peer_link != portchannel:
297                 if peer_link:
298                     module.fail_json(msg="A peer link already exists on"
299                                          " the device. Remove it first",
300                                      current_peer_link='Po{0}'.format(active_peer_link))
301         config_value = 'peer-link'
302 
303     proposed = dict((k, v) for k, v in args.items() if v is not None)
304     existing = get_portchannel_vpc_config(module, portchannel)
305 
306     if state == 'present':
307         delta = dict(set(proposed.items()).difference(existing.items()))
308         if delta:
309             commands = state_present(portchannel, delta, config_value, existing)
310 
311     elif state == 'absent' and existing:
312         commands = state_absent(portchannel, existing)
313 
314     cmds = flatten_list(commands)
315     if cmds:
316         if module.check_mode:
317             module.exit_json(changed=True, commands=cmds)
318         else:
319             load_config(module, cmds)
320             results['changed'] = True
321             if 'configure' in cmds:
322                 cmds.pop(0)
323 
324     results['commands'] = cmds
325     module.exit_json(**results)
326 
327 
328 if __name__ == '__main__':
329     main()
330
```
--- 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/nxos/nxos_vpc_interface.py b/lib/ansible/modules/network/nxos/nxos_vpc_interface.py
--- a/lib/ansible/modules/network/nxos/nxos_vpc_interface.py
+++ b/lib/ansible/modules/network/nxos/nxos_vpc_interface.py
@@ -193,12 +193,15 @@
 def get_commands_to_config_vpc_interface(portchannel, delta, config_value, existing):
     commands = []
 
-    if delta.get('peer-link') is False and existing.get('peer-link') is True:
-        command = 'no vpc peer-link'
+    if not delta.get('peer-link') and existing.get('peer-link'):
         commands.append('no vpc peer-link')
         commands.insert(0, 'interface port-channel{0}'.format(portchannel))
 
-    elif delta.get('peer-link') or not existing.get('vpc'):
+    elif delta.get('peer-link') and not existing.get('peer-link'):
+        commands.append('vpc peer-link')
+        commands.insert(0, 'interface port-channel{0}'.format(portchannel))
+
+    elif delta.get('vpc') and not existing.get('vpc'):
         command = 'vpc {0}'.format(config_value)
         commands.append(command)
         commands.insert(0, 'interface port-channel{0}'.format(portchannel))

{"golden_diff": "diff --git a/lib/ansible/modules/network/nxos/nxos_vpc_interface.py b/lib/ansible/modules/network/nxos/nxos_vpc_interface.py\n--- a/lib/ansible/modules/network/nxos/nxos_vpc_interface.py\n+++ b/lib/ansible/modules/network/nxos/nxos_vpc_interface.py\n@@ -193,12 +193,15 @@\n def get_commands_to_config_vpc_interface(portchannel, delta, config_value, existing):\n     commands = []\n \n-    if delta.get('peer-link') is False and existing.get('peer-link') is True:\n-        command = 'no vpc peer-link'\n+    if not delta.get('peer-link') and existing.get('peer-link'):\n         commands.append('no vpc peer-link')\n         commands.insert(0, 'interface port-channel{0}'.format(portchannel))\n \n-    elif delta.get('peer-link') or not existing.get('vpc'):\n+    elif delta.get('peer-link') and not existing.get('peer-link'):\n+        commands.append('vpc peer-link')\n+        commands.insert(0, 'interface port-channel{0}'.format(portchannel))\n+\n+    elif delta.get('vpc') and not existing.get('vpc'):\n         command = 'vpc {0}'.format(config_value)\n         commands.append(command)\n         commands.insert(0, 'interface port-channel{0}'.format(portchannel))\n", "issue": "nxos_vpc_interface peer_link is not idempotent\n<!---\r\nVerify first that your issue/request is not already reported on GitHub.\r\nAlso test if the latest release, and master 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\nnxos_vpc_Interface\r\n##### ANSIBLE VERSION\r\n<!--- Paste verbatim output from \"ansible --version\" between quotes below -->\r\n```\r\nansible 2.5.0 (devel 788010d0f0) last updated 2018/01/08 11:49:21 (GMT -400)\r\n  config file = /etc/ansible/ansible.cfg\r\n  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']\r\n  ansible python module location = /root/agents-ci/ansible/lib/ansible\r\n  executable location = /root/agents-ci/ansible/bin/ansible\r\n  python version = 2.7.6 (default, Oct 26 2016, 20:30:19) [GCC 4.8.4]\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\nAnsible Server : Ubuntu 14.04\r\nDevice: N9K running 7.0(3)I5(2)\r\n\r\n##### SUMMARY\r\n<!--- Explain the problem briefly -->\r\n\r\nIf we set peer_link to False, it is not idempotent. Setting it to True is ok.\r\n\r\nNote: I will open a PR shortly to address the above issue\n", "before_files": [{"content": "#!/usr/bin/python\n#\n# This file is part of Ansible\n#\n# Ansible is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# Ansible is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.\n#\n\nANSIBLE_METADATA = {'metadata_version': '1.1',\n                    'status': ['preview'],\n                    'supported_by': 'network'}\n\nDOCUMENTATION = '''\n---\nmodule: nxos_vpc_interface\nextends_documentation_fragment: nxos\nversion_added: \"2.2\"\nshort_description: Manages interface VPC configuration\ndescription:\n  - Manages interface VPC configuration\nauthor:\n  - Jason Edelman (@jedelman8)\n  - Gabriele Gerbino (@GGabriele)\nnotes:\n  - Tested against NXOSv 7.3.(0)D1(1) on VIRL\n  - Either vpc or peer_link param is required, but not both.\n  - C(state=absent) removes whatever VPC config is on a port-channel\n    if one exists.\n  - Re-assigning a vpc or peerlink from one portchannel to another is not\n    supported.  The module will force the user to unconfigure an existing\n    vpc/pl before configuring the same value on a new portchannel\noptions:\n  portchannel:\n    description:\n      - Group number of the portchannel that will be configured.\n    required: true\n  vpc:\n    description:\n      - VPC group/id that will be configured on associated portchannel.\n    required: false\n    default: null\n  peer_link:\n    description:\n      - Set to true/false for peer link config on associated portchannel.\n    required: false\n    default: null\n  state:\n    description:\n      - Manages desired state of the resource.\n    required: true\n    choices: ['present','absent']\n'''\n\nEXAMPLES = '''\n- nxos_vpc_interface:\n    portchannel: 10\n    vpc: 100\n'''\n\nRETURN = '''\ncommands:\n    description: commands sent to the device\n    returned: always\n    type: list\n    sample: [\"interface port-channel100\", \"vpc 10\"]\n'''\n\nfrom ansible.module_utils.network.nxos.nxos import get_config, load_config, run_commands\nfrom ansible.module_utils.network.nxos.nxos import nxos_argument_spec, check_args\nfrom ansible.module_utils.basic import AnsibleModule\n\n\ndef flatten_list(command_lists):\n    flat_command_list = []\n    for command in command_lists:\n        if isinstance(command, list):\n            flat_command_list.extend(command)\n        else:\n            flat_command_list.append(command)\n    return flat_command_list\n\n\ndef get_portchannel_list(module):\n    portchannels = []\n    pc_list = []\n\n    try:\n        body = run_commands(module, ['show port-channel summary | json'])[0]\n        pc_list = body['TABLE_channel']['ROW_channel']\n    except (KeyError, AttributeError, TypeError):\n        return portchannels\n\n    if pc_list:\n        if isinstance(pc_list, dict):\n            pc_list = [pc_list]\n\n        for pc in pc_list:\n            portchannels.append(pc['group'])\n\n    return portchannels\n\n\ndef get_existing_portchannel_to_vpc_mappings(module):\n    pc_vpc_mapping = {}\n\n    try:\n        body = run_commands(module, ['show vpc brief | json'])[0]\n        vpc_table = body['TABLE_vpc']['ROW_vpc']\n    except (KeyError, AttributeError, TypeError):\n        vpc_table = None\n\n    if vpc_table:\n        if isinstance(vpc_table, dict):\n            vpc_table = [vpc_table]\n\n        for vpc in vpc_table:\n            pc_vpc_mapping[str(vpc['vpc-id'])] = str(vpc['vpc-ifindex'])\n\n    return pc_vpc_mapping\n\n\ndef peer_link_exists(module):\n    found = False\n    run = get_config(module, flags=['vpc'])\n\n    vpc_list = run.split('\\n')\n    for each in vpc_list:\n        if 'peer-link' in each:\n            found = True\n    return found\n\n\ndef get_active_vpc_peer_link(module):\n    peer_link = None\n\n    try:\n        body = run_commands(module, ['show vpc brief | json'])[0]\n        peer_link = body['TABLE_peerlink']['ROW_peerlink']['peerlink-ifindex']\n    except (KeyError, AttributeError, TypeError):\n        return peer_link\n\n    return peer_link\n\n\ndef get_portchannel_vpc_config(module, portchannel):\n    peer_link_pc = None\n    peer_link = False\n    vpc = \"\"\n    pc = \"\"\n    config = {}\n\n    try:\n        body = run_commands(module, ['show vpc brief | json'])[0]\n        table = body['TABLE_peerlink']['ROW_peerlink']\n    except (KeyError, AttributeError, TypeError):\n        table = {}\n\n    if table:\n        peer_link_pc = table.get('peerlink-ifindex', None)\n\n    if peer_link_pc:\n        plpc = str(peer_link_pc[2:])\n        if portchannel == plpc:\n            config['portchannel'] = portchannel\n            config['peer-link'] = True\n            config['vpc'] = vpc\n\n    mapping = get_existing_portchannel_to_vpc_mappings(module)\n\n    for existing_vpc, port_channel in mapping.items():\n        port_ch = str(port_channel[2:])\n        if port_ch == portchannel:\n            pc = port_ch\n            vpc = str(existing_vpc)\n\n            config['portchannel'] = pc\n            config['peer-link'] = peer_link\n            config['vpc'] = vpc\n\n    return config\n\n\ndef get_commands_to_config_vpc_interface(portchannel, delta, config_value, existing):\n    commands = []\n\n    if delta.get('peer-link') is False and existing.get('peer-link') is True:\n        command = 'no vpc peer-link'\n        commands.append('no vpc peer-link')\n        commands.insert(0, 'interface port-channel{0}'.format(portchannel))\n\n    elif delta.get('peer-link') or not existing.get('vpc'):\n        command = 'vpc {0}'.format(config_value)\n        commands.append(command)\n        commands.insert(0, 'interface port-channel{0}'.format(portchannel))\n\n    return commands\n\n\ndef state_present(portchannel, delta, config_value, existing):\n    commands = []\n\n    command = get_commands_to_config_vpc_interface(\n        portchannel,\n        delta,\n        config_value,\n        existing\n    )\n    commands.append(command)\n\n    return commands\n\n\ndef state_absent(portchannel, existing):\n    commands = []\n    if existing.get('vpc'):\n        command = 'no vpc'\n        commands.append(command)\n    elif existing.get('peer-link'):\n        command = 'no vpc peer-link'\n        commands.append(command)\n    if commands:\n        commands.insert(0, 'interface port-channel{0}'.format(portchannel))\n\n    return commands\n\n\ndef main():\n    argument_spec = dict(\n        portchannel=dict(required=True, type='str'),\n        vpc=dict(required=False, type='str'),\n        peer_link=dict(required=False, type='bool'),\n        state=dict(choices=['absent', 'present'], default='present')\n    )\n\n    argument_spec.update(nxos_argument_spec)\n\n    module = AnsibleModule(argument_spec=argument_spec,\n                           mutually_exclusive=[['vpc', 'peer_link']],\n                           supports_check_mode=True)\n\n    warnings = list()\n    commands = []\n    check_args(module, warnings)\n    results = {'changed': False, 'warnings': warnings}\n\n    portchannel = module.params['portchannel']\n    vpc = module.params['vpc']\n    peer_link = module.params['peer_link']\n    state = module.params['state']\n\n    args = {'portchannel': portchannel, 'vpc': vpc, 'peer-link': peer_link}\n    active_peer_link = None\n\n    if portchannel not in get_portchannel_list(module):\n        if not portchannel.isdigit() or int(portchannel) not in get_portchannel_list(module):\n            module.fail_json(msg=\"The portchannel you are trying to make a\"\n                                 \" VPC or PL is not created yet. \"\n                                 \"Create it first!\")\n    if vpc:\n        mapping = get_existing_portchannel_to_vpc_mappings(module)\n\n        if vpc in mapping and portchannel != mapping[vpc].strip('Po'):\n            module.fail_json(msg=\"This vpc is already configured on \"\n                                 \"another portchannel. Remove it first \"\n                                 \"before trying to assign it here. \",\n                             existing_portchannel=mapping[vpc])\n\n        for vpcid, existing_pc in mapping.items():\n            if portchannel == existing_pc.strip('Po') and vpcid != vpc:\n                module.fail_json(msg=\"This portchannel already has another\"\n                                     \" VPC configured. Remove it first \"\n                                     \"before assigning this one\",\n                                 existing_vpc=vpcid)\n\n        if peer_link_exists(module):\n            active_peer_link = get_active_vpc_peer_link(module)\n            if active_peer_link[-2:] == portchannel:\n                module.fail_json(msg=\"That port channel is the current \"\n                                     \"PEER LINK. Remove it if you want it\"\n                                     \" to be a VPC\")\n        config_value = vpc\n\n    elif peer_link is not None:\n        if peer_link_exists(module):\n            active_peer_link = get_active_vpc_peer_link(module)[2::]\n            if active_peer_link != portchannel:\n                if peer_link:\n                    module.fail_json(msg=\"A peer link already exists on\"\n                                         \" the device. Remove it first\",\n                                     current_peer_link='Po{0}'.format(active_peer_link))\n        config_value = 'peer-link'\n\n    proposed = dict((k, v) for k, v in args.items() if v is not None)\n    existing = get_portchannel_vpc_config(module, portchannel)\n\n    if state == 'present':\n        delta = dict(set(proposed.items()).difference(existing.items()))\n        if delta:\n            commands = state_present(portchannel, delta, config_value, existing)\n\n    elif state == 'absent' and existing:\n        commands = state_absent(portchannel, existing)\n\n    cmds = flatten_list(commands)\n    if cmds:\n        if module.check_mode:\n            module.exit_json(changed=True, commands=cmds)\n        else:\n            load_config(module, cmds)\n            results['changed'] = True\n            if 'configure' in cmds:\n                cmds.pop(0)\n\n    results['commands'] = cmds\n    module.exit_json(**results)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "lib/ansible/modules/network/nxos/nxos_vpc_interface.py"}], "after_files": [{"content": "#!/usr/bin/python\n#\n# This file is part of Ansible\n#\n# Ansible is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# Ansible is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.\n#\n\nANSIBLE_METADATA = {'metadata_version': '1.1',\n                    'status': ['preview'],\n                    'supported_by': 'network'}\n\nDOCUMENTATION = '''\n---\nmodule: nxos_vpc_interface\nextends_documentation_fragment: nxos\nversion_added: \"2.2\"\nshort_description: Manages interface VPC configuration\ndescription:\n  - Manages interface VPC configuration\nauthor:\n  - Jason Edelman (@jedelman8)\n  - Gabriele Gerbino (@GGabriele)\nnotes:\n  - Tested against NXOSv 7.3.(0)D1(1) on VIRL\n  - Either vpc or peer_link param is required, but not both.\n  - C(state=absent) removes whatever VPC config is on a port-channel\n    if one exists.\n  - Re-assigning a vpc or peerlink from one portchannel to another is not\n    supported.  The module will force the user to unconfigure an existing\n    vpc/pl before configuring the same value on a new portchannel\noptions:\n  portchannel:\n    description:\n      - Group number of the portchannel that will be configured.\n    required: true\n  vpc:\n    description:\n      - VPC group/id that will be configured on associated portchannel.\n    required: false\n    default: null\n  peer_link:\n    description:\n      - Set to true/false for peer link config on associated portchannel.\n    required: false\n    default: null\n  state:\n    description:\n      - Manages desired state of the resource.\n    required: true\n    choices: ['present','absent']\n'''\n\nEXAMPLES = '''\n- nxos_vpc_interface:\n    portchannel: 10\n    vpc: 100\n'''\n\nRETURN = '''\ncommands:\n    description: commands sent to the device\n    returned: always\n    type: list\n    sample: [\"interface port-channel100\", \"vpc 10\"]\n'''\n\nfrom ansible.module_utils.network.nxos.nxos import get_config, load_config, run_commands\nfrom ansible.module_utils.network.nxos.nxos import nxos_argument_spec, check_args\nfrom ansible.module_utils.basic import AnsibleModule\n\n\ndef flatten_list(command_lists):\n    flat_command_list = []\n    for command in command_lists:\n        if isinstance(command, list):\n            flat_command_list.extend(command)\n        else:\n            flat_command_list.append(command)\n    return flat_command_list\n\n\ndef get_portchannel_list(module):\n    portchannels = []\n    pc_list = []\n\n    try:\n        body = run_commands(module, ['show port-channel summary | json'])[0]\n        pc_list = body['TABLE_channel']['ROW_channel']\n    except (KeyError, AttributeError, TypeError):\n        return portchannels\n\n    if pc_list:\n        if isinstance(pc_list, dict):\n            pc_list = [pc_list]\n\n        for pc in pc_list:\n            portchannels.append(pc['group'])\n\n    return portchannels\n\n\ndef get_existing_portchannel_to_vpc_mappings(module):\n    pc_vpc_mapping = {}\n\n    try:\n        body = run_commands(module, ['show vpc brief | json'])[0]\n        vpc_table = body['TABLE_vpc']['ROW_vpc']\n    except (KeyError, AttributeError, TypeError):\n        vpc_table = None\n\n    if vpc_table:\n        if isinstance(vpc_table, dict):\n            vpc_table = [vpc_table]\n\n        for vpc in vpc_table:\n            pc_vpc_mapping[str(vpc['vpc-id'])] = str(vpc['vpc-ifindex'])\n\n    return pc_vpc_mapping\n\n\ndef peer_link_exists(module):\n    found = False\n    run = get_config(module, flags=['vpc'])\n\n    vpc_list = run.split('\\n')\n    for each in vpc_list:\n        if 'peer-link' in each:\n            found = True\n    return found\n\n\ndef get_active_vpc_peer_link(module):\n    peer_link = None\n\n    try:\n        body = run_commands(module, ['show vpc brief | json'])[0]\n        peer_link = body['TABLE_peerlink']['ROW_peerlink']['peerlink-ifindex']\n    except (KeyError, AttributeError, TypeError):\n        return peer_link\n\n    return peer_link\n\n\ndef get_portchannel_vpc_config(module, portchannel):\n    peer_link_pc = None\n    peer_link = False\n    vpc = \"\"\n    pc = \"\"\n    config = {}\n\n    try:\n        body = run_commands(module, ['show vpc brief | json'])[0]\n        table = body['TABLE_peerlink']['ROW_peerlink']\n    except (KeyError, AttributeError, TypeError):\n        table = {}\n\n    if table:\n        peer_link_pc = table.get('peerlink-ifindex', None)\n\n    if peer_link_pc:\n        plpc = str(peer_link_pc[2:])\n        if portchannel == plpc:\n            config['portchannel'] = portchannel\n            config['peer-link'] = True\n            config['vpc'] = vpc\n\n    mapping = get_existing_portchannel_to_vpc_mappings(module)\n\n    for existing_vpc, port_channel in mapping.items():\n        port_ch = str(port_channel[2:])\n        if port_ch == portchannel:\n            pc = port_ch\n            vpc = str(existing_vpc)\n\n            config['portchannel'] = pc\n            config['peer-link'] = peer_link\n            config['vpc'] = vpc\n\n    return config\n\n\ndef get_commands_to_config_vpc_interface(portchannel, delta, config_value, existing):\n    commands = []\n\n    if not delta.get('peer-link') and existing.get('peer-link'):\n        commands.append('no vpc peer-link')\n        commands.insert(0, 'interface port-channel{0}'.format(portchannel))\n\n    elif delta.get('peer-link') and not existing.get('peer-link'):\n        commands.append('vpc peer-link')\n        commands.insert(0, 'interface port-channel{0}'.format(portchannel))\n\n    elif delta.get('vpc') and not existing.get('vpc'):\n        command = 'vpc {0}'.format(config_value)\n        commands.append(command)\n        commands.insert(0, 'interface port-channel{0}'.format(portchannel))\n\n    return commands\n\n\ndef state_present(portchannel, delta, config_value, existing):\n    commands = []\n\n    command = get_commands_to_config_vpc_interface(\n        portchannel,\n        delta,\n        config_value,\n        existing\n    )\n    commands.append(command)\n\n    return commands\n\n\ndef state_absent(portchannel, existing):\n    commands = []\n    if existing.get('vpc'):\n        command = 'no vpc'\n        commands.append(command)\n    elif existing.get('peer-link'):\n        command = 'no vpc peer-link'\n        commands.append(command)\n    if commands:\n        commands.insert(0, 'interface port-channel{0}'.format(portchannel))\n\n    return commands\n\n\ndef main():\n    argument_spec = dict(\n        portchannel=dict(required=True, type='str'),\n        vpc=dict(required=False, type='str'),\n        peer_link=dict(required=False, type='bool'),\n        state=dict(choices=['absent', 'present'], default='present')\n    )\n\n    argument_spec.update(nxos_argument_spec)\n\n    module = AnsibleModule(argument_spec=argument_spec,\n                           mutually_exclusive=[['vpc', 'peer_link']],\n                           supports_check_mode=True)\n\n    warnings = list()\n    commands = []\n    check_args(module, warnings)\n    results = {'changed': False, 'warnings': warnings}\n\n    portchannel = module.params['portchannel']\n    vpc = module.params['vpc']\n    peer_link = module.params['peer_link']\n    state = module.params['state']\n\n    args = {'portchannel': portchannel, 'vpc': vpc, 'peer-link': peer_link}\n    active_peer_link = None\n\n    if portchannel not in get_portchannel_list(module):\n        if not portchannel.isdigit() or int(portchannel) not in get_portchannel_list(module):\n            module.fail_json(msg=\"The portchannel you are trying to make a\"\n                                 \" VPC or PL is not created yet. \"\n                                 \"Create it first!\")\n    if vpc:\n        mapping = get_existing_portchannel_to_vpc_mappings(module)\n\n        if vpc in mapping and portchannel != mapping[vpc].strip('Po'):\n            module.fail_json(msg=\"This vpc is already configured on \"\n                                 \"another portchannel. Remove it first \"\n                                 \"before trying to assign it here. \",\n                             existing_portchannel=mapping[vpc])\n\n        for vpcid, existing_pc in mapping.items():\n            if portchannel == existing_pc.strip('Po') and vpcid != vpc:\n                module.fail_json(msg=\"This portchannel already has another\"\n                                     \" VPC configured. Remove it first \"\n                                     \"before assigning this one\",\n                                 existing_vpc=vpcid)\n\n        if peer_link_exists(module):\n            active_peer_link = get_active_vpc_peer_link(module)\n            if active_peer_link[-2:] == portchannel:\n                module.fail_json(msg=\"That port channel is the current \"\n                                     \"PEER LINK. Remove it if you want it\"\n                                     \" to be a VPC\")\n        config_value = vpc\n\n    elif peer_link is not None:\n        if peer_link_exists(module):\n            active_peer_link = get_active_vpc_peer_link(module)[2::]\n            if active_peer_link != portchannel:\n                if peer_link:\n                    module.fail_json(msg=\"A peer link already exists on\"\n                                         \" the device. Remove it first\",\n                                     current_peer_link='Po{0}'.format(active_peer_link))\n        config_value = 'peer-link'\n\n    proposed = dict((k, v) for k, v in args.items() if v is not None)\n    existing = get_portchannel_vpc_config(module, portchannel)\n\n    if state == 'present':\n        delta = dict(set(proposed.items()).difference(existing.items()))\n        if delta:\n            commands = state_present(portchannel, delta, config_value, existing)\n\n    elif state == 'absent' and existing:\n        commands = state_absent(portchannel, existing)\n\n    cmds = flatten_list(commands)\n    if cmds:\n        if module.check_mode:\n            module.exit_json(changed=True, commands=cmds)\n        else:\n            load_config(module, cmds)\n            results['changed'] = True\n            if 'configure' in cmds:\n                cmds.pop(0)\n\n    results['commands'] = cmds\n    module.exit_json(**results)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "lib/ansible/modules/network/nxos/nxos_vpc_interface.py"}]}