Example #1
0
class CaptureVMTemplateToContentLibrary(SampleBase):
    """
    Demonstrates the workflow to capture a virtual machine into a content library.

    Note: The sample needs an existing virtual machine to capture.
    """
    def __init__(self):
        SampleBase.__init__(self, self.__doc__)
        self.servicemanager = None
        self.datastore_name = None
        self.datastore_id = None
        self.cl_name = "LocalLibraryToCapture"
        self.vm_name = None
        self.vm_template_name = 'CapturedOvf'
        self.vm_template_description = 'Captured OVF description'
        self.deployable_resource_type = 'VirtualMachine'  # Substitute 'VirtualApp' for vApp

        self.content_library = None
        self.library_item_id = None

    def _options(self):
        self.argparser.add_argument('-datastorename',
                                    '--datastorename',
                                    required=True,
                                    help='The name of the datastore for'
                                    ' content library backing (of type vmfs)')
        self.argparser.add_argument('-vmname',
                                    '--vmname',
                                    required=True,
                                    help='Name of the VM to be captured')

    def _setup(self):
        self.datastore_name = self.args.datastorename
        assert self.datastore_name is not None

        self.vm_name = self.args.vmname
        assert self.vm_name is not None

        if self.servicemanager is None:
            self.servicemanager = self.get_service_manager()

        self.client = ClsApiClient(self.servicemanager)
        self.helper = ClsApiHelper(self.client, self.skip_verification)

        session = get_unverified_session() if self.skip_verification else None
        self.vsphere_client = create_vsphere_client(server=self.server,
                                                    username=self.username,
                                                    password=self.password,
                                                    session=session)

    def _execute(self):
        storage_backings = self.helper.create_storage_backings(
            self.servicemanager, self.datastore_name)

        print('Creating Content Library')
        # Create a content library
        library_id = self.helper.create_local_library(storage_backings,
                                                      self.cl_name)
        self.content_library = self.client.local_library_service.get(
            library_id)

        vm_id = get_vm(self.vsphere_client, self.vm_name)
        assert vm_id is not None

        param = self.create_capture_param(self.content_library,
                                          self.vm_template_name,
                                          self.vm_template_description)
        self.library_item_id = self.capture_source_vm(vm_id, param)
        assert self.library_item_id is not None
        assert self.client.library_item_service.get(
            self.library_item_id) is not None
        print(
            'The VM id : {0} is captured as vm template library item id : {1}'.
            format(vm_id, self.library_item_id))

    def capture_source_vm(self, vm_id, param):
        source = LibraryItem.DeployableIdentity(self.deployable_resource_type,
                                                vm_id)
        result = self.client.ovf_lib_item_service.create(
            source,
            param["target"],
            param["spec"],
            client_token=generate_random_uuid())
        return result.ovf_library_item_id

    def create_capture_param(self, library, name, description):
        spec = LibraryItem.CreateSpec(name=name, description=description)
        target = LibraryItem.CreateTarget(library_id=library.id,
                                          library_item_id=None)
        return {"target": target, "spec": spec}

    def _cleanup(self):
        # delete the local library.
        if self.content_library is not None:
            self.client.local_library_service.delete(
                library_id=self.content_library.id)
            print('Deleted Library Id: {0}'.format(self.content_library.id))
Example #2
0
class IsoMount(SampleBase):
    """
    Demonstrates the content library ISO item mount and
    unmount workflow via the mount and unmount APIs from the
    ISO service.
    """

    ISO_FILENAME = 'test.iso'

    def __init__(self):
        SampleBase.__init__(self, self.__doc__)
        self.servicemanager = None
        self.client = None
        self.datastore_name = None
        self.lib_name = "iso-demo-lib"
        self.local_library = None
        self.iso_item_name = "iso-demo-lib-item"
        self.vm_name = None

    def _options(self):
        self.argparser.add_argument(
            '-datastorename',
            '--datastorename',
            required=True,
            help='The name of a datastore (of type vmfs) that is'
            ' accessible to the vm specified with --vmname.')
        self.argparser.add_argument(
            '-vmname',
            '--vmname',
            required=True,
            help='The name of the vm where iso will be mounted. '
            'The vm needs to be already created on the vCenter')

    def _setup(self):
        self.datastore_name = self.args.datastorename
        assert self.datastore_name is not None

        self.vm_name = self.args.vmname
        assert self.vm_name is not None

        self.servicemanager = self.get_service_manager()

        self.client = ClsApiClient(self.servicemanager)
        self.helper = ClsApiHelper(self.client, self.skip_verification)

        session = get_unverified_session() if self.skip_verification else None
        self.vsphere_client = create_vsphere_client(server=self.server,
                                                    username=self.username,
                                                    password=self.password,
                                                    session=session)

    def _execute(self):
        storage_backings = self.helper.create_storage_backings(
            self.servicemanager, self.datastore_name)

        library_id = self.helper.create_local_library(storage_backings,
                                                      self.lib_name)
        self.local_library = self.client.local_library_service.get(library_id)

        library_item_id = self.helper.create_iso_library_item(
            library_id, self.iso_item_name, self.ISO_FILENAME)

        vm_id = get_vm(self.vsphere_client, self.vm_name)
        assert vm_id is not None

        # Mount the iso item as a CDROM device
        device_id = self.client.iso_service.mount(library_item_id, vm_id)
        assert device_id is not None
        print('Mounted library item {0} on vm {1} at device {2}'.format(
            self.iso_item_name, self.vm_name, device_id))
        # Unmount the CDROM
        self.client.iso_service.unmount(vm_id, device_id)
        print('Unmounted library item {0} from vm {1} mounted at device {2}'.
              format(self.iso_item_name, self.vm_name, device_id))

    def _cleanup(self):
        if self.local_library:
            self.client.local_library_service.delete(
                library_id=self.local_library.id)
            print('Deleted Library Id: {0}'.format(self.local_library.id))
class SignedOvaImport(SampleBase):
    """
    Demonstrates the workflow to import an OVA file into the content library,
    as an OVF library item.

    Note: the workflow needs an existing VC DS with available storage.
    """

    SIGNED_OVA_FILENAME = 'nostalgia-signed.ova'
    SIGNED_OVA_RELATIVE_DIR = '../resources/signedOvaWithCertWarning'

    def __init__(self):
        SampleBase.__init__(self, self.__doc__)
        self.servicemanager = None
        self.client = None
        self.helper = None
        self.datastore_name = None
        self.lib_name = 'ova-demo-lib'
        self.local_lib_id = None
        self.lib_item_name = 'signedOvaImport'
        self.lib_item_id = None

    def _options(self):
        self.argparser.add_argument('-datastorename',
                                    '--datastorename',
                                    required=True,
                                    help='The name of the datastore.')

    def _setup(self):
        self.servicemanager = self.get_service_manager()

        self.client = ClsApiClient(self.servicemanager)
        self.helper = ClsApiHelper(self.client, self.skip_verification)

    def _execute(self):
        # Build the storage backing for the library to be created using given datastore name
        self.datastore_name = self.args.datastorename
        storage_backings = self.helper.create_storage_backings(
            service_manager=self.servicemanager,
            datastore_name=self.datastore_name)

        # Create a local content library backed by the VC datastore using vAPIs
        self.local_lib_id = self.helper.create_local_library(
            storage_backings, self.lib_name)

        # Create a new library item in the content library for uploading the files
        self.lib_item_id = self.helper.create_library_item(
            library_id=self.local_lib_id,
            item_name=self.lib_item_name,
            item_description='Sample template from ova file',
            item_type='ovf')
        print('Library item created. ID: {0}'.format(self.lib_item_id))

        ova_file_map = self.helper.get_ova_file_map(
            self.SIGNED_OVA_RELATIVE_DIR,
            local_filename=self.SIGNED_OVA_FILENAME)
        # Create a new upload session for uploading the files
        # To ignore expected warnings and skip preview info check,
        # you can set create_spec.warning_behavior during session creation
        session_id = self.client.upload_service.create(
            create_spec=UpdateSessionModel(library_item_id=self.lib_item_id),
            client_token=generate_random_uuid())
        self.helper.upload_files_in_session(ova_file_map, session_id)

        # Wait for terminal preview state and obtain preview warnings if any
        self.wait_for_terminal_preview_state(session_id, AVAILABLE)
        session = self.client.upload_service.get(session_id)
        preview_info = session.preview_info

        # Collect generated preview warning types
        preview_warning_types = []
        print('Preview warnings for the session are the following:')
        for preview_warning in preview_info.warnings:
            print(preview_warning.message.default_message)
            preview_warning_types.append(preview_warning.type)

        # Ignore preview warnings on session
        ignore_warning_behaviors = []
        for warning_type in preview_warning_types:
            warning_behavior = WarningBehavior(type=warning_type, ignored=True)
            ignore_warning_behaviors.append(warning_behavior)
        self.client.upload_service.update(
            session_id,
            update_spec=UpdateSessionModel(
                warning_behavior=ignore_warning_behaviors))
        print(
            'All preview warnings are ignored, proceeding to complete the session'
        )

        self.client.upload_service.complete(session_id)
        self.client.upload_service.delete(session_id)
        print(
            'Uploaded ova file as an ovf template to library item {0}'.format(
                self.lib_item_id))

    def wait_for_terminal_preview_state(self,
                                        session_id,
                                        expected_terminal_preview_state,
                                        timeout_sec=300):
        """
        Periodically checks update session for preview state to reach a terminal state.

        :param session_id: ID of update session for which preview state is checked
        :param expected_terminal_preview_state: expected terminal preview state
        :param timeout_sec: number of seconds to wait before timing out
        """
        preview_state = None
        start_time = time.time()
        terminal_preview_state_list = [NOT_APPLICABLE, AVAILABLE]
        while (time.time() - start_time) < timeout_sec:
            session = self.client.upload_service.get(session_id)
            if session.state == 'ERROR':
                raise Exception(
                    'Session is in error state, error message: {}'.format(
                        session.error_message))
            preview_state = session.preview_info.state
            # check if preview state is in one of the terminal states
            if preview_state not in terminal_preview_state_list:
                time.sleep(1)
            else:
                break

        if preview_state != expected_terminal_preview_state:
            raise Exception(
                'Preview state did not reach expected {} state, actual preview state: '
                '{}'.format(expected_terminal_preview_state, preview_state))

    def _cleanup(self):
        if self.local_lib_id:
            self.client.local_library_service.delete(
                library_id=self.local_lib_id)
            print('Deleted library ID: {0}'.format(self.local_lib_id))
Example #4
0
class ContentUpdate(SampleBase):
    """
    Demonstrates the workflow of updating a content library item.

    Note: the workflow needs an existing datastore (of type vmfs) with available storage.
    """

    ISO_FILE_1 = 'test.iso'
    ISO_FILE_2 = 'test-2.iso'
    ISO_ITEM_NAME = 'test'

    def __init__(self):
        SampleBase.__init__(self, self.__doc__)
        self.servicemanager = None
        self.client = None
        self.helper = None
        self.datastore_name = None
        self.lib_name = "demo-lib"
        self.local_library = None

    def _options(self):
        self.argparser.add_argument('-datastorename',
                                    '--datastorename',
                                    help='The name of the datastore where '
                                    'the library will be created.')

    def _setup(self):
        self.datastore_name = self.args.datastorename
        assert self.datastore_name is not None

        self.servicemanager = self.get_service_manager()
        self.client = ClsApiClient(self.servicemanager)
        self.helper = ClsApiHelper(self.client, self.skip_verification)

    def _execute(self):
        storage_backings = self.helper.create_storage_backings(
            self.servicemanager, self.datastore_name)

        library_id = self.helper.create_local_library(storage_backings,
                                                      self.lib_name)
        self.local_library = self.client.local_library_service.get(library_id)
        self.delete_and_upload_scenario(library_id)
        self.replace_scenario(library_id)

    def replace_scenario(self, library_id):
        """
        :param library_id: the Iso item will be created, and then replaced in this library
        :return: None

        Content update scenario 2:
        Update ISO library item by creating an update session for the
        item, then adding the new ISO file using the same session file
        name into the update session, which will replace the existing
        ISO file upon session complete.
        """

        iso_item_id = self.helper.create_library_item(
            library_id=library_id,
            item_name=self.ISO_ITEM_NAME,
            item_description='Sample iso file',
            item_type='iso')
        print('ISO Library item version (on creation) {0}:'.format(
            self.get_item_version(iso_item_id)))

        iso_files_map = self.helper.get_iso_file_map(
            item_filename=self.ISO_FILE_1, disk_filename=self.ISO_FILE_1)
        self.helper.upload_files(library_item_id=iso_item_id,
                                 files_map=iso_files_map)
        original_version = self.get_item_version(iso_item_id)
        print('ISO Library item version (on original content upload) {0}:'.
              format(original_version))

        session_id = self.client.upload_service.create(
            create_spec=UpdateSessionModel(library_item_id=iso_item_id),
            client_token=generate_random_uuid())
        # Use the same item filename (update endpoint, as it's a replace scenario)
        iso_files_map = self.helper.get_iso_file_map(
            item_filename=self.ISO_FILE_1, disk_filename=self.ISO_FILE_2)

        self.helper.upload_files_in_session(iso_files_map, session_id)
        self.client.upload_service.complete(session_id)
        self.client.upload_service.delete(session_id)
        updated_version = self.get_item_version(iso_item_id)
        print('ISO Library item version (after content update): {0}'.format(
            updated_version))
        assert updated_version > original_version, 'content update should increase the version'

    def delete_and_upload_scenario(self, library_id):
        """
        :param library_id: the OVF item will be created and updated in this library
        :return: None

        Content update scenario 1:
        Update OVF library item by creating an update session for the
        OVF item, removing all existing files in the session, then
        adding all new files into the same update session, and completing
        the session to finish the content update.
        """

        # Create a new library item in the content library for uploading the files
        ovf_item_id = self.helper.create_library_item(
            library_id=library_id,
            item_name='demo-ovf-item',
            item_description='Sample simple VM template',
            item_type='ovf')
        assert ovf_item_id is not None
        print('Library item created id: {0}'.format(ovf_item_id))
        print('OVF Library item version (at creation) {0}:'.format(
            self.get_item_version(ovf_item_id)))

        # Upload a VM template to the CL
        ovf_files_map = self.helper.get_ovf_files_map(
            ClsApiHelper.SIMPLE_OVF_RELATIVE_DIR)
        self.helper.upload_files(library_item_id=ovf_item_id,
                                 files_map=ovf_files_map)
        print('Uploaded ovf and vmdk files to library item {0}'.format(
            ovf_item_id))
        original_version = self.get_item_version(ovf_item_id)
        print('OVF Library item version (on original content upload): {0}'.
              format(original_version))

        # Create a new session and perform content update
        session_id = self.client.upload_service.create(
            create_spec=UpdateSessionModel(library_item_id=ovf_item_id),
            client_token=generate_random_uuid())
        existing_files = self.client.upload_file_service.list(session_id)
        for file in existing_files:
            print('deleting {0}'.format(file.name))
            self.client.upload_file_service.remove(session_id, file.name)
        ovf_files_map = self.helper.get_ovf_files_map(
            ovf_location=ClsApiHelper.PLAIN_OVF_RELATIVE_DIR)
        self.helper.upload_files_in_session(ovf_files_map, session_id)
        self.client.upload_service.complete(session_id)
        self.client.upload_service.delete(session_id)
        updated_version = self.get_item_version(ovf_item_id)
        print('OVF Library item version (after content update): {0}'.format(
            updated_version))
        assert updated_version > original_version, 'content update should increase the version'

    def get_item_version(self, item_id):
        ovf_item_model = self.client.library_item_service.get(item_id)
        pre_update_version = ovf_item_model.content_version
        return pre_update_version

    def _cleanup(self):
        if self.local_library:
            self.client.local_library_service.delete(
                library_id=self.local_library.id)
            print('Deleted Library Id: {0}'.format(self.local_library.id))
Example #5
0
class CreateVmTemplate(SampleBase):
    """
    Demonstrates how to create a library item containing a virtual machine
    template from a virtual machine.

    Prerequisites:
        - A virtual machine
        - A datacenter
        - A resource pool
        - A datastore
    """
    def __init__(self):
        SampleBase.__init__(self, self.__doc__)
        self.servicemanager = None
        self.client = None
        self.helper = None
        self.vm_name = None
        self.datastore_name = None
        self.library_name = 'demo-vmtx-lib'
        self.item_name = None
        self.item_id = None

    def _options(self):
        self.argparser.add_argument('-vmname',
                                    '--vmname',
                                    required=True,
                                    help='The name of the source VM from '
                                    'which to create a library item')
        self.argparser.add_argument('-datacentername',
                                    '--datacentername',
                                    required=True,
                                    help='The name of the datacenter in which '
                                    'to place the VM template')
        self.argparser.add_argument('-resourcepoolname',
                                    '--resourcepoolname',
                                    required=True,
                                    help='The name of the resource pool in '
                                    'the datacenter in which to place '
                                    'the VM template')
        self.argparser.add_argument('-datastorename',
                                    '--datastorename',
                                    required=True,
                                    help='The name of the datastore in which '
                                    'to create a library and VM template')
        self.argparser.add_argument('-itemname',
                                    '--itemname',
                                    help='The name of the library item to '
                                    'create. The item will contain a '
                                    'VM template.')

    def _setup(self):
        # Required arguments
        self.vm_name = self.args.vmname
        self.datacenter_name = self.args.datacentername
        self.resource_pool_name = self.args.resourcepoolname
        self.datastore_name = self.args.datastorename

        # Optional arguments
        self.item_name = (self.args.itemname
                          if self.args.itemname else rand('vmtx-item-'))

        self.servicemanager = self.get_service_manager()
        self.client = ClsApiClient(self.servicemanager)
        self.helper = ClsApiHelper(self.client, self.skip_verification)

        session = get_unverified_session() if self.skip_verification else None
        self.vsphere_client = create_vsphere_client(server=self.server,
                                                    username=self.username,
                                                    password=self.password,
                                                    session=session)

    def _execute(self):
        # Get the identifiers
        vm_id = get_vm(self.vsphere_client, self.vm_name)
        assert vm_id
        resource_pool_id = get_resource_pool(self.vsphere_client,
                                             self.datacenter_name,
                                             self.resource_pool_name)
        assert resource_pool_id

        # Create a library
        storage_backings = self.helper.create_storage_backings(
            self.servicemanager, self.datastore_name)
        self.library_id = self.helper.create_local_library(
            storage_backings, self.library_name)

        # Build the create specification
        create_spec = VmtxLibraryItem.CreateSpec()
        create_spec.source_vm = vm_id
        create_spec.library = self.library_id
        create_spec.name = self.item_name
        create_spec.placement = VmtxLibraryItem.CreatePlacementSpec(
            resource_pool=resource_pool_id)

        # Create a new library item from the source VM
        self.item_id = self.client.vmtx_service.create(create_spec)
        print("Created VM template item '{0}' with ID: {1}".format(
            self.item_name, self.item_id))

        # Retrieve the library item info
        info = self.client.vmtx_service.get(self.item_id)
        print('VM template guest OS: {0}'.format(info.guest_os))

    def _cleanup(self):
        if self.library_id:
            self.client.local_library_service.delete(self.library_id)
            print('Deleted library ID: {0}'.format(self.library_id))