From 45fc0385ae38c91351b33e73591dd3cb1e4338fd Mon Sep 17 00:00:00 2001
From: Marius Rieder <marius.rieder@scs.ch>
Date: Fri, 6 May 2022 08:39:50 +0200
Subject: [PATCH 1/3] vmware_vswitch_info: Add support to return information
 about network policies

---
 ...switch_info-add_network_policy_support.yml |  3 +
 plugins/modules/vmware_vswitch_info.py        | 81 ++++++++++++++++---
 .../vmware_vswitch_info/tasks/main.yml        | 19 +++++
 3 files changed, 92 insertions(+), 11 deletions(-)
 create mode 100644 changelogs/fragments/1310-vmware_vswitch_info-add_network_policy_support.yml

diff --git a/changelogs/fragments/1310-vmware_vswitch_info-add_network_policy_support.yml b/changelogs/fragments/1310-vmware_vswitch_info-add_network_policy_support.yml
new file mode 100644
index 000000000..6cb540b47
--- /dev/null
+++ b/changelogs/fragments/1310-vmware_vswitch_info-add_network_policy_support.yml
@@ -0,0 +1,3 @@
+minor_changes:
+  - vmware_vswitch_info - Add support to return security, teaming and traffic shaping policies on vSwitches.
+    (https://github.com/ansible-collections/community.vmware/pull/1310).
\ No newline at end of file
diff --git a/plugins/modules/vmware_vswitch_info.py b/plugins/modules/vmware_vswitch_info.py
index dde6621bb..11fee7f93 100644
--- a/plugins/modules/vmware_vswitch_info.py
+++ b/plugins/modules/vmware_vswitch_info.py
@@ -24,6 +24,13 @@
 - python >= 2.6
 - PyVmomi
 options:
+  policies:
+    description:
+    - Gather information about Security, Traffic Shaping, as well as Teaming and failover.
+    - The property C(ts) stands for Traffic Shaping and C(lb) for Load Balancing.
+    version_added: '2.4.0'
+    type: bool
+    default: false
   cluster_name:
     description:
     - Name of the cluster.
@@ -72,7 +79,15 @@
                 "num_ports": 128,
                 "pnics": [
                     "vmnic0"
-                ]
+                ],
+                "failback": true,
+                "failover_active": ["vmnic0"],
+                "failover_standby": [],
+                "failure_detection": "link_status_only",
+                "lb": "loadbalance_srcid",
+                "notify": true,
+                "security": [false, false, false],
+                "ts": false
             },
             "vSwitch_0011": {
                 "mtu": 1500,
@@ -80,7 +95,15 @@
                 "pnics": [
                     "vmnic2",
                     "vmnic1"
-                    ]
+                    ],
+                "failback": true,
+                "failover_active": ["vmnic1"],
+                "failover_standby": ["vmnic2],
+                "failure_detection": "link_status_only",
+                "lb": "loadbalance_srcid",
+                "notify": true,
+                "security": [false, false, false],
+                "ts": false,
             },
         },
     }
@@ -100,6 +123,7 @@ def __init__(self, module):
         self.hosts = self.get_all_host_objs(cluster_name=cluster_name, esxi_host_name=esxi_host_name)
         if not self.hosts:
             self.module.fail_json(msg="Failed to find host system.")
+        self.policies = self.params.get('policies')
 
     @staticmethod
     def serialize_pnics(vswitch_obj):
@@ -110,6 +134,47 @@ def serialize_pnics(vswitch_obj):
             pnics.append(pnic.split("-", 3)[-1])
         return pnics
 
+    @staticmethod
+    def normalize_vswitch_info(vswitch_obj, policy_info):
+        """Create vSwitch information"""
+        vswitch_info_dict = dict()
+        spec = vswitch_obj.spec
+        vswitch_info_dict['pnics'] = VswitchInfoManager.serialize_pnics(vswitch_obj)
+        vswitch_info_dict['mtu'] = vswitch_obj.mtu
+        vswitch_info_dict['num_ports'] = spec.numPorts
+
+        if policy_info:
+            # Security info
+            if spec.policy.security:
+                promiscuous_mode = spec.policy.security.allowPromiscuous
+                mac_changes = spec.policy.security.macChanges
+                forged_transmits = spec.policy.security.forgedTransmits
+                vswitch_info_dict['security'] = (
+                    [
+                        spec.policy.security.allowPromiscuous,
+                        spec.policy.security.macChanges,
+                        spec.policy.security.forgedTransmits
+                    ]
+                )
+
+            # Traffic Shaping info
+            if spec.policy.shapingPolicy:
+                vswitch_info_dict['ts'] = spec.policy.shapingPolicy.enabled
+
+            # Teaming and failover info
+            if spec.policy.nicTeaming:
+                vswitch_info_dict['lb'] = spec.policy.nicTeaming.policy
+                vswitch_info_dict['notify'] = spec.policy.nicTeaming.notifySwitches
+                vswitch_info_dict['failback'] = not spec.policy.nicTeaming.rollingOrder
+                vswitch_info_dict['failover_active'] = spec.policy.nicTeaming.nicOrder.activeNic
+                vswitch_info_dict['failover_standby'] = spec.policy.nicTeaming.nicOrder.standbyNic
+                if spec.policy.nicTeaming.failureCriteria.checkBeacon:
+                    vswitch_info_dict['failure_detection'] = "beacon_probing"
+                else:
+                    vswitch_info_dict['failure_detection'] = "link_status_only"
+
+        return vswitch_info_dict
+
     def gather_vswitch_info(self):
         """Gather vSwitch info"""
         hosts_vswitch_info = dict()
@@ -117,15 +182,8 @@ def gather_vswitch_info(self):
             network_manager = host.configManager.networkSystem
             if network_manager:
                 temp_switch_dict = dict()
-                for available_vswitch in network_manager.networkInfo.vswitch:
-                    temp_switch_dict[available_vswitch.name] = dict(
-                        pnics=self.serialize_pnics(available_vswitch),
-                        mtu=available_vswitch.mtu,
-                        # we need to use the spec to get the ports
-                        # otherwise, the output might be different compared to the vswitch config module
-                        # (e.g. 5632 ports instead of 128)
-                        num_ports=available_vswitch.spec.numPorts
-                    )
+                for vswitch in network_manager.networkInfo.vswitch:
+                    temp_switch_dict[vswitch.name] = self.normalize_vswitch_info(vswitch_obj=vswitch, policy_info=self.policies)
                 hosts_vswitch_info[host.name] = temp_switch_dict
         return hosts_vswitch_info
 
@@ -136,6 +194,7 @@ def main():
     argument_spec.update(
         cluster_name=dict(type='str', required=False),
         esxi_hostname=dict(type='str', required=False),
+        policies=dict(type='bool', required=False, default=False),
     )
 
     module = AnsibleModule(
diff --git a/tests/integration/targets/vmware_vswitch_info/tasks/main.yml b/tests/integration/targets/vmware_vswitch_info/tasks/main.yml
index 47f73bea9..7b5e90b21 100644
--- a/tests/integration/targets/vmware_vswitch_info/tasks/main.yml
+++ b/tests/integration/targets/vmware_vswitch_info/tasks/main.yml
@@ -37,3 +37,22 @@
 - assert:
     that:
       - switch_info_check_mode.hosts_vswitch_info is defined
+
+- name: Gather vswitch policies info about all hosts in given cluster
+  vmware_vswitch_info:
+    hostname: "{{ vcenter_hostname }}"
+    username: "{{ vcenter_username }}"
+    password: "{{ vcenter_password }}"
+    esxi_hostname: '{{ esxi1 }}'
+    validate_certs: false
+    policies: true
+  register: switch_policies_info
+
+- debug: var=switch_policies_info
+
+- assert:
+    that:
+      - switch_policies_info.hosts_vswitch_info is defined
+      - switch_policies_info.hosts_vswitch_info[esxi1].security is defined
+      - switch_policies_info.hosts_vswitch_info[esxi1].ts is defined
+      - switch_policies_info.hosts_vswitch_info[esxi1].lb is defined

From 4ab77a0a488c739e8cf219d58740871e8ce81b96 Mon Sep 17 00:00:00 2001
From: Marius Rieder <marius.rieder@scs.ch>
Date: Fri, 6 May 2022 10:14:57 +0200
Subject: [PATCH 2/3] vmware_vswitch_info: Remove unused variables

---
 ...309-vmware_vswitch_info-add_network_policy_support.yml} | 2 +-
 plugins/modules/vmware_vswitch_info.py                     | 7 ++-----
 2 files changed, 3 insertions(+), 6 deletions(-)
 rename changelogs/fragments/{1310-vmware_vswitch_info-add_network_policy_support.yml => 1309-vmware_vswitch_info-add_network_policy_support.yml} (95%)

diff --git a/changelogs/fragments/1310-vmware_vswitch_info-add_network_policy_support.yml b/changelogs/fragments/1309-vmware_vswitch_info-add_network_policy_support.yml
similarity index 95%
rename from changelogs/fragments/1310-vmware_vswitch_info-add_network_policy_support.yml
rename to changelogs/fragments/1309-vmware_vswitch_info-add_network_policy_support.yml
index 6cb540b47..81134f30a 100644
--- a/changelogs/fragments/1310-vmware_vswitch_info-add_network_policy_support.yml
+++ b/changelogs/fragments/1309-vmware_vswitch_info-add_network_policy_support.yml
@@ -1,3 +1,3 @@
 minor_changes:
   - vmware_vswitch_info - Add support to return security, teaming and traffic shaping policies on vSwitches.
-    (https://github.com/ansible-collections/community.vmware/pull/1310).
\ No newline at end of file
+    (https://github.com/ansible-collections/community.vmware/pull/1309).
\ No newline at end of file
diff --git a/plugins/modules/vmware_vswitch_info.py b/plugins/modules/vmware_vswitch_info.py
index 11fee7f93..6f29b2dc4 100644
--- a/plugins/modules/vmware_vswitch_info.py
+++ b/plugins/modules/vmware_vswitch_info.py
@@ -25,10 +25,10 @@
 - PyVmomi
 options:
   policies:
+    version_added: '2.4.0'
     description:
     - Gather information about Security, Traffic Shaping, as well as Teaming and failover.
     - The property C(ts) stands for Traffic Shaping and C(lb) for Load Balancing.
-    version_added: '2.4.0'
     type: bool
     default: false
   cluster_name:
@@ -98,7 +98,7 @@
                     ],
                 "failback": true,
                 "failover_active": ["vmnic1"],
-                "failover_standby": ["vmnic2],
+                "failover_standby": ["vmnic2"],
                 "failure_detection": "link_status_only",
                 "lb": "loadbalance_srcid",
                 "notify": true,
@@ -146,9 +146,6 @@ def normalize_vswitch_info(vswitch_obj, policy_info):
         if policy_info:
             # Security info
             if spec.policy.security:
-                promiscuous_mode = spec.policy.security.allowPromiscuous
-                mac_changes = spec.policy.security.macChanges
-                forged_transmits = spec.policy.security.forgedTransmits
                 vswitch_info_dict['security'] = (
                     [
                         spec.policy.security.allowPromiscuous,

From 463a0c37ec3ab968b838794114cd8e49df971ba1 Mon Sep 17 00:00:00 2001
From: Marius Rieder <marius.rieder@durchmesser.ch>
Date: Fri, 6 May 2022 20:37:38 +0200
Subject: [PATCH 3/3] vmware_vswitch_info: Fix integration tests for policies

---
 .../targets/vmware_vswitch_info/tasks/main.yml            | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/tests/integration/targets/vmware_vswitch_info/tasks/main.yml b/tests/integration/targets/vmware_vswitch_info/tasks/main.yml
index 7b5e90b21..ca281aaba 100644
--- a/tests/integration/targets/vmware_vswitch_info/tasks/main.yml
+++ b/tests/integration/targets/vmware_vswitch_info/tasks/main.yml
@@ -53,6 +53,8 @@
 - assert:
     that:
       - switch_policies_info.hosts_vswitch_info is defined
-      - switch_policies_info.hosts_vswitch_info[esxi1].security is defined
-      - switch_policies_info.hosts_vswitch_info[esxi1].ts is defined
-      - switch_policies_info.hosts_vswitch_info[esxi1].lb is defined
+      - switch_policies_info.hosts_vswitch_info[esxi1] is defined
+      - switch_policies_info.hosts_vswitch_info[esxi1]['vSwitch0'] is defined
+      - switch_policies_info.hosts_vswitch_info[esxi1]['vSwitch0'].security is defined
+      - switch_policies_info.hosts_vswitch_info[esxi1]['vSwitch0'].ts is defined
+      - switch_policies_info.hosts_vswitch_info[esxi1]['vSwitch0'].lb is defined