VMware: Handle user unauthorization in tagging scenarios (#58405)
Handle unauthorization scenarios in VMware tagging APIs. Fixes: #58326 Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
This commit is contained in:
parent
242f160747
commit
e2d159c40c
5 changed files with 76 additions and 18 deletions
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- Handle user unauthorization errors in VMware REST API code for tagging (https://github.com/ansible/ansible/issues/58326).
|
|
@ -29,6 +29,7 @@ VSPHERE_IMP_ERR = None
|
|||
try:
|
||||
from com.vmware.vapi.std_client import DynamicID
|
||||
from vmware.vapi.vsphere.client import create_vsphere_client
|
||||
from com.vmware.vapi.std.errors_client import Unauthorized
|
||||
HAS_VSPHERE = True
|
||||
except ImportError:
|
||||
VSPHERE_IMP_ERR = traceback.format_exc()
|
||||
|
@ -49,6 +50,22 @@ class VmwareRestClient(object):
|
|||
self.check_required_library()
|
||||
self.api_client = self.connect_to_vsphere_client()
|
||||
|
||||
# Helper function
|
||||
def get_error_message(self, error):
|
||||
"""
|
||||
Helper function to show human readable error messages.
|
||||
"""
|
||||
err_msg = []
|
||||
if not error.messages:
|
||||
if isinstance(error, Unauthorized):
|
||||
return "Authorization required."
|
||||
return "Generic error occurred."
|
||||
|
||||
for err in error.messages:
|
||||
err_msg.append(err.default_message % err.args)
|
||||
|
||||
return " ,".join(err_msg)
|
||||
|
||||
def check_required_library(self):
|
||||
"""
|
||||
Check required libraries
|
||||
|
|
|
@ -119,6 +119,7 @@ from ansible.module_utils.basic import AnsibleModule
|
|||
from ansible.module_utils.vmware_rest_client import VmwareRestClient
|
||||
try:
|
||||
from com.vmware.cis.tagging_client import CategoryModel
|
||||
from com.vmware.vapi.std.errors_client import Error
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
@ -159,7 +160,11 @@ class VmwareCategory(VmwareRestClient):
|
|||
|
||||
category_spec.associable_types = set()
|
||||
|
||||
try:
|
||||
category_id = self.category_service.create(category_spec)
|
||||
except Error as error:
|
||||
self.module.fail_json(msg="%s" % self.get_error_message(error))
|
||||
|
||||
if category_id:
|
||||
self.module.exit_json(changed=True,
|
||||
category_results=dict(msg="Category '%s' created." % category_spec.name,
|
||||
|
@ -199,8 +204,11 @@ class VmwareCategory(VmwareRestClient):
|
|||
change_list.append(True)
|
||||
|
||||
if any(change_list):
|
||||
try:
|
||||
self.category_service.update(category_id, category_update_spec)
|
||||
changed = True
|
||||
except Error as error:
|
||||
self.module.fail_json(msg="%s" % self.get_error_message(error))
|
||||
|
||||
self.module.exit_json(changed=changed,
|
||||
category_results=results)
|
||||
|
@ -208,7 +216,10 @@ class VmwareCategory(VmwareRestClient):
|
|||
def state_delete_category(self):
|
||||
"""Delete category."""
|
||||
category_id = self.global_categories[self.category_name]['category_id']
|
||||
try:
|
||||
self.category_service.delete(category_id=category_id)
|
||||
except Error as error:
|
||||
self.module.fail_json(msg="%s" % self.get_error_message(error))
|
||||
self.module.exit_json(changed=True,
|
||||
category_results=dict(msg="Category '%s' deleted." % self.category_name,
|
||||
category_id=category_id))
|
||||
|
|
|
@ -107,6 +107,10 @@ results:
|
|||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.vmware_rest_client import VmwareRestClient
|
||||
try:
|
||||
from com.vmware.vapi.std.errors_client import Error
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
class VmwareTag(VmwareRestClient):
|
||||
|
@ -160,13 +164,18 @@ class VmwareTag(VmwareRestClient):
|
|||
self.module.fail_json(msg="Unable to find category specified using 'category_id' - %s" % category_id)
|
||||
|
||||
tag_spec.category_id = category_id
|
||||
tag_id = ''
|
||||
try:
|
||||
tag_id = self.tag_service.create(tag_spec)
|
||||
except Error as error:
|
||||
self.module.fail_json(msg="%s" % self.get_error_message(error))
|
||||
|
||||
if tag_id:
|
||||
self.module.exit_json(changed=True,
|
||||
results=dict(msg="Tag '%s' created." % tag_spec.name,
|
||||
tag_id=tag_id))
|
||||
self.module.exit_json(changed=False,
|
||||
results=dict(msg="No tag created", tag_id=''))
|
||||
results=dict(msg="No tag created", tag_id=tag_id))
|
||||
|
||||
def state_unchanged(self):
|
||||
"""
|
||||
|
@ -189,7 +198,11 @@ class VmwareTag(VmwareRestClient):
|
|||
desired_tag_desc = self.params.get('tag_description')
|
||||
if tag_desc != desired_tag_desc:
|
||||
tag_update_spec.description = desired_tag_desc
|
||||
try:
|
||||
self.tag_service.update(tag_id, tag_update_spec)
|
||||
except Error as error:
|
||||
self.module.fail_json(msg="%s" % self.get_error_message(error))
|
||||
|
||||
results['msg'] = 'Tag %s updated.' % self.tag_name
|
||||
changed = True
|
||||
|
||||
|
@ -201,7 +214,10 @@ class VmwareTag(VmwareRestClient):
|
|||
|
||||
"""
|
||||
tag_id = self.global_tags[self.tag_name]['tag_id']
|
||||
try:
|
||||
self.tag_service.delete(tag_id=tag_id)
|
||||
except Error as error:
|
||||
self.module.fail_json(msg="%s" % self.get_error_message(error))
|
||||
self.module.exit_json(changed=True,
|
||||
results=dict(msg="Tag '%s' deleted." % self.tag_name,
|
||||
tag_id=tag_id))
|
||||
|
|
|
@ -137,6 +137,7 @@ from ansible.module_utils.vmware_rest_client import VmwareRestClient
|
|||
from ansible.module_utils.vmware import (PyVmomi, find_dvs_by_name, find_dvspg_by_name)
|
||||
try:
|
||||
from com.vmware.vapi.std_client import DynamicID
|
||||
from com.vmware.vapi.std.errors_client import Error
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
@ -239,20 +240,31 @@ class VmwareTagManager(VmwareRestClient):
|
|||
if action in ('add', 'present'):
|
||||
if tag_obj not in available_tag_obj:
|
||||
# Tag is not already applied
|
||||
try:
|
||||
self.tag_association_svc.attach(tag_id=tag_obj.id, object_id=self.dynamic_managed_object)
|
||||
changed = True
|
||||
except Error as error:
|
||||
self.module.fail_json(msg="%s" % self.get_error_message(error))
|
||||
|
||||
elif action == 'set':
|
||||
# Remove all tags first
|
||||
try:
|
||||
if not removed_tags_for_set:
|
||||
for av_tag in available_tag_obj:
|
||||
self.tag_association_svc.detach(tag_id=av_tag.id, object_id=self.dynamic_managed_object)
|
||||
removed_tags_for_set = True
|
||||
self.tag_association_svc.attach(tag_id=tag_obj.id, object_id=self.dynamic_managed_object)
|
||||
changed = True
|
||||
except Error as error:
|
||||
self.module.fail_json(msg="%s" % self.get_error_message(error))
|
||||
|
||||
elif action in ('remove', 'absent'):
|
||||
if tag_obj in available_tag_obj:
|
||||
try:
|
||||
self.tag_association_svc.detach(tag_id=tag_obj.id, object_id=self.dynamic_managed_object)
|
||||
changed = True
|
||||
except Error as error:
|
||||
self.module.fail_json(msg="%s" % self.get_error_message(error))
|
||||
|
||||
results['tag_status']['current_tags'] = [tag.name for tag in self.get_tags_for_object(self.tag_service,
|
||||
self.tag_association_svc,
|
||||
|
|
Loading…
Reference in a new issue