Exemple #1
0
    def __init__(self, session, server, username, password, bearer_token,
                 hok_token, private_key):
        """
        Initialize VsphereClient by creating a parent stub factory instance
        of all vSphere components.

        :type  session: :class:`requests.Session`
        :param session: Requests HTTP session instance. If not specified,
        then one is automatically created and used
        :type  server: :class:`str`
        :param server: vCenter host name or IP address
        :type  username: :class:`str`
        :param username: Name of the user
        :type  password: :class:`str`
        :param password: Password of the user
        :type  bearer_token: :class:`str`
        :param bearer_token: SAML Bearer Token
        :type  hok_token: :class:`str`
        :param hok_token: SAML Hok Token
        :type  private_key: :class:`str`
        :param private_key: Absolute file path of the private key of the user
        """
        if not session:
            self.session = session = requests.Session()
        host_url = "https://" + server + JSON_RPC_ENDPOINT

        if username is not None and password is not None and \
                not bearer_token and not hok_token:
            sec_ctx = create_user_password_security_context(username, password)
        elif bearer_token and not username and not hok_token:
            sec_ctx = create_saml_bearer_security_context(bearer_token)
        elif hok_token and private_key and not bearer_token and not username:
            sec_ctx = create_saml_security_context(hok_token, private_key)
        else:
            raise ValueError('Please provide exactly one of the following '
                             'authentication scheme: username/password, '
                             'bear_token or hok_token/private_key')

        session_svc = Session(
            StubConfigurationFactory.new_std_configuration(
                get_requests_connector(
                    session=session,
                    url=host_url,
                    provider_filter_chain=[
                        LegacySecurityContextFilter(security_context=sec_ctx)
                    ])))

        session_id = session_svc.create()
        sec_ctx = create_session_security_context(session_id)
        stub_config = StubConfigurationFactory.new_std_configuration(
            get_requests_connector(
                session=session,
                url=host_url,
                provider_filter_chain=[
                    LegacySecurityContextFilter(security_context=sec_ctx)
                ]))
        self.session_svc = Session(stub_config)
        stub_factory = StubFactory(stub_config)
        ApiClient.__init__(self, stub_factory)
Exemple #2
0
    def _login_vapi(self):
        """
        Login to vCenter API using REST call
        Returns: connection object

        """
        session = requests.Session()
        session.verify = self.validate_certs
        if not self.validate_certs:
            # Disable warning shown at stdout
            requests.packages.urllib3.disable_warnings()

        vcenter_url = "https://%s/api" % self.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(self.username, self.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 = session_svc.create()

        # 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:
            raise AnsibleError("Failed to login to %s using %s" % (self.hostname, self.username))
        return stub_config
def logout(stub_config):
    """
    Delete session with vCenter.
    """
    if stub_config:
        session_svc = Session(stub_config)
        session_svc.delete()
Exemple #4
0
    def _vApiInit(self, host, user, password, proto='https', msg_type='json'):
        """
        The authenticated stub configuration object can be used to issue requests against vCenter.
        The _config object stores the session identifier that can be used to issue authenticated
        requests against vCenter.
        """
        session = requests.Session()
        session.verify = False
        api_url = '{0}://{1}/api'.format(proto, host)

        self._connector = get_requests_connector(session=session, url=api_url)
        self._config = StubConfigurationFactory.new_std_configuration(
            self._connector)

        # Creating security context loging for vAPI endpoint authentication
        sec_context_login = create_user_password_security_context(
            user, password)
        self._config.connector.set_security_context(sec_context_login)

        # Create the stub for the session service and login by creating a session.
        session_svc = Session(self._config)
        session_id = session_svc.create()

        # Successful authentication.  Store the session identifier in the security
        # context of the stub config and use that for all subsequent remote requests
        session_security_context = create_session_security_context(session_id)
        self._config.connector.set_security_context(session_security_context)
Exemple #5
0
def stub_connect(host, username, password, verify=False):
    """
    Connect to the vCenter using the REST API
    """
    from com.vmware.cis_client import Session
    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 vmware.vapi.stdlib.client.factories import StubConfigurationFactory

    url = "https://{}/api".format(host)

    session = requests.Session()
    session.verify = verify

    connector = get_requests_connector(session=session, url=url)
    stub_config = StubConfigurationFactory.new_std_configuration(connector)

    # Pass user credentials (user/password) in the security context to authenticate.
    # login to vAPI endpoint
    user_password_security_context = create_user_password_security_context(
        username, password)
    stub_config.connector.set_security_context(user_password_security_context)
    session_svc = Session(stub_config)
    session_id = session_svc.create()
    session_security_context = create_session_security_context(session_id)
    stub_config.connector.set_security_context(session_security_context)

    return stub_config
Exemple #6
0
def get_configuration(server, username, password, skipVerification):
    session = get_unverified_session() if skipVerification else None
    if not session:
        session = requests.Session()
    host_url = "https://{}/api".format(server)
    sec_ctx = create_user_password_security_context(username, password)
    session_svc = Session(
        StubConfigurationFactory.new_std_configuration(
            get_requests_connector(
                session=session,
                url=host_url,
                provider_filter_chain=[
                    LegacySecurityContextFilter(security_context=sec_ctx)
                ])))
    session_id = session_svc.create()
    print("Session ID : ", session_id)
    sec_ctx = create_session_security_context(session_id)
    stub_config = StubConfigurationFactory.new_std_configuration(
        get_requests_connector(
            session=session,
            url=host_url,
            provider_filter_chain=[
                LegacySecurityContextFilter(security_context=sec_ctx)
            ]))
    return stub_config
    def run(self):
        print('\n\n#### Example: Login to vCenter server with '
              'embedded Platform Services Controller')

        # Since the platform services controller is embedded, the sso server
        # is the same as the vCenter server.
        ssoUrl = 'https://{}/sts/STSService'.format(self.server)

        print('\nStep 1: Connect to the Single Sign-On URL and '
              'retrieve the SAML bearer token.')

        authenticator = sso.SsoAuthenticator(ssoUrl)
        context = None
        if self.skip_verification:
            context = get_unverified_context()
        bearer_token = authenticator.get_bearer_saml_assertion(
            self.username,
            self.password,
            delegatable=True,
            ssl_context=context)

        # Creating SAML Bearer Security Context
        sec_ctx = create_saml_bearer_security_context(bearer_token)

        print('\nStep 2. Login to vAPI services using the SAML bearer token.')

        # The URL for the stub requests are made against the /api HTTP endpoint
        # of the vCenter system.
        vapi_url = 'https://{}/api'.format(self.server)

        # Create an authenticated stub configuration object that can be used to
        # issue requests against vCenter.
        session = requests.Session()
        if self.skip_verification:
            session = create_unverified_session(session)
        connector = get_requests_connector(session=session, url=vapi_url)
        connector.set_security_context(sec_ctx)
        stub_config = StubConfigurationFactory.new_std_configuration(
            connector)
        self.session = Session(stub_config)

        # Login to VAPI endpoint and get the session_id
        self.session_id = self.session.create()

        # Update the VAPI connection with session_id
        session_sec_ctx = create_session_security_context(self.session_id)
        connector.set_security_context(session_sec_ctx)

        print('\nStep 3: List available datacenters using the vAPI services')

        datacenter_svc = Datacenter(stub_config)
        pprint(datacenter_svc.list())

        self.session.delete()
        print('VAPI session disconnected successfully...')
Exemple #8
0
def automationSDKConnect(vcenter=None,
                         username=None,
                         password=None,
                         insecure=None):
    """Creates stub_config with connection object for advanced features like VM Tagging present
    in vsphere-automation-sdk-python library, which is required to be installed:
    https://github.com/vmware/vsphere-automation-sdk-python"""
    vcenter = vcenter or conf.VCENTER
    username = username or conf.USERNAME
    password = password or conf.PASSWORD
    insecure = insecure or conf.INSECURE_CONNECTION

    if not HAS_AUTOMAT_SDK_INSTALLED:
        raise VmCLIException(
            'Required vsphere-automation-sdk-python not installed. Exiting...')
        sys.exit(1)

    if (vcenter and username) and not password:
        password = getpass.getpass()
    elif not (vcenter and username and password):
        logger.error('No authentication credentials provided!')
        sys.exit(1)

    if not vcenter.startswith('http'):
        vcenter = 'https://{}/api'.format(vcenter)

    session = requests.Session()
    if insecure:
        requests.packages.urllib3.disable_warnings(
            requests.packages.urllib3.exceptions.InsecureRequestWarning)
        session.verify = False

    connector = get_requests_connector(session=session, url=vcenter)
    stub_config = StubConfigurationFactory.new_std_configuration(connector)

    # Pass user credentials (user/password) in the security context to authenticate.
    # login to vAPI endpoint
    user_password_security_context = create_user_password_security_context(
        username, password)
    stub_config.connector.set_security_context(user_password_security_context)

    # Create the stub for the session service and login by creating a session.
    session_svc = Session(stub_config)
    try:
        session_id = session_svc.create()
    except Unauthenticated:
        logger.error('Unable to connect. Check your credentials!')
        sys.exit(1)

    # 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)

    return stub_config
Exemple #9
0
    def __init__(self, sddc=None, verbose=False):

        self.sddc = sddc

        if not self.sddc:
            raise ValueError('You must supply a valid SDDC() object')

        self.org = sddc.org
        self.vmc = self.org.vmc

        self.vc_url = self.sddc.sddc.resource_config.vc_url
        self.vc_host = re.sub(r'https://(.*)/', r'\1', self.vc_url)
        self.vc_username = self.sddc.sddc.resource_config.cloud_username
        self.vc_password = self.sddc.sddc.resource_config.cloud_password

        session = requests.Session()
        connector = get_requests_connector(session=session,
                                           url='https://' + self.vc_host +
                                           '/api')
        user_password_security_context = create_user_password_security_context(
            self.vc_username, self.vc_password)
        context = ssl._create_unverified_context()

        self.stub_config = StubConfigurationFactory.new_std_configuration(
            connector)
        self.stub_config.connector.set_security_context(
            user_password_security_context)

        session_svc = Session(self.stub_config)
        session_id = session_svc.create()
        session_security_context = create_session_security_context(session_id)

        self.stub_config.connector.set_security_context(
            session_security_context)
        self.library_stub = content_client.Library(self.stub_config)
        self.subscribed_library_stub = content_client.SubscribedLibrary(
            self.stub_config)
        self.si = SmartConnect(host=self.vc_host,
                               user=self.vc_username,
                               pwd=self.vc_password,
                               sslContext=context)
        self.content = self.si.RetrieveContent()

        self.references = {}

        self.referenceTypes = {
            'datastores': [vim.Datastore],
            'resourcePools': [vim.ClusterComputeResource],
            'folders': [vim.Folder],
            'VMs': [vim.VirtualMachine]
        }

        for referenceName in self.referenceTypes:
            self.refreshReference(referenceName)
Exemple #10
0
    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
def connect_cis():
    """Connect to CIS"""
    import configuration as config
    import requests
    import urllib3
    from com.vmware.cis_client import Session
    from vmware.vapi.security.user_password import create_user_password_security_context
    from vmware.vapi.stdlib.client.factories import StubConfigurationFactory
    from vmware.vapi.lib.connect import get_requests_connector
    from vmware.vapi.security.session import create_session_security_context
    # Create a session object in the client.
    session = requests.Session()
    # We don't have valid certificates so...
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
    session.verify = False
    # Create a connection for the session.
    connector = get_requests_connector(
        session=session,
        url='https://' + config.VM_HOSTNAME + '/api'
    )
    # Add username/password security context to the connector.
    connector.set_security_context(
        create_user_password_security_context(
            config.VM_USERNAME,
            config.VM_PASSWORD
        )
    )
    # Create a stub configuration by using the username-password security context.
    my_stub_config = StubConfigurationFactory.new_std_configuration(connector)
    # Create a Session stub with username-password security context.
    session_stub = Session(my_stub_config)
    # Use the create operation to create an authenticated session.
    session_id = session_stub.create()
    # Create a session ID security context.
    session_id_context = create_session_security_context(session_id)
    # Update the stub configuration with the session ID security context.
    my_stub_config.connector.set_security_context(session_id_context)
    return my_stub_config
def login(stub_config, user, pwd):
    """
    Create an authenticated session with vCenter.

    Returns a stub_config that stores the session identifier that can be used
    to issue authenticated requests against vCenter.
    """
    # Pass user credentials (user/password) in the security context to
    # authenticate.
    user_password_security_context = create_user_password_security_context(
        user, pwd)
    stub_config.connector.set_security_context(user_password_security_context)

    # Create the stub for the session service and login by creating a session.
    session_svc = Session(stub_config)
    session_id = session_svc.create()

    # 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)

    return stub_config
    def run(self):
        print('\n\n#### Example: Login to vCenter server with '
              'embedded Platform Services Controller')

        # Since the platform services controller is embedded, the sso server
        # is the same as the vCenter server.
        ssoUrl = 'https://{}/sts/STSService'.format(self.args.server)

        print('\nStep 1: Connect to the Single Sign-On URL and '
              'retrieve the SAML bearer token.')

        authenticator = sso.SsoAuthenticator(ssoUrl)
        context = None
        if self.args.skipverification:
            context = get_unverified_context()
        bearer_token = authenticator.get_bearer_saml_assertion(
            self.args.username,
            self.args.password,
            delegatable=True,
            ssl_context=context)

        # Creating SAML Bearer Security Context
        sec_ctx = create_saml_bearer_security_context(bearer_token)

        print('\nStep 2. Login to vAPI services using the SAML bearer token.')

        # The URL for the stub requests are made against the /api HTTP endpoint
        # of the vCenter system.
        vapi_url = 'https://{}/api'.format(self.args.server)

        # Create an authenticated stub configuration object that can be used to
        # issue requests against vCenter.
        session = requests.Session()
        if self.args.skipverification:
            session = create_unverified_session(session)
        connector = get_requests_connector(session=session, url=vapi_url)
        connector.set_security_context(sec_ctx)
        stub_config = StubConfigurationFactory.new_std_configuration(connector)
        self.session = Session(stub_config)

        # Login to VAPI endpoint and get the session_id
        self.session_id = self.session.create()

        # Update the VAPI connection with session_id
        session_sec_ctx = create_session_security_context(self.session_id)
        connector.set_security_context(session_sec_ctx)

        # Create and Delete TagCategory to Verify connection is successful
        print('\nStep 3: Creating and Deleting Tag Category...\n')
        self.category_svc = Category(stub_config)

        self.category_id = self.create_tag_category(
            'TestTagCat', 'TestTagDesc', CategoryModel.Cardinality.MULTIPLE)
        assert self.category_id is not None
        print('Tag category created; Id: {0}\n'.format(self.category_id))

        # Delete TagCategory
        self.category_svc.delete(self.category_id)

        self.session.delete()
        print('VAPI session disconnected successfully...')
Exemple #14
0
    def discover_environment(self, debug=False):
        # Connect to the lookup service to discover relevant information
        self.lookup_service_helper = LookupServiceHelper(
            wsdl_url=self.user_wsdl_url + '/lookupservice.wsdl',
            soap_url=self.vcs_target,
            skip_verification=True)
        self.lookup_service_helper.connect()

        # Print information obtained through the lookup service to the console
        if debug:
            print("SSO URL: " + str(self.lookup_service_helper.find_sso_url()))
            print("VAPI URL(s): " +
                  str(self.lookup_service_helper.find_vapi_urls()))
            print("VIM URL: " +
                  str(self.lookup_service_helper.find_vim_urls()))
            print("VIM PBM URL(s): " +
                  str(self.lookup_service_helper.find_vim_pbm_urls()))
            print("MGMT Nodes: " +
                  str(self.lookup_service_helper.find_mgmt_nodes()))
            print()
            print('Connecting to SSO Service : $s',
                  str(self.lookup_service_helper.find_sso_url()))
            print(" - user: {}".format(self.sso_user))

        # Use the SsoAuthenticator utility class to retrieve
        # a bearer SAML token from the vCenter Single Sign-On service.
        print()
        print("Retrieving SAML Token ::")
        authenticator = sso.SsoAuthenticator(
            str(self.lookup_service_helper.find_sso_url()))
        saml_token = authenticator.get_bearer_saml_assertion(self.sso_user,
                                                             self.sso_pass,
                                                             delegatable=True)

        print(">>> SAML Token Successfully Retrieved!")

        print()
        print("Generating vSphere Authentication Session via SAML Token ::")
        # Create a session object in the client.
        session = requests.Session()

        # For development environment only, suppress server certificate checking.
        print()
        print("Suppressing Server Certificate Checking...")
        session.verify = False
        disable_warnings(InsecureRequestWarning)
        print(">>> Server Certificate Checking Suppressed!")

        # Create a connection for the session.
        print()
        print("Creating the VAPI connection object...")
        vapi_url = str(self.lookup_service_helper.find_vapi_urls()).split()[1]
        vapi_url = vapi_url[:-1]
        if debug:
            print(" --> Endpoint: " + vapi_url)
        connector = get_requests_connector(session=session, url=vapi_url)

        # Add SAML token security context to the connector.
        saml_token_context = create_saml_bearer_security_context(saml_token)
        connector.set_security_context(saml_token_context)

        # Create a stub configuration by using the SAML token security context.
        self.stub_config = StubConfigurationFactory.new_std_configuration(
            connector)

        # Create a Session stub with SAML token security context.
        session_stub = Session(self.stub_config)

        # Use the create operation to create an authenticated session.
        session_id = session_stub.create()
        if debug:
            print(" --> vSphere Automation Session ID: ", session_id)

        # Create a session ID security context.
        session_id_context = create_session_security_context(session_id)

        # Update the stub configuration with the session ID security context.
        self.stub_config.connector.set_security_context(session_id_context)

        print()
        print("Generating Web Services Session Info via Lookup Service...")
        vim_url = str(self.lookup_service_helper.find_vim_urls()).split()[1]
        vim_url = vim_url[:-1]
        if debug:
            print(" --> Endpoint: " + vim_url)

        # Extract the hostname from the endpoint URL.
        url_scheme, url_host, url_path, url_params, url_query, url_fragment = \
            urlparse(vim_url)
        pattern = '(?P<host>[^:/ ]+).?(?P<port>[0-9]*)'
        match = re.search(pattern, url_host)
        self.web_svcs_host = match.group('host')
        if debug:
            print(">>> Connecting to host: ", self.web_svcs_host)
Exemple #15
0
Returns a stub_config that stores the session identifier that can be used
to issue authenticated requests against vCenter.
"""
session = requests.Session()
session.verify = False
connector = get_requests_connector(session=session, url=url)
stub_config = StubConfigurationFactory.new_std_configuration(connector)

# Pass user credentials (user/password) in the security context to authenticate.
# login to vAPI endpoint
user_password_security_context = create_user_password_security_context(
    username, password)
stub_config.connector.set_security_context(user_password_security_context)

# Create the stub for the session service and login by creating a session.
session_svc = Session(stub_config)
session_id = session_svc.create()

# 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)

# Create Tagging services
tag_svc = Tag(stub_config)
category_svc = Category(stub_config)
tag_association = TagAssociation(stub_config)


def get_vm_id(name):
    """Find vm id by given name using pyVmomi."""
    def run(self):
        print('\n\n#### Example: Login to vCenter server with '
              'external Platform Services Controller')

        print('\nStep 1: Connect to the lookup service on the '
              'Platform Services Controller node: {0}'.format(self.lsurl))

        # Convert wsdl path to url
        self.lswsdl = parse.urljoin('file:', request.pathname2url(self.lswsdl))
        lookupservicehelper = LookupServiceHelper(
            wsdl_url=self.lswsdl,
            soap_url=self.lsurl,
            skip_verification=self.skip_verification)
        lookupservicehelper.connect()

        if self.mgmtinstancename is None:
            self.mgmtinstancename, self.mgmtnodeid = lookupservicehelper.get_default_mgmt_node(
            )
        elif self.mgmtnodeid is None:
            self.mgmtnodeid = lookupservicehelper.get_mgmt_node_id(
                self.mgmtinstancename)
        assert self.mgmtnodeid is not None

        print('\nStep 2: Discover the Single Sign-On service URL'
              ' from lookup service.')
        sso_url = lookupservicehelper.find_sso_url()
        print('Sso URL: {0}'.format(sso_url))

        print('\nStep 3: Connect to the Single Sign-On URL and '
              'retrieve the SAML bearer token.')
        authenticator = sso.SsoAuthenticator(sso_url)
        context = None
        if self.skip_verification:
            context = get_unverified_context()
        bearer_token = authenticator.get_bearer_saml_assertion(
            self.username,
            self.password,
            delegatable=True,
            ssl_context=context)

        # Creating SAML Bearer Security Context
        sec_ctx = create_saml_bearer_security_context(bearer_token)

        print('\nStep 4. Discover the vAPI service URL from lookup service.')
        vapi_url = lookupservicehelper.find_vapi_url(self.mgmtnodeid)
        print('vAPI URL: {0}'.format(vapi_url))

        print('\nStep 5. Login to vAPI service using the SAML bearer token.')

        # Create an authenticated stub configuration object that can be used to
        # issue requests against vCenter.
        session = requests.Session()
        if self.skip_verification:
            session = create_unverified_session(session)
        connector = get_requests_connector(session=session, url=vapi_url)
        connector.set_security_context(sec_ctx)
        stub_config = StubConfigurationFactory.new_std_configuration(connector)
        self.session = Session(stub_config)

        # Login to VAPI endpoint and get the session_id
        self.session_id = self.session.create()

        # Update the VAPI connection with session_id
        session_sec_ctx = create_session_security_context(self.session_id)
        connector.set_security_context(session_sec_ctx)

        # Create and Delete TagCategory to Verify connection is successful
        print('\nStep 6: Creating and Deleting Tag Category...\n')
        self.category_svc = Category(stub_config)

        self.category_id = self.create_tag_category(
            'TestTagCat', 'TestTagDesc', CategoryModel.Cardinality.MULTIPLE)
        assert self.category_id is not None
        print('Tag category created; Id: {0}\n'.format(self.category_id))

        # Delete TagCategory
        self.category_svc.delete(self.category_id)

        self.session.delete()
        print('VAPI session disconnected successfully...')