diff --git a/lib/ansible/module_utils/vmware_rest_client.py b/lib/ansible/module_utils/vmware_rest_client.py index b6f9cadd60d..1e3a9086c50 100644 --- a/lib/ansible/module_utils/vmware_rest_client.py +++ b/lib/ansible/module_utils/vmware_rest_client.py @@ -25,21 +25,10 @@ except ImportError: PYVMOMI_IMP_ERR = traceback.format_exc() HAS_PYVMOMI = False -VCLOUD_IMP_ERR = None -try: - from vmware.vapi.lib.connect import get_requests_connector - from vmware.vapi.security.session import create_session_security_context - from vmware.vapi.security.user_password import create_user_password_security_context - from com.vmware.cis_client import Session - from com.vmware.vapi.std_client import DynamicID - HAS_VCLOUD = True -except ImportError: - VCLOUD_IMP_ERR = traceback.format_exc() - HAS_VCLOUD = False - VSPHERE_IMP_ERR = None try: - from vmware.vapi.stdlib.client.factories import StubConfigurationFactory + from com.vmware.vapi.std_client import DynamicID + from vmware.vapi.vsphere.client import create_vsphere_client HAS_VSPHERE = True except ImportError: VSPHERE_IMP_ERR = traceback.format_exc() @@ -58,7 +47,7 @@ class VmwareRestClient(object): self.module = module self.params = module.params self.check_required_library() - self.connect = self.connect_to_rest() + self.api_client = self.connect_to_vsphere_client() def check_required_library(self): """ @@ -76,59 +65,6 @@ class VmwareRestClient(object): msg=missing_required_lib('vSphere Automation SDK', url='https://code.vmware.com/web/sdk/65/vsphere-automation-python'), exception=VSPHERE_IMP_ERR) - if not HAS_VCLOUD: - self.module.fail_json( - msg=missing_required_lib('vCloud Suite SDK', - url='https://code.vmware.com/web/sdk/60/vcloudsuite-python'), - exception=VCLOUD_IMP_ERR) - - def connect_to_rest(self): - """ - Connect to server using username and password - - """ - session = requests.Session() - session.verify = self.params.get('validate_certs') - - username = self.params.get('username', None) - password = self.params.get('password', None) - protocol = self.params.get('protocol', 'https') - hostname = self.params.get('hostname') - - if not all([self.params.get('hostname', None), username, password]): - self.module.fail_json(msg="Missing one of the following : hostname, username, password." - " Please read the documentation for more information.") - - vcenter_url = "%s://%s/api" % (protocol, hostname) - - # Get request connector - connector = get_requests_connector(session=session, url=vcenter_url) - # Create standard Configuration - stub_config = StubConfigurationFactory.new_std_configuration(connector) - # Use username and password in the security context to authenticate - security_context = create_user_password_security_context(username, password) - # Login - stub_config.connector.set_security_context(security_context) - # Create the stub for the session service and login by creating a session. - session_svc = Session(stub_config) - session_id = None - try: - session_id = session_svc.create() - except OSError as os_err: - self.module.fail_json(msg="Failed to login to %s: %s" % (hostname, - to_native(os_err))) - - if session_id is None: - self.module.fail_json(msg="Failed to create session using provided credentials." - " Please check hostname, username and password.") - # After successful authentication, store the session identifier in the security - # context of the stub and use that for all subsequent remote requests - session_security_context = create_session_security_context(session_id) - stub_config.connector.set_security_context(session_security_context) - - if stub_config is None: - self.module.fail_json(msg="Failed to login to %s" % hostname) - return stub_config @staticmethod def vmware_client_argument_spec(): @@ -150,6 +86,31 @@ class VmwareRestClient(object): default=True), ) + def connect_to_vsphere_client(self): + """ + Connect to vSphere API Client with Username and Password + + """ + username = self.params.get('username') + password = self.params.get('password') + hostname = self.params.get('hostname') + session = requests.Session() + session.verify = self.params.get('validate_certs') + + if not all([hostname, username, password]): + self.module.fail_json(msg="Missing one of the following : hostname, username, password." + " Please read the documentation for more information.") + + client = create_vsphere_client( + server=hostname, + username=username, + password=password, + session=session) + if client is None: + self.module.fail_json(msg="Failed to login to %s" % hostname) + + return client + def get_tags_for_object(self, tag_service, tag_assoc_svc, dobj): """ Return list of tag objects associated with an object diff --git a/lib/ansible/modules/cloud/vmware/vmware_category.py b/lib/ansible/modules/cloud/vmware/vmware_category.py index fd42c54f3c7..d5343ff5d92 100644 --- a/lib/ansible/modules/cloud/vmware/vmware_category.py +++ b/lib/ansible/modules/cloud/vmware/vmware_category.py @@ -119,7 +119,7 @@ category_results: from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.vmware_rest_client import VmwareRestClient try: - from com.vmware.cis.tagging_client import Category, CategoryModel + from com.vmware.cis.tagging_client import CategoryModel except ImportError: pass @@ -127,7 +127,7 @@ except ImportError: class VmwareCategory(VmwareRestClient): def __init__(self, module): super(VmwareCategory, self).__init__(module) - self.category_service = Category(self.connect) + self.category_service = self.api_client.tagging.Category self.global_categories = dict() self.category_name = self.params.get('category_name') self.get_all_categories() diff --git a/lib/ansible/modules/cloud/vmware/vmware_category_facts.py b/lib/ansible/modules/cloud/vmware/vmware_category_facts.py index 31d8fc6be2c..60f5480a9ff 100644 --- a/lib/ansible/modules/cloud/vmware/vmware_category_facts.py +++ b/lib/ansible/modules/cloud/vmware/vmware_category_facts.py @@ -91,16 +91,12 @@ tag_category_facts: from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.vmware_rest_client import VmwareRestClient -try: - from com.vmware.cis.tagging_client import Category -except ImportError: - pass class VmwareCategoryFactsManager(VmwareRestClient): def __init__(self, module): super(VmwareCategoryFactsManager, self).__init__(module) - self.category_service = Category(self.connect) + self.category_service = self.api_client.tagging.Category def get_all_tag_categories(self): """Retrieve all tag category information.""" diff --git a/lib/ansible/modules/cloud/vmware/vmware_guest_facts.py b/lib/ansible/modules/cloud/vmware/vmware_guest_facts.py index f0ad0e7449f..64a266e4f77 100644 --- a/lib/ansible/modules/cloud/vmware/vmware_guest_facts.py +++ b/lib/ansible/modules/cloud/vmware/vmware_guest_facts.py @@ -218,17 +218,16 @@ from ansible.module_utils.vmware import PyVmomi, vmware_argument_spec from ansible.module_utils.vmware_rest_client import VmwareRestClient try: from com.vmware.vapi.std_client import DynamicID - from com.vmware.cis.tagging_client import Tag, TagAssociation - HAS_VCLOUD = True + HAS_VSPHERE = True except ImportError: - HAS_VCLOUD = False + HAS_VSPHERE = False class VmwareTag(VmwareRestClient): def __init__(self, module): super(VmwareTag, self).__init__(module) - self.tag_service = Tag(self.connect) - self.tag_association_svc = TagAssociation(self.connect) + self.tag_service = self.api_client.tagging.Tag + self.tag_association_svc = self.api_client.tagging.TagAssociation def main(): @@ -268,7 +267,7 @@ def main(): else: instance = pyv.to_json(vm, module.params['properties']) if module.params.get('tags'): - if not HAS_VCLOUD: + if not HAS_VSPHERE: module.fail_json(msg="Unable to find 'vCloud Suite SDK' Python library which is required." " Please refer this URL for installation steps" " - https://code.vmware.com/web/sdk/60/vcloudsuite-python") diff --git a/lib/ansible/modules/cloud/vmware/vmware_tag.py b/lib/ansible/modules/cloud/vmware/vmware_tag.py index 1617b3ecadc..ff9cc0c9250 100644 --- a/lib/ansible/modules/cloud/vmware/vmware_tag.py +++ b/lib/ansible/modules/cloud/vmware/vmware_tag.py @@ -108,20 +108,17 @@ results: from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.vmware_rest_client import VmwareRestClient -try: - from com.vmware.cis.tagging_client import Tag, Category -except ImportError: - pass class VmwareTag(VmwareRestClient): def __init__(self, module): super(VmwareTag, self).__init__(module) - self.tag_service = Tag(self.connect) self.global_tags = dict() + # api_client to call APIs instead of individual service + self.tag_service = self.api_client.tagging.Tag self.tag_name = self.params.get('tag_name') self.get_all_tags() - self.category_service = Category(self.connect) + self.category_service = self.api_client.tagging.Category def ensure_state(self): """ diff --git a/lib/ansible/modules/cloud/vmware/vmware_tag_facts.py b/lib/ansible/modules/cloud/vmware/vmware_tag_facts.py index e8aded77e23..ea5dca8d943 100644 --- a/lib/ansible/modules/cloud/vmware/vmware_tag_facts.py +++ b/lib/ansible/modules/cloud/vmware/vmware_tag_facts.py @@ -86,17 +86,13 @@ results: from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.vmware_rest_client import VmwareRestClient -try: - from com.vmware.cis.tagging_client import Tag -except ImportError: - pass class VmTagFactManager(VmwareRestClient): def __init__(self, module): """Constructor.""" super(VmTagFactManager, self).__init__(module) - self.tag_service = Tag(self.connect) + self.tag_service = self.api_client.tagging.Tag self.global_tags = dict() def get_all_tags(self): diff --git a/lib/ansible/modules/cloud/vmware/vmware_tag_manager.py b/lib/ansible/modules/cloud/vmware/vmware_tag_manager.py index e4b1914785b..abe46ccfffc 100644 --- a/lib/ansible/modules/cloud/vmware/vmware_tag_manager.py +++ b/lib/ansible/modules/cloud/vmware/vmware_tag_manager.py @@ -138,7 +138,6 @@ 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.cis.tagging_client import Tag, TagAssociation, Category except ImportError: pass @@ -186,9 +185,9 @@ class VmwareTagManager(VmwareRestClient): self.dynamic_managed_object = DynamicID(type=self.object_type, id=self.managed_object._moId) - self.tag_service = Tag(self.connect) - self.category_service = Category(self.connect) - self.tag_association_svc = TagAssociation(self.connect) + self.tag_service = self.api_client.tagging.Tag + self.category_service = self.api_client.tagging.Category + self.tag_association_svc = self.api_client.tagging.TagAssociation self.tag_names = self.params.get('tag_names') diff --git a/test/integration/targets/vmware_tag/aliases b/test/integration/targets/vmware_tag/aliases new file mode 100644 index 00000000000..c2a6921d433 --- /dev/null +++ b/test/integration/targets/vmware_tag/aliases @@ -0,0 +1,2 @@ +cloud/vcenter +unsupported \ No newline at end of file diff --git a/test/integration/targets/vmware_tag/tasks/main.yml b/test/integration/targets/vmware_tag/tasks/main.yml new file mode 100644 index 00000000000..1cbd000fe52 --- /dev/null +++ b/test/integration/targets/vmware_tag/tasks/main.yml @@ -0,0 +1,6 @@ +# Test code for the vmware_tag Operations. +# Copyright: (c) 2019, Pavan Bidkar +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +- include: tag_crud_ops.yml +- include: tag_manager_ops.yml \ No newline at end of file diff --git a/test/integration/targets/vmware_tag/tasks/tag_crud_ops.yml b/test/integration/targets/vmware_tag/tasks/tag_crud_ops.yml new file mode 100644 index 00000000000..36b38757e65 --- /dev/null +++ b/test/integration/targets/vmware_tag/tasks/tag_crud_ops.yml @@ -0,0 +1,78 @@ +# Test code for the vmware_tag CRUD Operations. +# Copyright: (c) 2019, Pavan Bidkar +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +- when: vcsim is not defined + block: + + # Testcase Create Category + - name: Create Category + vmware_category: + hostname: '{{ vcenter_hostname }}' + username: '{{ vcenter_username }}' + password: '{{ vcenter_password }}' + validate_certs: False + category_name: Sample_Cat_0006 + category_description: Sample Description + category_cardinality: 'multiple' + state: present + register: category_create + + - name: Check Category is created + assert: + that: + - category_create.changed + + - name: Set Cat_ID Paramter. Required for Tag creation + set_fact: Cat_ID={{ category_create['category_results']['category_id'] }} + + # Testcase Create Tag + - name: Create a tag + vmware_tag: + hostname: '{{ vcenter_hostname }}' + username: '{{ vcenter_username }}' + password: '{{ vcenter_password }}' + validate_certs: no + tag_name: Sample_Tag_0001 + category_id: "{{ Cat_ID }}" + tag_description: Sample Description + state: present + register: tag_creation + + - name: Check tag is created + assert: + that: + - tag_creation.changed + + # Testcase Update Tag Description (reconfig) + - name: Update Tag Description + vmware_tag: + hostname: '{{ vcenter_hostname }}' + username: '{{ vcenter_username }}' + password: '{{ vcenter_password }}' + validate_certs: no + tag_name: Sample_Tag_0001 + tag_description: Some fancy description + state: present + register: update_tag_desc + + - name: Check tag description updated + assert: + that: + - update_tag_desc.changed + + # Testcase Delete the Tag + - name: Delete Tag + vmware_tag: + hostname: '{{ vcenter_hostname }}' + username: '{{ vcenter_username }}' + password: '{{ vcenter_password }}' + validate_certs: no + tag_name: Sample_Tag_0001 + state: absent + register: delete_tag + + - name: Check Tag is Deleted + assert: + that: + - delete_tag.changed \ No newline at end of file diff --git a/test/integration/targets/vmware_tag/tasks/tag_manager_ops.yml b/test/integration/targets/vmware_tag/tasks/tag_manager_ops.yml new file mode 100644 index 00000000000..ec686455380 --- /dev/null +++ b/test/integration/targets/vmware_tag/tasks/tag_manager_ops.yml @@ -0,0 +1,49 @@ +# Test code for the vmware_tag Manager Operations. +# Copyright: (c) 2019, Pavan Bidkar +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +- when: vcsim is not defined + block: + + # Get VM name to attach the tag + - name: Get VM Facts + vmware_vm_facts: + hostname: '{{ vcenter_hostname }}' + username: '{{ vcenter_username }}' + password: '{{ vcenter_password }}' + validate_certs: False + register: vm_facts + + - set_fact: vm_name="{{ vm_facts['virtual_machines'][0]['guest_name'] }}" + + # Get Tagname + - name: Get facts about tag + vmware_tag_facts: + hostname: '{{ vcenter_hostname }}' + username: '{{ vcenter_username }}' + password: '{{ vcenter_password }}' + validate_certs: False + register: tag_facts + + - set_fact: Tag_Name={{ tag_facts['tag_facts'].keys() | list }} + + - debug: var=Tag_Name + + # Testcase Assign tag to virtual Machine + - name: Add tags to a virtual machine + vmware_tag_manager: + hostname: '{{ vcenter_hostname }}' + username: '{{ vcenter_username }}' + password: '{{ vcenter_password }}' + validate_certs: no + tag_names: + - "{{ Tag_Name[0] }}" + object_name: "{{ vm_name }}" + object_type: VirtualMachine + state: add + register: tag_manager_ops + + - name: Check Category is created + assert: + that: + - tag_manager_ops.changed" \ No newline at end of file