We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
vmware_dvs_portgroup destroy fails
<!--- Verify first that your issue/request is not already reported in GitHub -->
##### ISSUE TYPE

<!--- Pick one below and delete the rest: -->
- Bug Report
##### COMPONENT NAME

<!--- Name of the plugin/module/task -->

cloud/vmware/vmware_dvs_portgroup.py
##### ANSIBLE VERSION

<!--- Paste verbatim output from “ansible --version” between quotes below -->

```
ansible 2.1.1.0 (detached HEAD 780c363482) last updated 2016/08/19 17:46:34 (GMT -400)
  lib/ansible/modules/core: (detached HEAD 91a839f1e3) last updated 2016/08/19 17:46:11 (GMT -400)
  lib/ansible/modules/extras: (detached HEAD 1aeb9f8a8c) last updated 2016/08/19 17:46:13 (GMT -400)
  config file =
  configured module search path = Default w/o overrides

```
##### CONFIGURATION

<!---
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.
-->

N/A
##### SUMMARY

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

The function definition for state_destroy_dvspg(self) contains the line
            task = dvs_portgroup.Destroy_Task()

This should be 
            task = self.dvs_portgroup.Destroy_Task()
##### STEPS TO REPRODUCE

<!---
For bugs, show exactly how to reproduce the problem.
For new features, show how the feature would be used.
-->

Issue a playbook task to remove a vSphere portgroup by setting the state property to absent.

<!--- Paste example playbooks or commands between quotes below -->

```
  - name: Remove vSphere Portgroups
    vmware_dvs_portgroup:
      hostname: "{{ VSPHERE_HOST }}"
      username: "{{ VSPHERE_LOGIN }}"
      password: "{{ VSPHERE_PASSWORD }}"
      portgroup_name: "{{ TESTBED_NAME }}_{{ item }}"
      switch_name: "{{ VDS }}"
      vlan_id: "{{ item }}"
      num_ports: 10
      portgroup_type: earlyBinding
      state: absent
      validate_certs: False
    with_items: "{{ test_vlans }}"

```

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

<!--- What did you expect to happen when running the steps above? -->

Expected portgroup entry to be removed from vSphere networking.
##### ACTUAL RESULTS

<!--- What actually happened? If possible run with high verbosity (-vvvv) -->

Task fails with an error that 'dvs_portgroup' is not defined.

<!--- Paste verbatim command output between quotes below -->

```
TASK [teardown : Remove vSphere Portgroup] *************************************
task path: /var/jenkins/workspace/Build_CVP_Testbed/lab-automation/roles/teardown/tasks/main.yml:46
<10.81.110.96> ESTABLISH SSH CONNECTION FOR USER: root
<10.81.110.96> SSH: EXEC sshpass -d12 ssh -C -q -o ControlMaster=auto -o ControlPersist=60s -o User=root -o ConnectTimeout=10 -o ControlPath=/users/builder/.ansible/cp/ansible-ssh-%h-%p-%r 10.81.110.96 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1471642781.59-166008742553082 `" && echo ansible-tmp-1471642781.59-166008742553082="` echo $HOME/.ansible/tmp/ansible-tmp-1471642781.59-166008742553082 `" ) && sleep 0'"'"''
<10.81.110.96> PUT /tmp/tmpzAGbLy TO /root/.ansible/tmp/ansible-tmp-1471642781.59-166008742553082/vmware_dvs_portgroup
<10.81.110.96> SSH: EXEC sshpass -d12 sftp -o BatchMode=no -b - -C -o ControlMaster=auto -o ControlPersist=60s -o User=root -o ConnectTimeout=10 -o ControlPath=/users/builder/.ansible/cp/ansible-ssh-%h-%p-%r '[10.81.110.96]'
<10.81.110.96> ESTABLISH SSH CONNECTION FOR USER: root
<10.81.110.96> SSH: EXEC sshpass -d12 ssh -C -q -o ControlMaster=auto -o ControlPersist=60s -o User=root -o ConnectTimeout=10 -o ControlPath=/users/builder/.ansible/cp/ansible-ssh-%h-%p-%r -tt 10.81.110.96 '/bin/sh -c '"'"'LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1471642781.59-166008742553082/vmware_dvs_portgroup; rm -rf "/root/.ansible/tmp/ansible-tmp-1471642781.59-166008742553082/" > /dev/null 2>&1 && sleep 0'"'"''
failed: [10.81.110.96] (item=502) => {"failed": true, "invocation": {"module_args": {"hostname": "10.81.110.87", "num_ports": 10, "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", "portgroup_name": "garaaa_502", "portgroup_type": "earlyBinding", "state": "absent", "switch_name": "EOS+vDS", "username": "jenkins@vsphere.local", "validate_certs": false, "vlan_id": 502}, "module_name": "vmware_dvs_portgroup"}, "item": 502, "msg": "global name 'dvs_portgroup' is not defined"}
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cloud/vmware/vmware_dvs_portgroup.py`
Content:
```
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 
4 # (c) 2015, Joseph Callen <jcallen () csc.com>
5 #
6 # This file is part of Ansible
7 #
8 # Ansible is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # Ansible is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
20 
21 DOCUMENTATION = '''
22 ---
23 module: vmware_dvs_portgroup
24 short_description: Create or remove a Distributed vSwitch portgroup
25 description:
26     - Create or remove a Distributed vSwitch portgroup
27 version_added: 2.0
28 author: "Joseph Callen (@jcpowermac)"
29 notes:
30     - Tested on vSphere 5.5
31 requirements:
32     - "python >= 2.6"
33     - PyVmomi
34 options:
35     portgroup_name:
36         description:
37             - The name of the portgroup that is to be created or deleted
38         required: True
39     switch_name:
40         description:
41             - The name of the distributed vSwitch the port group should be created on.
42         required: True
43     vlan_id:
44         description:
45             - The VLAN ID that should be configured with the portgroup
46         required: True
47     num_ports:
48         description:
49             - The number of ports the portgroup should contain
50         required: True
51     portgroup_type:
52         description:
53             - See VMware KB 1022312 regarding portgroup types
54         required: True
55         choices:
56             - 'earlyBinding'
57             - 'lateBinding'
58             - 'ephemeral'
59 extends_documentation_fragment: vmware.documentation
60 '''
61 
62 EXAMPLES = '''
63    - name: Create Management portgroup
64       local_action:
65         module: vmware_dvs_portgroup
66         hostname: vcenter_ip_or_hostname
67         username: vcenter_username
68         password: vcenter_password
69         portgroup_name: Management
70         switch_name: dvSwitch
71         vlan_id: 123 
72         num_ports: 120
73         portgroup_type: earlyBinding
74         state: present
75 '''
76 
77 try:
78     from pyVmomi import vim, vmodl
79     HAS_PYVMOMI = True
80 except ImportError:
81     HAS_PYVMOMI = False
82 
83 
84 class VMwareDvsPortgroup(object):
85     def __init__(self, module):
86         self.module = module
87         self.dvs_portgroup = None
88         self.switch_name = self.module.params['switch_name']
89         self.portgroup_name = self.module.params['portgroup_name']
90         self.vlan_id = self.module.params['vlan_id']
91         self.num_ports = self.module.params['num_ports']
92         self.portgroup_type = self.module.params['portgroup_type']
93         self.dv_switch = None
94         self.state = self.module.params['state']
95         self.content = connect_to_api(module)
96         
97     def process_state(self):
98         try:
99             dvspg_states = {
100                 'absent': {
101                     'present': self.state_destroy_dvspg,
102                     'absent': self.state_exit_unchanged,
103                 },
104                 'present': {
105                     'update': self.state_update_dvspg,
106                     'present': self.state_exit_unchanged,
107                     'absent': self.state_create_dvspg,
108                 }
109             }
110             dvspg_states[self.state][self.check_dvspg_state()]()
111         except vmodl.RuntimeFault as runtime_fault:
112             self.module.fail_json(msg=runtime_fault.msg)
113         except vmodl.MethodFault as method_fault:
114             self.module.fail_json(msg=method_fault.msg)
115         except Exception as e:
116             self.module.fail_json(msg=str(e))
117 
118     def create_port_group(self):
119         config = vim.dvs.DistributedVirtualPortgroup.ConfigSpec()
120 
121         config.name = self.portgroup_name
122         config.numPorts = self.num_ports
123 
124         # vim.VMwareDVSPortSetting() does not exist in the pyvmomi documentation
125         # but this is the correct managed object type.
126 
127         config.defaultPortConfig = vim.VMwareDVSPortSetting()
128 
129         # vim.VmwareDistributedVirtualSwitchVlanIdSpec() does not exist in the
130         # pyvmomi documentation but this is the correct managed object type
131         config.defaultPortConfig.vlan = vim.VmwareDistributedVirtualSwitchVlanIdSpec()
132         config.defaultPortConfig.vlan.inherited = False
133         config.defaultPortConfig.vlan.vlanId = self.vlan_id
134         config.type = self.portgroup_type
135 
136         spec = [config]
137         task = self.dv_switch.AddDVPortgroup_Task(spec)
138         changed, result = wait_for_task(task)
139         return changed, result
140 
141     def state_destroy_dvspg(self):
142         changed = True
143         result = None
144 
145         if not self.module.check_mode:
146             task = dvs_portgroup.Destroy_Task()
147             changed, result = wait_for_task(task)
148         self.module.exit_json(changed=changed, result=str(result))
149 
150     def state_exit_unchanged(self):
151         self.module.exit_json(changed=False)
152 
153     def state_update_dvspg(self):
154         self.module.exit_json(changed=False, msg="Currently not implemented.")
155 
156     def state_create_dvspg(self):
157         changed = True
158         result = None
159 
160         if not self.module.check_mode:
161             changed, result = self.create_port_group()
162         self.module.exit_json(changed=changed, result=str(result))
163 
164     def check_dvspg_state(self):
165         self.dv_switch = find_dvs_by_name(self.content, self.switch_name)
166 
167         if self.dv_switch is None:
168             raise Exception("A distributed virtual switch with name %s does not exist" % self.switch_name)
169         self.dvs_portgroup = find_dvspg_by_name(self.dv_switch, self.portgroup_name)
170 
171         if self.dvs_portgroup is None:
172             return 'absent'
173         else:
174             return 'present'
175 
176 
177 def main():
178     argument_spec = vmware_argument_spec()
179     argument_spec.update(dict(portgroup_name=dict(required=True, type='str'),
180                          switch_name=dict(required=True, type='str'),
181                          vlan_id=dict(required=True, type='int'),
182                          num_ports=dict(required=True, type='int'),
183                          portgroup_type=dict(required=True, choices=['earlyBinding', 'lateBinding', 'ephemeral'], type='str'),
184                          state=dict(default='present', choices=['present', 'absent'], type='str')))
185 
186     module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
187 
188     if not HAS_PYVMOMI:
189         module.fail_json(msg='pyvmomi is required for this module')
190 
191     vmware_dvs_portgroup = VMwareDvsPortgroup(module)
192     vmware_dvs_portgroup.process_state()
193 
194 from ansible.module_utils.vmware import *
195 from ansible.module_utils.basic import *
196 
197 if __name__ == '__main__':
198     main()
199
```
--- 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/cloud/vmware/vmware_dvs_portgroup.py b/cloud/vmware/vmware_dvs_portgroup.py
--- a/cloud/vmware/vmware_dvs_portgroup.py
+++ b/cloud/vmware/vmware_dvs_portgroup.py
@@ -68,7 +68,7 @@
         password: vcenter_password
         portgroup_name: Management
         switch_name: dvSwitch
-        vlan_id: 123 
+        vlan_id: 123
         num_ports: 120
         portgroup_type: earlyBinding
         state: present
@@ -93,7 +93,7 @@
         self.dv_switch = None
         self.state = self.module.params['state']
         self.content = connect_to_api(module)
-        
+
     def process_state(self):
         try:
             dvspg_states = {
@@ -143,7 +143,7 @@
         result = None
 
         if not self.module.check_mode:
-            task = dvs_portgroup.Destroy_Task()
+            task = self.dvs_portgroup.Destroy_Task()
             changed, result = wait_for_task(task)
         self.module.exit_json(changed=changed, result=str(result))

{"golden_diff": "diff --git a/cloud/vmware/vmware_dvs_portgroup.py b/cloud/vmware/vmware_dvs_portgroup.py\n--- a/cloud/vmware/vmware_dvs_portgroup.py\n+++ b/cloud/vmware/vmware_dvs_portgroup.py\n@@ -68,7 +68,7 @@\n         password: vcenter_password\n         portgroup_name: Management\n         switch_name: dvSwitch\n-        vlan_id: 123 \n+        vlan_id: 123\n         num_ports: 120\n         portgroup_type: earlyBinding\n         state: present\n@@ -93,7 +93,7 @@\n         self.dv_switch = None\n         self.state = self.module.params['state']\n         self.content = connect_to_api(module)\n-        \n+\n     def process_state(self):\n         try:\n             dvspg_states = {\n@@ -143,7 +143,7 @@\n         result = None\n \n         if not self.module.check_mode:\n-            task = dvs_portgroup.Destroy_Task()\n+            task = self.dvs_portgroup.Destroy_Task()\n             changed, result = wait_for_task(task)\n         self.module.exit_json(changed=changed, result=str(result))\n", "issue": "vmware_dvs_portgroup destroy fails\n<!--- Verify first that your issue/request is not already reported in GitHub -->\n##### ISSUE TYPE\n\n<!--- Pick one below and delete the rest: -->\n- Bug Report\n##### COMPONENT NAME\n\n<!--- Name of the plugin/module/task -->\n\ncloud/vmware/vmware_dvs_portgroup.py\n##### ANSIBLE VERSION\n\n<!--- Paste verbatim output from \u201cansible --version\u201d between quotes below -->\n\n```\nansible 2.1.1.0 (detached HEAD 780c363482) last updated 2016/08/19 17:46:34 (GMT -400)\n  lib/ansible/modules/core: (detached HEAD 91a839f1e3) last updated 2016/08/19 17:46:11 (GMT -400)\n  lib/ansible/modules/extras: (detached HEAD 1aeb9f8a8c) last updated 2016/08/19 17:46:13 (GMT -400)\n  config file =\n  configured module search path = Default w/o overrides\n\n```\n##### CONFIGURATION\n\n<!---\nMention any settings you have changed/added/removed in ansible.cfg\n(or using the ANSIBLE_* environment variables).\n-->\n##### OS / ENVIRONMENT\n\n<!---\nMention the OS you are running Ansible from, and the OS you are\nmanaging, or say \u201cN/A\u201d for anything that is not platform-specific.\n-->\n\nN/A\n##### SUMMARY\n\n<!--- Explain the problem briefly -->\n\nThe function definition for state_destroy_dvspg(self) contains the line\n            task = dvs_portgroup.Destroy_Task()\n\nThis should be \n            task = self.dvs_portgroup.Destroy_Task()\n##### STEPS TO REPRODUCE\n\n<!---\nFor bugs, show exactly how to reproduce the problem.\nFor new features, show how the feature would be used.\n-->\n\nIssue a playbook task to remove a vSphere portgroup by setting the state property to absent.\n\n<!--- Paste example playbooks or commands between quotes below -->\n\n```\n  - name: Remove vSphere Portgroups\n    vmware_dvs_portgroup:\n      hostname: \"{{ VSPHERE_HOST }}\"\n      username: \"{{ VSPHERE_LOGIN }}\"\n      password: \"{{ VSPHERE_PASSWORD }}\"\n      portgroup_name: \"{{ TESTBED_NAME }}_{{ item }}\"\n      switch_name: \"{{ VDS }}\"\n      vlan_id: \"{{ item }}\"\n      num_ports: 10\n      portgroup_type: earlyBinding\n      state: absent\n      validate_certs: False\n    with_items: \"{{ test_vlans }}\"\n\n```\n\n<!--- You can also paste gist.github.com links for larger files -->\n##### EXPECTED RESULTS\n\n<!--- What did you expect to happen when running the steps above? -->\n\nExpected portgroup entry to be removed from vSphere networking.\n##### ACTUAL RESULTS\n\n<!--- What actually happened? If possible run with high verbosity (-vvvv) -->\n\nTask fails with an error that 'dvs_portgroup' is not defined.\n\n<!--- Paste verbatim command output between quotes below -->\n\n```\nTASK [teardown : Remove vSphere Portgroup] *************************************\ntask path: /var/jenkins/workspace/Build_CVP_Testbed/lab-automation/roles/teardown/tasks/main.yml:46\n<10.81.110.96> ESTABLISH SSH CONNECTION FOR USER: root\n<10.81.110.96> SSH: EXEC sshpass -d12 ssh -C -q -o ControlMaster=auto -o ControlPersist=60s -o User=root -o ConnectTimeout=10 -o ControlPath=/users/builder/.ansible/cp/ansible-ssh-%h-%p-%r 10.81.110.96 '/bin/sh -c '\"'\"'( umask 77 && mkdir -p \"` echo $HOME/.ansible/tmp/ansible-tmp-1471642781.59-166008742553082 `\" && echo ansible-tmp-1471642781.59-166008742553082=\"` echo $HOME/.ansible/tmp/ansible-tmp-1471642781.59-166008742553082 `\" ) && sleep 0'\"'\"''\n<10.81.110.96> PUT /tmp/tmpzAGbLy TO /root/.ansible/tmp/ansible-tmp-1471642781.59-166008742553082/vmware_dvs_portgroup\n<10.81.110.96> SSH: EXEC sshpass -d12 sftp -o BatchMode=no -b - -C -o ControlMaster=auto -o ControlPersist=60s -o User=root -o ConnectTimeout=10 -o ControlPath=/users/builder/.ansible/cp/ansible-ssh-%h-%p-%r '[10.81.110.96]'\n<10.81.110.96> ESTABLISH SSH CONNECTION FOR USER: root\n<10.81.110.96> SSH: EXEC sshpass -d12 ssh -C -q -o ControlMaster=auto -o ControlPersist=60s -o User=root -o ConnectTimeout=10 -o ControlPath=/users/builder/.ansible/cp/ansible-ssh-%h-%p-%r -tt 10.81.110.96 '/bin/sh -c '\"'\"'LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1471642781.59-166008742553082/vmware_dvs_portgroup; rm -rf \"/root/.ansible/tmp/ansible-tmp-1471642781.59-166008742553082/\" > /dev/null 2>&1 && sleep 0'\"'\"''\nfailed: [10.81.110.96] (item=502) => {\"failed\": true, \"invocation\": {\"module_args\": {\"hostname\": \"10.81.110.87\", \"num_ports\": 10, \"password\": \"VALUE_SPECIFIED_IN_NO_LOG_PARAMETER\", \"portgroup_name\": \"garaaa_502\", \"portgroup_type\": \"earlyBinding\", \"state\": \"absent\", \"switch_name\": \"EOS+vDS\", \"username\": \"jenkins@vsphere.local\", \"validate_certs\": false, \"vlan_id\": 502}, \"module_name\": \"vmware_dvs_portgroup\"}, \"item\": 502, \"msg\": \"global name 'dvs_portgroup' is not defined\"}\n```\n\n", "before_files": [{"content": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# (c) 2015, Joseph Callen <jcallen () csc.com>\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\nDOCUMENTATION = '''\n---\nmodule: vmware_dvs_portgroup\nshort_description: Create or remove a Distributed vSwitch portgroup\ndescription:\n    - Create or remove a Distributed vSwitch portgroup\nversion_added: 2.0\nauthor: \"Joseph Callen (@jcpowermac)\"\nnotes:\n    - Tested on vSphere 5.5\nrequirements:\n    - \"python >= 2.6\"\n    - PyVmomi\noptions:\n    portgroup_name:\n        description:\n            - The name of the portgroup that is to be created or deleted\n        required: True\n    switch_name:\n        description:\n            - The name of the distributed vSwitch the port group should be created on.\n        required: True\n    vlan_id:\n        description:\n            - The VLAN ID that should be configured with the portgroup\n        required: True\n    num_ports:\n        description:\n            - The number of ports the portgroup should contain\n        required: True\n    portgroup_type:\n        description:\n            - See VMware KB 1022312 regarding portgroup types\n        required: True\n        choices:\n            - 'earlyBinding'\n            - 'lateBinding'\n            - 'ephemeral'\nextends_documentation_fragment: vmware.documentation\n'''\n\nEXAMPLES = '''\n   - name: Create Management portgroup\n      local_action:\n        module: vmware_dvs_portgroup\n        hostname: vcenter_ip_or_hostname\n        username: vcenter_username\n        password: vcenter_password\n        portgroup_name: Management\n        switch_name: dvSwitch\n        vlan_id: 123 \n        num_ports: 120\n        portgroup_type: earlyBinding\n        state: present\n'''\n\ntry:\n    from pyVmomi import vim, vmodl\n    HAS_PYVMOMI = True\nexcept ImportError:\n    HAS_PYVMOMI = False\n\n\nclass VMwareDvsPortgroup(object):\n    def __init__(self, module):\n        self.module = module\n        self.dvs_portgroup = None\n        self.switch_name = self.module.params['switch_name']\n        self.portgroup_name = self.module.params['portgroup_name']\n        self.vlan_id = self.module.params['vlan_id']\n        self.num_ports = self.module.params['num_ports']\n        self.portgroup_type = self.module.params['portgroup_type']\n        self.dv_switch = None\n        self.state = self.module.params['state']\n        self.content = connect_to_api(module)\n        \n    def process_state(self):\n        try:\n            dvspg_states = {\n                'absent': {\n                    'present': self.state_destroy_dvspg,\n                    'absent': self.state_exit_unchanged,\n                },\n                'present': {\n                    'update': self.state_update_dvspg,\n                    'present': self.state_exit_unchanged,\n                    'absent': self.state_create_dvspg,\n                }\n            }\n            dvspg_states[self.state][self.check_dvspg_state()]()\n        except vmodl.RuntimeFault as runtime_fault:\n            self.module.fail_json(msg=runtime_fault.msg)\n        except vmodl.MethodFault as method_fault:\n            self.module.fail_json(msg=method_fault.msg)\n        except Exception as e:\n            self.module.fail_json(msg=str(e))\n\n    def create_port_group(self):\n        config = vim.dvs.DistributedVirtualPortgroup.ConfigSpec()\n\n        config.name = self.portgroup_name\n        config.numPorts = self.num_ports\n\n        # vim.VMwareDVSPortSetting() does not exist in the pyvmomi documentation\n        # but this is the correct managed object type.\n\n        config.defaultPortConfig = vim.VMwareDVSPortSetting()\n\n        # vim.VmwareDistributedVirtualSwitchVlanIdSpec() does not exist in the\n        # pyvmomi documentation but this is the correct managed object type\n        config.defaultPortConfig.vlan = vim.VmwareDistributedVirtualSwitchVlanIdSpec()\n        config.defaultPortConfig.vlan.inherited = False\n        config.defaultPortConfig.vlan.vlanId = self.vlan_id\n        config.type = self.portgroup_type\n\n        spec = [config]\n        task = self.dv_switch.AddDVPortgroup_Task(spec)\n        changed, result = wait_for_task(task)\n        return changed, result\n\n    def state_destroy_dvspg(self):\n        changed = True\n        result = None\n\n        if not self.module.check_mode:\n            task = dvs_portgroup.Destroy_Task()\n            changed, result = wait_for_task(task)\n        self.module.exit_json(changed=changed, result=str(result))\n\n    def state_exit_unchanged(self):\n        self.module.exit_json(changed=False)\n\n    def state_update_dvspg(self):\n        self.module.exit_json(changed=False, msg=\"Currently not implemented.\")\n\n    def state_create_dvspg(self):\n        changed = True\n        result = None\n\n        if not self.module.check_mode:\n            changed, result = self.create_port_group()\n        self.module.exit_json(changed=changed, result=str(result))\n\n    def check_dvspg_state(self):\n        self.dv_switch = find_dvs_by_name(self.content, self.switch_name)\n\n        if self.dv_switch is None:\n            raise Exception(\"A distributed virtual switch with name %s does not exist\" % self.switch_name)\n        self.dvs_portgroup = find_dvspg_by_name(self.dv_switch, self.portgroup_name)\n\n        if self.dvs_portgroup is None:\n            return 'absent'\n        else:\n            return 'present'\n\n\ndef main():\n    argument_spec = vmware_argument_spec()\n    argument_spec.update(dict(portgroup_name=dict(required=True, type='str'),\n                         switch_name=dict(required=True, type='str'),\n                         vlan_id=dict(required=True, type='int'),\n                         num_ports=dict(required=True, type='int'),\n                         portgroup_type=dict(required=True, choices=['earlyBinding', 'lateBinding', 'ephemeral'], type='str'),\n                         state=dict(default='present', choices=['present', 'absent'], type='str')))\n\n    module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)\n\n    if not HAS_PYVMOMI:\n        module.fail_json(msg='pyvmomi is required for this module')\n\n    vmware_dvs_portgroup = VMwareDvsPortgroup(module)\n    vmware_dvs_portgroup.process_state()\n\nfrom ansible.module_utils.vmware import *\nfrom ansible.module_utils.basic import *\n\nif __name__ == '__main__':\n    main()\n", "path": "cloud/vmware/vmware_dvs_portgroup.py"}], "after_files": [{"content": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# (c) 2015, Joseph Callen <jcallen () csc.com>\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\nDOCUMENTATION = '''\n---\nmodule: vmware_dvs_portgroup\nshort_description: Create or remove a Distributed vSwitch portgroup\ndescription:\n    - Create or remove a Distributed vSwitch portgroup\nversion_added: 2.0\nauthor: \"Joseph Callen (@jcpowermac)\"\nnotes:\n    - Tested on vSphere 5.5\nrequirements:\n    - \"python >= 2.6\"\n    - PyVmomi\noptions:\n    portgroup_name:\n        description:\n            - The name of the portgroup that is to be created or deleted\n        required: True\n    switch_name:\n        description:\n            - The name of the distributed vSwitch the port group should be created on.\n        required: True\n    vlan_id:\n        description:\n            - The VLAN ID that should be configured with the portgroup\n        required: True\n    num_ports:\n        description:\n            - The number of ports the portgroup should contain\n        required: True\n    portgroup_type:\n        description:\n            - See VMware KB 1022312 regarding portgroup types\n        required: True\n        choices:\n            - 'earlyBinding'\n            - 'lateBinding'\n            - 'ephemeral'\nextends_documentation_fragment: vmware.documentation\n'''\n\nEXAMPLES = '''\n   - name: Create Management portgroup\n      local_action:\n        module: vmware_dvs_portgroup\n        hostname: vcenter_ip_or_hostname\n        username: vcenter_username\n        password: vcenter_password\n        portgroup_name: Management\n        switch_name: dvSwitch\n        vlan_id: 123\n        num_ports: 120\n        portgroup_type: earlyBinding\n        state: present\n'''\n\ntry:\n    from pyVmomi import vim, vmodl\n    HAS_PYVMOMI = True\nexcept ImportError:\n    HAS_PYVMOMI = False\n\n\nclass VMwareDvsPortgroup(object):\n    def __init__(self, module):\n        self.module = module\n        self.dvs_portgroup = None\n        self.switch_name = self.module.params['switch_name']\n        self.portgroup_name = self.module.params['portgroup_name']\n        self.vlan_id = self.module.params['vlan_id']\n        self.num_ports = self.module.params['num_ports']\n        self.portgroup_type = self.module.params['portgroup_type']\n        self.dv_switch = None\n        self.state = self.module.params['state']\n        self.content = connect_to_api(module)\n\n    def process_state(self):\n        try:\n            dvspg_states = {\n                'absent': {\n                    'present': self.state_destroy_dvspg,\n                    'absent': self.state_exit_unchanged,\n                },\n                'present': {\n                    'update': self.state_update_dvspg,\n                    'present': self.state_exit_unchanged,\n                    'absent': self.state_create_dvspg,\n                }\n            }\n            dvspg_states[self.state][self.check_dvspg_state()]()\n        except vmodl.RuntimeFault as runtime_fault:\n            self.module.fail_json(msg=runtime_fault.msg)\n        except vmodl.MethodFault as method_fault:\n            self.module.fail_json(msg=method_fault.msg)\n        except Exception as e:\n            self.module.fail_json(msg=str(e))\n\n    def create_port_group(self):\n        config = vim.dvs.DistributedVirtualPortgroup.ConfigSpec()\n\n        config.name = self.portgroup_name\n        config.numPorts = self.num_ports\n\n        # vim.VMwareDVSPortSetting() does not exist in the pyvmomi documentation\n        # but this is the correct managed object type.\n\n        config.defaultPortConfig = vim.VMwareDVSPortSetting()\n\n        # vim.VmwareDistributedVirtualSwitchVlanIdSpec() does not exist in the\n        # pyvmomi documentation but this is the correct managed object type\n        config.defaultPortConfig.vlan = vim.VmwareDistributedVirtualSwitchVlanIdSpec()\n        config.defaultPortConfig.vlan.inherited = False\n        config.defaultPortConfig.vlan.vlanId = self.vlan_id\n        config.type = self.portgroup_type\n\n        spec = [config]\n        task = self.dv_switch.AddDVPortgroup_Task(spec)\n        changed, result = wait_for_task(task)\n        return changed, result\n\n    def state_destroy_dvspg(self):\n        changed = True\n        result = None\n\n        if not self.module.check_mode:\n            task = self.dvs_portgroup.Destroy_Task()\n            changed, result = wait_for_task(task)\n        self.module.exit_json(changed=changed, result=str(result))\n\n    def state_exit_unchanged(self):\n        self.module.exit_json(changed=False)\n\n    def state_update_dvspg(self):\n        self.module.exit_json(changed=False, msg=\"Currently not implemented.\")\n\n    def state_create_dvspg(self):\n        changed = True\n        result = None\n\n        if not self.module.check_mode:\n            changed, result = self.create_port_group()\n        self.module.exit_json(changed=changed, result=str(result))\n\n    def check_dvspg_state(self):\n        self.dv_switch = find_dvs_by_name(self.content, self.switch_name)\n\n        if self.dv_switch is None:\n            raise Exception(\"A distributed virtual switch with name %s does not exist\" % self.switch_name)\n        self.dvs_portgroup = find_dvspg_by_name(self.dv_switch, self.portgroup_name)\n\n        if self.dvs_portgroup is None:\n            return 'absent'\n        else:\n            return 'present'\n\n\ndef main():\n    argument_spec = vmware_argument_spec()\n    argument_spec.update(dict(portgroup_name=dict(required=True, type='str'),\n                         switch_name=dict(required=True, type='str'),\n                         vlan_id=dict(required=True, type='int'),\n                         num_ports=dict(required=True, type='int'),\n                         portgroup_type=dict(required=True, choices=['earlyBinding', 'lateBinding', 'ephemeral'], type='str'),\n                         state=dict(default='present', choices=['present', 'absent'], type='str')))\n\n    module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)\n\n    if not HAS_PYVMOMI:\n        module.fail_json(msg='pyvmomi is required for this module')\n\n    vmware_dvs_portgroup = VMwareDvsPortgroup(module)\n    vmware_dvs_portgroup.process_state()\n\nfrom ansible.module_utils.vmware import *\nfrom ansible.module_utils.basic import *\n\nif __name__ == '__main__':\n    main()\n", "path": "cloud/vmware/vmware_dvs_portgroup.py"}]}