1#!/usr/local/bin/python3.8
2# -*- coding: utf-8 -*-
3# Copyright: (c) 2018, Derek Rushing <derek.rushing@geekops.com>
4# Copyright: (c) 2018, VMware, Inc.
5# Copyright: (c) 2021, Ansible Project
6# Copyright: (c) 2021, Abhijeet Kasurde <akasurde@redhat.com>
7# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
8
9from __future__ import absolute_import, division, print_function
10
11__metaclass__ = type
12
13
14DOCUMENTATION = r"""
15---
16module: vmware_object_role_permission_info
17short_description: Gather information about object's permissions
18description: This module can be used to gather object permissions on the given VMware object.
19author:
20- Abhijeet Kasurde (@Akasurde)
21notes:
22    - Tested on ESXi 6.5, vSphere 6.7
23    - The ESXi login user must have the appropriate rights to administer permissions.
24    - Supports check mode.
25requirements:
26    - "python >= 3"
27    - PyVmomi
28options:
29  principal:
30    description:
31    - The optional name of an entity, such as a user, assigned permissions on an object.
32    - If provided, actual permissions on the specified object are returned for the principal, instead of roles.
33    type: str
34    required: False
35    version_added: '1.12.0'
36  object_name:
37    description:
38    - The object name to assigned permission.
39    - Mutually exclusive with I(moid).
40    type: str
41  object_type:
42    description:
43    - The object type being targeted.
44    default: 'Folder'
45    choices: ['Folder', 'VirtualMachine', 'Datacenter', 'ResourcePool',
46              'Datastore', 'Network', 'HostSystem', 'ComputeResource',
47              'ClusterComputeResource', 'DistributedVirtualSwitch']
48    type: str
49  moid:
50    description:
51    - Managed object ID for the given object.
52    - Mutually exclusive with I(object_name).
53    aliases: ['object_moid']
54    type: 'str'
55extends_documentation_fragment:
56- community.vmware.vmware.documentation
57version_added: "1.11.0"
58"""
59
60EXAMPLES = r"""
61- name: Gather role information about Datastore
62  community.vmware.vmware_object_role_permission_info:
63    hostname: "{{ vcenter_hostname }}"
64    username: "{{ vcenter_username }}"
65    password: "{{ vcenter_password }}"
66    validate_certs: false
67    object_name: ds_200
68    object_type: Datastore
69
70- name: Gather permissions on Datastore for a User
71  community.vmware.vmware_object_role_permission_info:
72    hostname: "{{ vcenter_hostname }}"
73    username: "{{ vcenter_username }}"
74    password: "{{ vcenter_password }}"
75    validate_certs: false
76    principal: some.user@company.com
77    object_name: ds_200
78    object_type: Datastore
79"""
80
81RETURN = r"""
82permission_info:
83    description: information about object's permission
84    returned: always
85    type: list
86    sample: [
87        {
88            "principal": "VSPHERE.LOCAL\\vpxd-extension-12e0b667-892c-4694-8a5e-f13147e45dbd",
89            "propagate": true,
90            "role_id": -1,
91            "role_name": "Admin"
92        }
93    ]
94"""
95
96try:
97    from pyVmomi import vim
98except ImportError:
99    pass
100
101from ansible.module_utils.basic import AnsibleModule
102from ansible_collections.community.vmware.plugins.module_utils.vmware import (
103    PyVmomi,
104    vmware_argument_spec,
105    find_obj,
106)
107
108
109class VMwareObjectRolePermission(PyVmomi):
110    def __init__(self, module):
111        super(VMwareObjectRolePermission, self).__init__(module)
112        self.module = module
113        self.params = module.params
114        self.role_list = {}
115        self.auth_manager = self.content.authorizationManager
116
117        self.principal = self.params.get('principal')
118        self.get_object()
119        self.get_perms()
120        self.populate_role_list()
121        self.populate_permission_list()
122
123    def populate_permission_list(self):
124        results = []
125        if self.principal is None:
126            for permission in self.current_perms:
127                results.append(
128                    {
129                        "principal": permission.principal,
130                        "role_name": self.role_list.get(permission.roleId, ""),
131                        "role_id": permission.roleId,
132                        "propagate": permission.propagate,
133                    }
134                )
135        else:
136            results = self.to_json(self.current_perms)
137        self.module.exit_json(changed=False, permission_info=results)
138
139    def populate_role_list(self):
140        user_friendly_role_names = {
141            "Admin": ["Administrator"],
142            "ReadOnly": ["Read-Only"],
143            "com.vmware.Content.Admin": [
144                "Content library administrator (sample)",
145                "Content library administrator",
146            ],
147            "NoCryptoAdmin": ["No cryptography administrator"],
148            "NoAccess": ["No access"],
149            "VirtualMachinePowerUser": [
150                "Virtual machine power user (sample)",
151                "Virtual machine power user",
152            ],
153            "VirtualMachineUser": [
154                "Virtual machine user (sample)",
155                "Virtual machine user",
156            ],
157            "ResourcePoolAdministrator": [
158                "Resource pool administrator (sample)",
159                "Resource pool administrator",
160            ],
161            "VMwareConsolidatedBackupUser": [
162                "VMware Consolidated Backup user (sample)",
163                "VMware Consolidated Backup user",
164            ],
165            "DatastoreConsumer": ["Datastore consumer (sample)", "Datastore consumer"],
166            "NetworkConsumer": [
167                "Network administrator (sample)",
168                "Network administrator",
169            ],
170            "VirtualMachineConsoleUser": ["Virtual Machine console user"],
171            "InventoryService.Tagging.TaggingAdmin": ["Tagging Admin"],
172        }
173        for role in self.content.authorizationManager.roleList:
174            self.role_list[role.roleId] = role.name
175            if user_friendly_role_names.get(role.name):
176                for role_name in user_friendly_role_names[role.name]:
177                    self.role_list[role.roleId] = role_name
178
179    def get_perms(self):
180        if self.principal is None:
181            self.current_perms = self.auth_manager.RetrieveEntityPermissions(
182                self.current_obj, True
183            )
184        else:
185            moid_list = []
186            moid_list.append(self.current_obj)
187            self.current_perms = self.auth_manager.FetchUserPrivilegeOnEntities(
188                moid_list, self.principal
189            )
190
191    def get_object(self):
192        # find_obj doesn't include rootFolder
193        if (
194            self.params["object_type"] == "Folder" and self.params["object_name"] == "rootFolder"
195        ):
196            self.current_obj = self.content.rootFolder
197            return
198
199        vim_type = None
200        try:
201            vim_type = getattr(vim, self.params["object_type"])
202        except AttributeError:
203            pass
204        if not vim_type:
205            self.module.fail_json(
206                msg="Object type %s is not valid." % self.params["object_type"]
207            )
208
209        msg = "Specified object "
210        if "moid" in self.params and self.params["moid"]:
211            self.current_obj = vim_type(self.params["moid"], self.si._stub)
212            msg += "with moid %s of type %s" % (
213                self.params["moid"],
214                self.params["object_type"],
215            )
216        elif "object_name" in self.params and self.params["object_name"]:
217            self.current_obj = find_obj(
218                content=self.content,
219                vimtype=[vim_type],
220                name=self.params["object_name"],
221            )
222            msg = "%s of type %s" % (
223                self.params["object_name"],
224                self.params["object_type"],
225            )
226
227        if self.current_obj is None:
228            msg += "was not found"
229            self.module.fail_json(msg=msg)
230
231
232def main():
233    argument_spec = vmware_argument_spec()
234    argument_spec.update(
235        dict(
236            principal=dict(
237                type="str",
238                required=False
239            ),
240            object_name=dict(type="str"),
241            object_type=dict(
242                type="str",
243                default="Folder",
244                choices=[
245                    "Folder",
246                    "VirtualMachine",
247                    "Datacenter",
248                    "ResourcePool",
249                    "Datastore",
250                    "Network",
251                    "HostSystem",
252                    "ComputeResource",
253                    "ClusterComputeResource",
254                    "DistributedVirtualSwitch",
255                ],
256            ),
257            moid=dict(
258                type="str",
259                aliases=["object_moid"],
260            ),
261        )
262    )
263
264    module = AnsibleModule(
265        argument_spec=argument_spec,
266        supports_check_mode=True,
267        required_one_of=[
268            ["object_name", "moid"],
269        ],
270        mutually_exclusive=[
271            ["object_name", "moid"],
272        ],
273    )
274
275    VMwareObjectRolePermission(module)
276
277
278if __name__ == "__main__":
279    main()
280