def get_org_href(self): """Return the href of the org where the parent resource belongs to. :return: (str): org href of the parent resource. """ if 'VApp' in self.parent_resource.tag: # for vapp, have to get the org via vdc vdc_href = find_link(self.parent_resource, RelationType.UP, EntityType.VDC.value).href return find_link(self.client.get_resource(vdc_href), RelationType.UP, EntityType.ORG.value).href else: return find_link(self.parent_resource, RelationType.UP, EntityType.ORG.value).href
def get_org_href(self): """Return the href of the org where the parent resource belongs to. :return: (str): org href of the parent resource. """ if 'VApp' in self.parent_resource.tag: # for vapp, have to get the org via vdc vdc_href = find_link(self.parent_resource, RelationType.UP, EntityType.VDC.value).href return find_link( self.client.get_resource(vdc_href), RelationType.UP, EntityType.ORG.value).href else: return find_link(self.parent_resource, RelationType.UP, EntityType.ORG.value).href
def get_org_name_from_ovdc_id(sysadmin_client: vcd_client.Client, vdc_id): """Get org_name from vdc_id using OVDC_TO_ORG_MAP. Update OVDC_TO_ORG_MAP for new {org_name:vdc_id} pair :param vdc_id: unique ovdc id :return: org_name :rtype: str """ raise_error_if_not_sysadmin(sysadmin_client) if vdc_id in OVDC_TO_ORG_MAP: return OVDC_TO_ORG_MAP.get(vdc_id) vdc_href = f"{sysadmin_client.get_api_uri()}/vdc/{vdc_id}" vdc_resource = sysadmin_client.get_resource(get_admin_href(vdc_href)) vdc_obj = VDC(sysadmin_client, resource=vdc_resource) link = vcd_client.find_link(vdc_obj.get_resource(), vcd_client.RelationType.UP, vcd_client.EntityType.ADMIN_ORG.value) org = vcd_org.Org(sysadmin_client, href=link.href) OVDC_TO_ORG_MAP[vdc_id] = org.get_name() return org.get_name()
def change_catalog_owner(self, catalog_name, user_name): """ Change the ownership of Catalog to a given user :param catalog_name: Catalog whose ownership needs to be changed :param user_name: New Owner of the Catalog :return: None """ # NOQA if self.resource is None: self.resource = self.client.get_resource(self.href) catalog_resource = self.get_catalog_resource( catalog_name, is_admin_operation=True) owner_link = find_link( catalog_resource, rel=RelationType.DOWN, media_type=EntityType.OWNER.value, fail_if_absent=True) catalog_href = owner_link.href user_resource = self.get_user(user_name) new_owner = catalog_resource.Owner new_owner.User.set('href', user_resource.get('href')) objectify.deannotate(new_owner) return self.client.put_resource(catalog_href, new_owner, EntityType.OWNER.value)
def _build_self_href(self): self.parent = self._get_parent_by_name() self.parent_href = self.parent.get('href') self.href = find_link(self.client.get_resource(self.parent_href), RelationType.DOWN, EntityType.vApp_Network.value, name=self.network_name).href
def change_catalog_owner(self, catalog_name, user_name): """Change the ownership of Catalog to a given user :param catalog_name: Catalog whose ownership needs to be changed :param user_name: New Owner of the Catalog :return: None """ if self.resource is None: self.resource = self.client.get_resource(self.href) catalog_resource = self.get_catalog_resource( catalog_name, is_admin_operation=True) owner_link = find_link( catalog_resource, rel=RelationType.DOWN, media_type=EntityType.OWNER.value, fail_if_absent=True) catalog_href = owner_link.href user_resource = self.get_user(user_name) new_owner = catalog_resource.Owner new_owner.User.set('href', user_resource.get('href')) objectify.deannotate(new_owner) return self.client.put_resource(catalog_href, new_owner, EntityType.OWNER.value)
def get_org_name_from_ovdc_id(vdc_id): """Get org_name from vdc_id using OVDC_TO_ORG_MAP. Update OVDC_TO_ORG_MAP for new {org_name:vdc_id} pair :param vdc_id: unique ovdc id :return: org_name :rtype: str """ if vdc_id in OVDC_TO_ORG_MAP: org_name = OVDC_TO_ORG_MAP.get(vdc_id) else: client = None try: client = get_sys_admin_client() vdc_href = f"{client._uri}/vdc/{vdc_id}" vdc_resource = client.get_resource(get_admin_href(vdc_href)) vdc_obj = VDC(client, resource=vdc_resource) link = find_link(vdc_obj.get_resource(), RelationType.UP, EntityType.ADMIN_ORG.value) org = Org(client, href=link.href) OVDC_TO_ORG_MAP[vdc_id] = org.get_name() org_name = org.get_name() finally: if client: client.logout return org_name
def get_user_rights(sys_admin_client, user_session): """Return rights associated with the role of an user. :param pyvcloud.vcd.client.Client sys_admin_client: the sys admin cilent that will be used to query vCD about the rights and roles of the concerned user. :param lxml.objectify.ObjectifiedElement user_session: :return: the list of rights contained in the role of the user (corresponding to the user_session). :rtype: list of str """ user_org_link = find_link(resource=user_session, rel=RelationType.DOWN, media_type=EntityType.ORG.value) user_org_href = user_org_link.href org = Org(sys_admin_client, href=user_org_href) user_role_name = user_session.get('roles') role = Role(sys_admin_client, resource=org.get_role_resource(user_role_name)) user_rights = [] user_rights_as_list_of_dict = role.list_rights() for right_dict in user_rights_as_list_of_dict: user_rights.append(right_dict.get('name')) return user_rights
def get_org_name_href_from_ovdc_id(sysadmin_client: vcd_client.Client, vdc_id): """Get org name and href from vdc_id using OVDC_TO_ORG_MAP. Update OVDC_TO_ORG_MAP for new vdc_id :param vdc_id: unique ovdc id :return: org's name and href :rtype: dict """ raise_error_if_user_not_from_system_org(sysadmin_client) if vdc_id in OVDC_TO_ORG_MAP: return OVDC_TO_ORG_MAP.get(vdc_id) vdc_href = f"{sysadmin_client.get_api_uri()}/vdc/{vdc_id}" vdc_resource = sysadmin_client.get_resource(get_admin_href(vdc_href)) vdc_obj = VDC(sysadmin_client, resource=vdc_resource) link = vcd_client.find_link(vdc_obj.get_resource(), vcd_client.RelationType.UP, vcd_client.EntityType.ADMIN_ORG.value) org_href = link.href org = vcd_org.Org(sysadmin_client, href=org_href) org_name = org.get_name() result = {'name': org_name, 'href': org_href} OVDC_TO_ORG_MAP[vdc_id] = result return result
def connect_org_vdc_network(self, orgvdc_network_name, retain_ip=None, is_deployed=None, fence_mode=FenceMode.BRIDGED.value): """Connect the vapp to an orgvdc network. :param orgvdc_network_name: (str): name of the orgvdc network to be connected :param retain_ip: (bool): True if the network resources such as IP/MAC of router will be retained across deployments. :param is_deployed: (bool): True if this orgvdc network has been deployed. :param fence_mode: (str): Controls connectivity to the parent network. One of bridged, isolated or natRouted. bridged by default. :return: A :class:`lxml.objectify.StringElement` object representing the asynchronous task that is connecting the network. :raises: Exception: If orgvdc network does not exist in the vdc or if it is already connected to the vapp. """ vdc = VDC(self.client, href=find_link(self.resource, RelationType.UP, EntityType.VDC.value).href) orgvdc_networks = \ vdc.list_orgvdc_network_resources(orgvdc_network_name) if len(orgvdc_networks) == 0: raise EntityNotFoundException( "Orgvdc network \'%s\' does not exist in vdc " "\'%s\'" % (orgvdc_network_name, vdc.get_resource().get('name'))) orgvdc_network_href = orgvdc_networks[0].get('href') network_configuration_section = \ deepcopy(self.resource.NetworkConfigSection) matched_orgvdc_network_config = \ self._search_for_network_config_by_name( orgvdc_network_name, network_configuration_section) if matched_orgvdc_network_config is not None: raise InvalidStateException( "Orgvdc network \'%s\' is already connected to " "vapp." % orgvdc_network_name) configuration = E.Configuration( E.ParentNetwork(href=orgvdc_network_href), E.FenceMode(fence_mode)) if retain_ip is not None: configuration.append(E.RetainNetInfoAcrossDeployments(retain_ip)) network_config = E.NetworkConfig(configuration, networkName=orgvdc_network_name) if is_deployed is not None: network_config.append(E.IsDeployed(is_deployed)) network_configuration_section.append(network_config) return self.client.put_linked_resource( self.resource.NetworkConfigSection, RelationType.EDIT, EntityType.NETWORK_CONFIG_SECTION.value, network_configuration_section)
def connect_org_vdc_network(self, orgvdc_network_name, retain_ip=None, is_deployed=None, fence_mode=FenceMode.BRIDGED.value): """Connect the vApp to an org vdc network. :param str orgvdc_network_name: name of the org vdc network to be connected to. :param bool retain_ip: True, if the network resources such as IP/MAC of router will be retained across deployments. :param bool is_deployed: True, if this org vdc network has been deployed. :param str fence_mode: mode of connectivity to the parent network. Acceptable values are 'bridged', 'isolated' or 'natRouted'. Default value is 'bridged'. :return: an object containing EntityType.TASK XML data which represents the asynchronous task that is connecting the vApp to the network. :rtype: lxml.objectify.ObjectifiedElement :raises: EntityNotFoundException: if named org vdc network does not exist. :raises: InvalidStateException: if the vApp is already connected to the org vdc network. """ vdc = VDC(self.client, href=find_link(self.resource, RelationType.UP, EntityType.VDC.value).href) orgvdc_network_href = vdc.get_orgvdc_network_record_by_name( orgvdc_network_name).get('href') network_configuration_section = \ deepcopy(self.resource.NetworkConfigSection) matched_orgvdc_network_config = \ self._search_for_network_config_by_name( orgvdc_network_name, network_configuration_section) if matched_orgvdc_network_config is not None: raise InvalidStateException( "Org vdc network \'%s\' is already connected to " "vApp." % orgvdc_network_name) configuration = E.Configuration( E.ParentNetwork(href=orgvdc_network_href), E.FenceMode(fence_mode)) if retain_ip is not None: configuration.append(E.RetainNetInfoAcrossDeployments(retain_ip)) network_config = E.NetworkConfig( configuration, networkName=orgvdc_network_name) if is_deployed is not None: network_config.append(E.IsDeployed(is_deployed)) network_configuration_section.append(network_config) return self.client.put_linked_resource( self.resource.NetworkConfigSection, RelationType.EDIT, EntityType.NETWORK_CONFIG_SECTION.value, network_configuration_section)
def _build_self_href(self): self.parent = self._get_parent_by_name() self.parent_href = self.parent.get('href') self.href = find_link( self.client.get_resource(self.parent_href), RelationType.DOWN, EntityType.vApp_Network.value, name=self.network_name).href
def test_0200_create_vapp_network_from_ovdc_network(self): vapp = Environment.get_vapp_in_test_vdc( client=TestVApp._sys_admin_client, vapp_name=TestVApp._customized_vapp_name) task = vapp.create_vapp_network_from_ovdc_network( TestVApp._ovdc_network_name) result = TestVApp._sys_admin_client.get_task_monitor( ).wait_for_success(task) self.assertEqual(result.get('status'), TaskStatus.SUCCESS.value) vapp.reload() vapp_network_href = find_link(resource=vapp.resource, rel=RelationType.DOWN, media_type=EntityType.vApp_Network.value, name=TestVApp._ovdc_network_name).href self.assertIsNotNone(vapp_network_href)
def test_0111_connect_vapp_network_to_ovdc_network(self): vapp = Environment.get_vapp_in_test_vdc( client=TestVApp._sys_admin_client, vapp_name=TestVApp._customized_vapp_name) # connect vapp network to org vdc network task = vapp.connect_vapp_network_to_ovdc_network( TestVApp._vapp_network_name, TestVApp._ovdc_network_name) result = TestVApp._client.get_task_monitor().wait_for_success(task) self.assertEqual(result.get('status'), TaskStatus.SUCCESS.value) vapp_network_href = find_link(resource=vapp.resource, rel=RelationType.DOWN, media_type=EntityType.vApp_Network.value, name=TestVApp._vapp_network_name).href vapp_net_res = TestVApp._client.get_resource(vapp_network_href) self.assertEqual(vapp_net_res.Configuration.ParentNetwork.get('name'), TestVApp._ovdc_network_name)
def update(self, status, namespace, operation, operation_name, details, progress, owner_href, owner_name, owner_type, user_href, user_name, org_href=None, task_href=None, error_message=None): t = E.Task( status=status, serviceNamespace=namespace, type=EntityType.TASK.value, operation=operation, operationName=operation_name, name='task') t.append(E.Owner(href=owner_href, name=owner_name, type=owner_type)) if error_message is not None: t.append( E.Error( stackTrace='', majorErrorCode='500', message=error_message, minorErrorCode='INTERNAL_SERVER_ERROR')) t.append( E.User(href=user_href, name=user_name, type=EntityType.USER.value)) if progress is not None: t.append(E.Progress(progress)) t.append(E.Details(details)) if task_href is None: org_resource = self.client.get_resource(org_href) link = find_link(org_resource, RelationType.DOWN, EntityType.TASKS_LIST.value) return self.client.post_resource(link.href, t, EntityType.TASK.value) else: return self.client.put_resource(task_href, t, EntityType.TASK.value)
def convert_access_settings_list_to_params(self, access_settings_list): """Convert access_settings_list to object of type AccessSettingsType :param access_settings_list: (list of dict): list of access_setting in the dict format. Each dict contains: type: (str): type of the subject. One of 'org' or 'user' name: (str): subject name access_level: (str): access_level of each subject. One of 'ReadOnly', 'Change', 'FullControl'. :return: A :class:`lxml.objectify.StringElement` object representing xml of type AccessSettingsType """ access_settings_params = E.AccessSettings() for access_setting in access_settings_list: if access_setting["type"] == 'user': org_href = find_link(self.parent_resource, RelationType.UP, EntityType.ORG.value).href subject_href = self.client.get_user_in_org( access_setting['name'], org_href).get('href') subject_type = EntityType.USER.value elif access_setting["type"] == 'org': subject_href = get_admin_href( self.client.get_org_by_name( access_setting['name']).get('href')) subject_type = EntityType.ADMIN_ORG.value else: raise Exception("Invalid subject type") subject_name = access_setting['name'] # Make 'ReadOnly' the default access_level if it is not specified. if 'access_level' in access_setting: access_level = access_setting['access_level'] else: access_level = 'ReadOnly' access_setting_params = E.AccessSetting( E.Subject(name=subject_name, href=subject_href, type=subject_type), E.AccessLevel(access_level)) access_settings_params.append(access_setting_params) return access_settings_params
def update(self, status, namespace, operation, operation_name, details, progress, owner_href, owner_name, owner_type, user_href, user_name, org_href=None, task_href=None, error_message=None): t = E.Task(status=status, serviceNamespace=namespace, type=EntityType.TASK.value, operation=operation, operationName=operation_name, name='task') t.append(E.Owner(href=owner_href, name=owner_name, type=owner_type)) if error_message is not None: t.append( E.Error(stackTrace='', majorErrorCode='500', message=error_message, minorErrorCode='INTERNAL_SERVER_ERROR')) t.append( E.User(href=user_href, name=user_name, type=EntityType.USER.value)) if progress is not None: t.append(E.Progress(progress)) t.append(E.Details(details)) if task_href is None: org_resource = self.client.get_resource(org_href) link = find_link(org_resource, RelationType.DOWN, EntityType.TASKS_LIST.value) return self.client.post_resource(link.href, t, EntityType.TASK.value) else: return self.client.put_resource(task_href, t, EntityType.TASK.value)
def get_org_name_of_ovdc(vdc_id): """Get org_name from vdc_id using OVDC_TO_ORG_MAP. Update OVDC_TO_ORG_MAP for new {org_name:vdc_id} pair :param vdc_id: unique ovdc id :return: org_name """ if vdc_id in OVDC_TO_ORG_MAP: org_name = OVDC_TO_ORG_MAP.get(vdc_id) else: client = get_vcd_sys_admin_client() vdc_href = f"{client._uri}/vdc/{vdc_id}" vdc_resource = client.get_resource(get_admin_href(vdc_href)) vdc_obj = VDC(client, resource=vdc_resource) link = find_link(vdc_obj.resource, RelationType.UP, EntityType.ADMIN_ORG.value) org = Org(client, href=link.href) '''Add the entry to the map to be used next time the \ same ovdc is requested''' OVDC_TO_ORG_MAP[vdc_id] = org.get_name() org_name = org.get_name() return org_name
def __init__(self, client, vapp_name=None, network_name=None, resource_href=None, resource=None): """Constructor for VappServices objects(DHCP,NAT,Firewall etc..). :param pyvcloud.vcd.client.Client client: the client that will be used to make REST calls to vCD. :param str vapp_name: name of the vapp entity. :param str network_name: name of the vapp network entity. :param str resource_href: Service href. :param lxml.objectify.ObjectifiedElement resource: object containing EntityType.Service XML data representing the Service. :raises: InvalidParameterException: Service Initialization failed as arguments are either invalid or None. """ self.client = client self.vapp_name = vapp_name if vapp_name is not None and network_name is not None and\ resource_href is None and resource is None: self.network_name = network_name self._build_self_href() if resource_href is None and resource is None and self.href is None: raise InvalidParameterException( "Service Initialization failed as arguments are either " "invalid or None") if resource_href is not None: self.resource_href = resource_href self.href = resource_href self._get_resource() self.parent_href = find_link(self.resource, RelationType.UP, EntityType.VAPP).href self.parent = self.client.get_resource(self.parent_href) self.resource = resource
def __init__(self, client): """Initialize ComputePolicyManager Object. :param pyvcloud.vcd.client client: :raises: OperationNotSupportedException: If cloudapi endpoint is not found in session. :raises: ValueError: If non sys admin client is passed during initialization. """ if not client.is_sysadmin(): raise ValueError("Only Sys admin clients should be used to " "initialize ComputePolicyManager.") self._vcd_client = client # TODO: pyvcloud should expose methods to grab the session and token # from a client object. auth_token = \ self._vcd_client._session.headers['x-vcloud-authorization'] # pyvcloud doesn't store the vCD session response in client. So we need # to get it from vCD. session = self._vcd_client.rehydrate_from_token(auth_token) # Ideally this information should be fetched from # client._session_endpoints. However pyvcloud client doesn't store # the cloudapi link, so we have to find it manually. try: link = find_link(session, RelationType.OPEN_API, EntityType.APPLICATION_JSON) except MissingLinkException: raise OperationNotSupportedException( "Cloudapi endpoint unavailable at current api version.") self._cloudapi_client = CloudApiClient( base_url=link.href, auth_token=auth_token, verify_ssl=self._vcd_client._verify_ssl_certs)
def instantiate_vapp(self, name, catalog, template, network=None, deploy=True, power_on=True): if self.vdc_resource is None: self.vdc_resource = self.client.get_resource(self.href) network_href = None if hasattr(self.vdc_resource, 'AvailableNetworks') and \ hasattr(self.vdc_resource.AvailableNetworks, 'Network'): for n in self.vdc_resource.AvailableNetworks.Network: if network is None or n.get('name') == network: network_href = n.get('href') if network_href is None: raise Exception('Network not found in the Virtual Datacenter.') # TODO(cache some of these objects here and in Org object) org_href = find_link(self.vdc_resource, RelationType.UP, EntityType.ORG.value).href org = Org(self.client, org_href) template_resource = org.get_catalog_item(catalog, template) v = self.client.get_resource(template_resource.Entity.get('href')) n = v.xpath( '//ovf:NetworkSection/ovf:Network', namespaces={'ovf': 'http://schemas.dmtf.org/ovf/envelope/1'}) network_name = n[0].get('{http://schemas.dmtf.org/ovf/envelope/1}name') deploy_param = 'true' if deploy else 'false' power_on_param = 'true' if power_on else 'false' vapp_template_params = Maker.InstantiateVAppTemplateParams( name=name, deploy=deploy_param, powerOn=power_on_param) vapp_template_params.append( Maker.InstantiationParams( Maker.NetworkConfigSection( OvfMaker.Info('Configuration for logical networks'), Maker.NetworkConfig( Maker.Configuration( Maker.ParentNetwork(href=network_href), Maker.FenceMode('bridged') ), # Maker.IsDeployed('true'), networkName=network_name ) ) ) ) vapp_template_params.append( Maker.Source(href=template_resource.Entity.get('href')) ) vm = v.xpath( '//vcloud:VAppTemplate/vcloud:Children/vcloud:Vm', namespaces=NSMAP) # for c in vm[0].NetworkConnectionSection.NetworkConnection: # c.remove(c.MACAddress) # # c.remove(c.IpAddressAllocationMode) # # tmp = c.NetworkAdapterType # # c.remove(c.NetworkAdapterType) # # c.append(Maker.IpAddressAllocationMode('POOL')) # # c.append(tmp) ip = Maker.InstantiationParams() # ip.append(vm[0].NetworkConnectionSection) gc = Maker.GuestCustomizationSection( OvfMaker.Info('Specifies Guest OS Customization Settings'), Maker.Enabled('false'), # Maker.AdminPasswordEnabled('false'), Maker.ComputerName(name) ) ip.append(gc) vapp_template_params.append( Maker.SourcedItem( Maker.Source(href=vm[0].get('href'), id=vm[0].get('id'), name=vm[0].get('name'), type=vm[0].get('type')), Maker.VmGeneralParams( Maker.Name(name), Maker.NeedsCustomization('false') ), ip ) ) # from lxml import etree # print(etree.tostring(vapp_template_params, pretty_print=True)) # return None return self.client.post_resource( self.href+'/action/instantiateVAppTemplate', vapp_template_params, EntityType.INSTANTIATE_VAPP_TEMPLATE_PARAMS.value)
def download_catalog_item(self, catalog_name, item_name, file_name, chunk_size=DEFAULT_CHUNK_SIZE, callback=None, task_callback=None): item = self.get_catalog_item(catalog_name, item_name) item_type = item.Entity.get('type') enable_href = item.Entity.get('href') + '/action/enableDownload' task = self.client.post_resource(enable_href, None, None) tm = _TaskMonitor(self.client) tm.wait_for_success(task, 60, 1, callback=task_callback) item = self.client.get_resource(item.Entity.get('href')) bytes_written = 0 if item_type == EntityType.MEDIA.value: size = item.Files.File.get('size') download_href = item.Files.File.Link.get('href') bytes_written = self.client.download_from_uri( download_href, file_name, chunk_size=chunk_size, size=size, callback=callback) elif item_type == EntityType.VAPP_TEMPLATE.value: ovf_descriptor = self.client.get_linked_resource( item, RelationType.DOWNLOAD_DEFAULT, EntityType.TEXT_XML.value) transfer_uri = find_link(item, RelationType.DOWNLOAD_DEFAULT, EntityType.TEXT_XML.value).href transfer_uri = transfer_uri.replace('/descriptor.ovf', '/') tempdir = None cwd = os.getcwd() try: tempdir = tempfile.mkdtemp(dir='.') ovf_file = os.path.join(tempdir, 'descriptor.ovf') with open(ovf_file, 'wb') as f: payload = etree.tostring( ovf_descriptor, pretty_print=True, xml_declaration=True, encoding='utf-8') f.write(payload) ns = '{' + NSMAP['ovf'] + '}' files = [] for f in ovf_descriptor.References.File: source_file = { 'href': f.get(ns + 'href'), 'name': f.get(ns + 'id'), 'size': f.get(ns + 'size') } target_file = os.path.join(tempdir, source_file['href']) uri = transfer_uri + source_file['href'] num_bytes = self.client.download_from_uri( uri, target_file, chunk_size=chunk_size, size=source_file['size'], callback=callback) if num_bytes != int(source_file['size']): raise Exception('download incomplete for file %s' % source_file['href']) files.append(source_file) with tarfile.open(file_name, 'w') as tar: os.chdir(tempdir) tar.add('descriptor.ovf') for f in files: tar.add(f['href']) finally: if tempdir is not None: os.chdir(cwd) stat_info = os.stat(file_name) bytes_written = stat_info.st_size return bytes_written
def instantiate_vapp(self, name, catalog, template, network=None, fence_mode='bridged', ip_allocation_mode='dhcp', deploy=True, power_on=True, accept_all_eulas=True, memory=None, cpu=None, password=None, cust_script=None, identical=False): """ Instantiate a vApp from a vApp template. :param name: (str): The name of the new vApp. :param catalog: (str): The name of the catalog. :param template: (str): The name of the vApp template. :param identical: (bool): If True, no guest customization or VM name update is performed :return: A :class:`lxml.objectify.StringElement` object describing the new vApp. """ # NOQA if self.resource is None: self.resource = self.client.get_resource(self.href) network_href = None if hasattr(self.resource, 'AvailableNetworks') and \ hasattr(self.resource.AvailableNetworks, 'Network'): for n in self.resource.AvailableNetworks.Network: if network is None or network == n.get('name'): network_href = n.get('href') network_name = n.get('name') if network_href is None: raise Exception('Network not found in the Virtual Datacenter.') org_href = find_link(self.resource, RelationType.UP, EntityType.ORG.value).href org = Org(self.client, href=org_href) template_resource = org.get_catalog_item(catalog, template) v = self.client.get_resource(template_resource.Entity.get('href')) n = v.xpath( '//ovf:NetworkSection/ovf:Network', namespaces={'ovf': 'http://schemas.dmtf.org/ovf/envelope/1'}) assert len(n) > 0 network_name_from_template = n[0].get( '{http://schemas.dmtf.org/ovf/envelope/1}name') deploy_param = 'true' if deploy else 'false' power_on_param = 'true' if power_on else 'false' network_configuration = E.Configuration( E.ParentNetwork(href=network_href), E.FenceMode(fence_mode)) # if fence_mode == 'natRouted': # network_configuration.append( # E.Features( # E.NatService( # E.IsEnabled('true'), # E.NatType('ipTranslation'), # E.Policy('allowTraffic'), # E.NatRule( # E.OneToOneVmRule( # E.MappingMode('automatic'), # E.VAppScopedVmId(vm_id), # E.VmNicId(0) # ) # ) # ) # ) # ) vapp_network_name = network_name_from_template if vapp_network_name == 'none': vapp_network_name = network_name vapp_template_params = E.InstantiateVAppTemplateParams( name=name, deploy=deploy_param, powerOn=power_on_param) if network_name is not None: vapp_template_params.append( E.InstantiationParams( E.NetworkConfigSection( E_OVF.Info('Configuration for logical networks'), E.NetworkConfig(network_configuration, networkName=vapp_network_name)))) vapp_template_params.append( E.Source(href=template_resource.Entity.get('href'))) vm = v.xpath('//vcloud:VAppTemplate/vcloud:Children/vcloud:Vm', namespaces=NSMAP) assert len(vm) > 0 ip = E.InstantiationParams() if not identical: gc = E.GuestCustomizationSection( E_OVF.Info('Specifies Guest OS Customization Settings'), E.Enabled('false'), ) if password is not None: gc.append(E.AdminPasswordEnabled('true')) gc.append(E.AdminPasswordAuto('false')) gc.append(E.AdminPassword(password)) gc.append(E.ResetPasswordRequired('false')) else: gc.append(E.AdminPasswordEnabled('false')) if cust_script is not None: gc.append(E.CustomizationScript(cust_script)) gc.Enabled = E.Enabled('true') gc.append(E.ComputerName(name)) ip.append(gc) primary_index = int( vm[0].NetworkConnectionSection.PrimaryNetworkConnectionIndex.text) ip.append( E.NetworkConnectionSection( E_OVF.Info('Specifies the available VM network connections'), E.NetworkConnection(E.NetworkConnectionIndex(primary_index), E.IsConnected('true'), E.IpAddressAllocationMode( ip_allocation_mode.upper()), network=vapp_network_name))) if memory is not None: items = v.Children[0].Vm.xpath( '//ovf:VirtualHardwareSection/ovf:Item', namespaces={'ovf': 'http://schemas.dmtf.org/ovf/envelope/1'}) for item in items: if item['{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}ResourceType'] == 4: # NOQA item[ '{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}ElementName'] = '%s MB of memory' % memory # NOQA item[ '{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}VirtualQuantity'] = memory # NOQA memory_params = item break if cpu is not None: items = v.Children[0].Vm.xpath( '//ovf:VirtualHardwareSection/ovf:Item', namespaces={'ovf': 'http://schemas.dmtf.org/ovf/envelope/1'}) for item in items: if item['{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}ResourceType'] == 3: # NOQA item[ '{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}ElementName'] = '%s virtual CPU(s)' % cpu # NOQA item[ '{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}VirtualQuantity'] = cpu # NOQA cpu_params = item break if memory is not None or cpu is not None: vhs = E_OVF.VirtualHardwareSection( E_OVF.Info('Virtual hardware requirements')) if memory is not None: vhs.append(memory_params) if cpu is not None: vhs.append(cpu_params) ip.append(vhs) if identical or (password is None and cust_script is None): needs_customization = 'false' else: needs_customization = 'true' si = E.SourcedItem( E.Source(href=vm[0].get('href'), id=vm[0].get('id'), name=vm[0].get('name'), type=vm[0].get('type'))) if not identical: si.append( E.VmGeneralParams(E.Name(name), E.NeedsCustomization(needs_customization))) si.append(ip) # if network_name != network_name_from_template: # si.append(E.NetworkAssignment( # innerNetwork=network_name_from_template, # containerNetwork=network_name)) vapp_template_params.append(si) all_eulas_accepted = 'true' if accept_all_eulas else 'false' vapp_template_params.append(E.AllEULAsAccepted(all_eulas_accepted)) return self.client.post_resource( self.href + '/action/instantiateVAppTemplate', vapp_template_params, EntityType.INSTANTIATE_VAPP_TEMPLATE_PARAMS.value)
def test_0000_setup(self): """Setup the gateway required for the other tests in this module. Create a gateway as per the configuration stated above. This test passes if the gateway is created successfully. """ TestGateway._client = Environment.get_sys_admin_client() TestGateway._vdc = Environment.get_test_vdc(TestGateway._client) TestGateway._org_client = Environment.get_client_in_default_org( CommonRoles.ORGANIZATION_ADMINISTRATOR) TestGateway._config = Environment.get_config() TestGateway._api_version = TestGateway._config['vcd']['api_version'] external_network = Environment.get_test_external_network( TestGateway._client) ext_net_resource = external_network.get_resource() ip_scopes = ext_net_resource.xpath( 'vcloud:Configuration/vcloud:IpScopes/vcloud:IpScope', namespaces=NSMAP) first_ipscope = ip_scopes[0] gateway_ip = first_ipscope.Gateway.text prefix_len = netmask_to_cidr_prefix_len(gateway_ip, first_ipscope.Netmask.text) subnet_addr = gateway_ip + '/' + str(prefix_len) ext_net_to_participated_subnet_with_ip_settings = { ext_net_resource.get('name'): { subnet_addr: 'Auto' } } gateway_ip_arr = gateway_ip.split('.') last_ip_digit = int(gateway_ip_arr[-1]) + 1 gateway_ip_arr[-1] = str(last_ip_digit) next_ip = '.'.join(gateway_ip_arr) ext_net_to_subnet_with_ip_range = { ext_net_resource.get('name'): { subnet_addr: [next_ip + '-' + next_ip] } } ext_net_to_rate_limit = {ext_net_resource.get('name'): {100: 100}} if float(TestGateway._api_version) <= float( ApiVersion.VERSION_30.value): TestGateway._gateway = \ TestGateway._vdc.create_gateway_api_version_30( self._name, [ext_net_resource.get('name')], 'compact', None, True, ext_net_resource.get('name'), gateway_ip, True, False, False, False, True, ext_net_to_participated_subnet_with_ip_settings, True, ext_net_to_subnet_with_ip_range, ext_net_to_rate_limit) elif float(TestGateway._api_version) == float( ApiVersion.VERSION_31.value): TestGateway._gateway = \ TestGateway._vdc.create_gateway_api_version_31( self._name, [ext_net_resource.get('name')], 'compact', None, True, ext_net_resource.get('name'), gateway_ip, True, False, False, False, True, ext_net_to_participated_subnet_with_ip_settings, True, ext_net_to_subnet_with_ip_range, ext_net_to_rate_limit) elif float(TestGateway._api_version) >= float( ApiVersion.VERSION_32.value): TestGateway._gateway = \ TestGateway._vdc.create_gateway_api_version_32( self._name, [ext_net_resource.get('name')], 'compact', None, True, ext_net_resource.get('name'), gateway_ip, True, False, False, False, True, ext_net_to_participated_subnet_with_ip_settings, True, ext_net_to_subnet_with_ip_range, ext_net_to_rate_limit) result = TestGateway._client.get_task_monitor().wait_for_success( task=TestGateway._gateway.Tasks.Task) self.assertEqual(result.get('status'), TaskStatus.SUCCESS.value) TestGateway._extension = Extension(TestGateway._client) TestGateway._extension.get_resource() link = find_link(TestGateway._extension.resource, RelationType.DOWN, EntityType.SYSTEM_SETTINGS.value) settings = TestGateway._client.get_resource(link.href) syslog_server_settings = settings.GeneralSettings.SyslogServerSettings if hasattr(syslog_server_settings, '{' + NSMAP['vcloud'] + '}SyslogServerIp1'): return syslog_server_settings.append( E.SyslogServerIp1(TestGateway._syslog_server_ip1)) TestGateway._client.put_resource(link.href, settings, EntityType.SYSTEM_SETTINGS.value) TestGateway._extension.reload() settings = TestGateway._client.get_resource(link.href) self.assertTrue( hasattr(syslog_server_settings, '{' + NSMAP['vcloud'] + '}SyslogServerIp1'))
def instantiate_vapp(self, name, catalog, template, network=None, fence_mode='bridged', ip_allocation_mode='dhcp', deploy=True, power_on=True, accept_all_eulas=False, memory=None, cpu=None, disk_size=None, password=None, cust_script=None, vm_name=None, hostname=None, storage_profile=None): """Instantiate a vApp from a vApp template in a catalog. If customization parameters are provided, it will customize the VM and guest OS, taking some assumptions. See each parameter for details. :param name: (str): The name of the new vApp. :param catalog: (str): The name of the catalog. :param template: (str): The name of the vApp template. :param network: (str): The name of a vdc network. When provided, connects the VM to the network. It assumes one VM in the vApp and one NIC in the VM. :param fence_mode: (str): Fence mode. Possible values are `bridged` and `natRouted` :param ip_allocation_mode: (str): IP allocation mode. Possible values are `pool`, `dhcp` and `static` :param deploy: (bool): :param power_on: (bool): :param accept_all_eulas: (bool): True confirms acceptance of all EULAs in a vApp template. :param memory: (int): :param cpu: (int): :param disk_size: (int): :param password: (str): :param cust_script: (str): :param vm_name: (str): When provided, set the name of the VM. It assumes one VM in the vApp. :param hostname: (str): When provided, set the hostname of the guest OS. It assumes one VM in the vApp. :param storage_profile: (str): :return: A :class:`lxml.objectify.StringElement` object describing the new vApp. """ if self.resource is None: self.resource = self.client.get_resource(self.href) # Get hold of the template org_href = find_link(self.resource, RelationType.UP, EntityType.ORG.value).href org = Org(self.client, href=org_href) catalog_item = org.get_catalog_item(catalog, template) template_resource = self.client.get_resource( catalog_item.Entity.get('href')) # If network is not specified by user then default to # vApp network name specified in the template template_networks = template_resource.xpath( '//ovf:NetworkSection/ovf:Network', namespaces={ 'ovf': NSMAP['ovf'] }) assert len(template_networks) > 0 network_name_from_template = template_networks[0].get( '{' + NSMAP['ovf'] + '}name') if ((network is None) and (network_name_from_template != 'none')): network = network_name_from_template # Find the network in vdc referred to by user, using # name of the network network_href = network_name = None if network is not None: if hasattr(self.resource, 'AvailableNetworks') and \ hasattr(self.resource.AvailableNetworks, 'Network'): for n in self.resource.AvailableNetworks.Network: if network == n.get('name'): network_href = n.get('href') network_name = n.get('name') break if network_href is None: raise Exception( 'Network \'%s\' not found in the Virtual Datacenter.' % network) # Configure the network of the vApp vapp_instantiation_param = None if network_name is not None: network_configuration = E.Configuration( E.ParentNetwork(href=network_href), E.FenceMode(fence_mode)) if fence_mode == 'natRouted': # TODO(need to find the vm_id) vm_id = None network_configuration.append( E.Features( E.NatService( E.IsEnabled('true'), E.NatType('ipTranslation'), E.Policy('allowTraffic'), E.NatRule( E.OneToOneVmRule( E.MappingMode('automatic'), E.VAppScopedVmId(vm_id), E.VmNicId(0)))))) vapp_instantiation_param = E.InstantiationParams( E.NetworkConfigSection( E_OVF.Info('Configuration for logical networks'), E.NetworkConfig( network_configuration, networkName=network_name))) # Get all vms in the vapp template vms = template_resource.xpath( '//vcloud:VAppTemplate/vcloud:Children/vcloud:Vm', namespaces=NSMAP) assert len(vms) > 0 vm_instantiation_param = E.InstantiationParams() # Configure network of the first vm if network_name is not None: primary_index = int(vms[ 0].NetworkConnectionSection.PrimaryNetworkConnectionIndex.text) vm_instantiation_param.append( E.NetworkConnectionSection( E_OVF.Info( 'Specifies the available VM network connections'), E.NetworkConnection( E.NetworkConnectionIndex(primary_index), E.IsConnected('true'), E.IpAddressAllocationMode(ip_allocation_mode.upper()), network=network_name))) # Configure cpu, memory, disk of the first vm cpu_params = memory_params = disk_params = None if memory is not None or cpu is not None or disk_size is not None: virtual_hardware_section = E_OVF.VirtualHardwareSection( E_OVF.Info('Virtual hardware requirements')) items = vms[0].xpath( '//ovf:VirtualHardwareSection/ovf:Item', namespaces={ 'ovf': NSMAP['ovf'] }) for item in items: if memory is not None and memory_params is None: if item['{' + NSMAP['rasd'] + '}ResourceType'] == 4: item['{' + NSMAP['rasd'] + '}ElementName'] = '%s MB of memory' % memory item['{' + NSMAP['rasd'] + '}VirtualQuantity'] = memory memory_params = item virtual_hardware_section.append(memory_params) if cpu is not None and cpu_params is None: if item['{' + NSMAP['rasd'] + '}ResourceType'] == 3: item['{' + NSMAP['rasd'] + '}ElementName'] = '%s virtual CPU(s)' % cpu item['{' + NSMAP['rasd'] + '}VirtualQuantity'] = cpu cpu_params = item virtual_hardware_section.append(cpu_params) if disk_size is not None and disk_params is None: if item['{' + NSMAP['rasd'] + '}ResourceType'] == 17: item['{' + NSMAP['rasd'] + '}Parent'] = None item['{' + NSMAP['rasd'] + '}HostResource'].attrib[ '{' + NSMAP['vcloud'] + '}capacity'] = '%s' % disk_size item['{' + NSMAP['rasd'] + '}VirtualQuantity'] = disk_size * 1024 * 1024 disk_params = item virtual_hardware_section.append(disk_params) vm_instantiation_param.append(virtual_hardware_section) # Configure guest customization for the vm if password is not None or cust_script is not None or \ hostname is not None: guest_customization_param = E.GuestCustomizationSection( E_OVF.Info('Specifies Guest OS Customization Settings'), E.Enabled('true'), ) if password is None: guest_customization_param.append( E.AdminPasswordEnabled('false')) else: guest_customization_param.append( E.AdminPasswordEnabled('true')) guest_customization_param.append(E.AdminPasswordAuto('false')) guest_customization_param.append(E.AdminPassword(password)) guest_customization_param.append( E.ResetPasswordRequired('false')) if cust_script is not None: guest_customization_param.append( E.CustomizationScript(cust_script)) if hostname is not None: guest_customization_param.append(E.ComputerName(hostname)) vm_instantiation_param.append(guest_customization_param) # Craft the <SourcedItem> element for the first VM sourced_item = E.SourcedItem( E.Source( href=vms[0].get('href'), id=vms[0].get('id'), name=vms[0].get('name'), type=vms[0].get('type'))) vm_general_params = E.VmGeneralParams() if vm_name is not None: vm_general_params.append(E.Name(vm_name)) # TODO(check if it needs customization if network, cpu or memory...) if disk_size is None and \ password is None and \ cust_script is None and \ hostname is None: needs_customization = 'false' else: needs_customization = 'true' vm_general_params.append(E.NeedsCustomization(needs_customization)) sourced_item.append(vm_general_params) sourced_item.append(vm_instantiation_param) if storage_profile is not None: sp = self.get_storage_profile(storage_profile) vapp_storage_profile = E.StorageProfile( href=sp.get('href'), id=sp.get('href').split('/')[-1], type=sp.get('type'), name=sp.get('name')) sourced_item.append(vapp_storage_profile) # Cook the entire vApp Template instantiation element deploy_param = 'true' if deploy else 'false' power_on_param = 'true' if power_on else 'false' all_eulas_accepted = 'true' if accept_all_eulas else 'false' vapp_template_params = E.InstantiateVAppTemplateParams( name=name, deploy=deploy_param, powerOn=power_on_param) if vapp_instantiation_param is not None: vapp_template_params.append(vapp_instantiation_param) vapp_template_params.append( E.Source(href=catalog_item.Entity.get('href'))) vapp_template_params.append(sourced_item) vapp_template_params.append(E.AllEULAsAccepted(all_eulas_accepted)) # TODO(use post_linked_resource?) return self.client.post_resource( self.href + '/action/instantiateVAppTemplate', vapp_template_params, EntityType.INSTANTIATE_VAPP_TEMPLATE_PARAMS.value)
def update(self, status, namespace, operation, operation_name, details, progress, owner_href, owner_name, owner_type, user_href, user_name, org_href=None, task_href=None, error_message=None, stack_trace=''): """Update a task in vCD. :param str status: new status of the task. :param str namespace: identifier of the service that created the task. It must not start with com.vmware.vcloud and the length must be between 1 and 128 symbols. :param str operation: new message describing the operation that is being tracked by this task. :param str operation_name: new short name of the operation that is being tracked by the task. :param details: new detailed message about the task. :param str progress: read-only indicator of task progress as an approximate percentage between 0 and 100. Not available for all tasks. :param str owner_href: href of the owner of the task. This is typically the object that the task is creating or updating. :param str owner_name: name of the owner of the task. :param str owner_type: XML type of the owner object :param str user_href: href of the user who started the task. :param str user_name: name of the user who started the task. :param str org_href: href of the organization, which the user mentioned above belongs to. :param str task_href: href of the task. :param str error_message: represents error information from a failed task. :param str stack_trace: stack trace of the error message from a failed task. :return: an object containing EntityType.TASK XML data representing the updated task. :rtype: lxml.objectify.ObjectifiedElement """ t = E.Task( status=status, serviceNamespace=namespace, type=EntityType.TASK.value, operation=operation, operationName=operation_name, name='task') t.append(E.Owner(href=owner_href, name=owner_name, type=owner_type)) if error_message is not None: t.append( E.Error( stackTrace=stack_trace, majorErrorCode='500', message=error_message, minorErrorCode='INTERNAL_SERVER_ERROR')) t.append( E.User(href=user_href, name=user_name, type=EntityType.USER.value)) if progress is not None: t.append(E.Progress(progress)) t.append(E.Details(details)) if task_href is None: org_resource = self.client.get_resource(org_href) link = find_link(org_resource, RelationType.DOWN, EntityType.TASKS_LIST.value) return self.client.post_resource(link.href, t, EntityType.TASK.value) else: return self.client.put_resource(task_href, t, EntityType.TASK.value)
def instantiate_vapp(self, name, catalog, template, network=None, fence_mode=FenceMode.BRIDGED.value, ip_allocation_mode='dhcp', deploy=True, power_on=True, accept_all_eulas=False, memory=None, cpu=None, disk_size=None, password=None, cust_script=None, vm_name=None, hostname=None, storage_profile=None): """Instantiate a vApp from a vApp template in a catalog. If customization parameters are provided, it will customize the VM and guest OS, taking some assumptions. See each parameter for details. :param name: (str): The name of the new vApp. :param catalog: (str): The name of the catalog. :param template: (str): The name of the vApp template. :param network: (str): The name of a vdc network. When provided, connects the VM to the network. It assumes one VM in the vApp and one NIC in the VM. :param fence_mode: (str): Fence mode. Possible values are `bridged` and `natRouted` :param ip_allocation_mode: (str): IP allocation mode. Possible values are `pool`, `dhcp` and `static` :param deploy: (bool): :param power_on: (bool): :param accept_all_eulas: (bool): True confirms acceptance of all EULAs in a vApp template. :param memory: (int): :param cpu: (int): :param disk_size: (int): :param password: (str): :param cust_script: (str): :param vm_name: (str): When provided, set the name of the VM. It assumes one VM in the vApp. :param hostname: (str): When provided, set the hostname of the guest OS. It assumes one VM in the vApp. :param storage_profile: (str): :return: A :class:`lxml.objectify.StringElement` object describing the new vApp. """ if self.resource is None: self.resource = self.client.get_resource(self.href) # Get hold of the template org_href = find_link(self.resource, RelationType.UP, EntityType.ORG.value).href org = Org(self.client, href=org_href) catalog_item = org.get_catalog_item(catalog, template) template_resource = self.client.get_resource( catalog_item.Entity.get('href')) # If network is not specified by user then default to # vApp network name specified in the template template_networks = template_resource.xpath( '//ovf:NetworkSection/ovf:Network', namespaces={'ovf': NSMAP['ovf']}) assert len(template_networks) > 0 network_name_from_template = template_networks[0].get('{' + NSMAP['ovf'] + '}name') if ((network is None) and (network_name_from_template != 'none')): network = network_name_from_template # Find the network in vdc referred to by user, using # name of the network network_href = network_name = None if network is not None: if hasattr(self.resource, 'AvailableNetworks') and \ hasattr(self.resource.AvailableNetworks, 'Network'): for n in self.resource.AvailableNetworks.Network: if network == n.get('name'): network_href = n.get('href') network_name = n.get('name') break if network_href is None: raise Exception( 'Network \'%s\' not found in the Virtual Datacenter.' % network) # Configure the network of the vApp vapp_instantiation_param = None if network_name is not None: network_configuration = E.Configuration( E.ParentNetwork(href=network_href), E.FenceMode(fence_mode)) if fence_mode == 'natRouted': # TODO(need to find the vm_id) vm_id = None network_configuration.append( E.Features( E.NatService( E.IsEnabled('true'), E.NatType('ipTranslation'), E.Policy('allowTraffic'), E.NatRule( E.OneToOneVmRule(E.MappingMode('automatic'), E.VAppScopedVmId(vm_id), E.VmNicId(0)))))) vapp_instantiation_param = E.InstantiationParams( E.NetworkConfigSection( E_OVF.Info('Configuration for logical networks'), E.NetworkConfig(network_configuration, networkName=network_name))) # Get all vms in the vapp template vms = template_resource.xpath( '//vcloud:VAppTemplate/vcloud:Children/vcloud:Vm', namespaces=NSMAP) assert len(vms) > 0 vm_instantiation_param = E.InstantiationParams() # Configure network of the first vm if network_name is not None: primary_index = int(vms[0].NetworkConnectionSection. PrimaryNetworkConnectionIndex.text) vm_instantiation_param.append( E.NetworkConnectionSection( E_OVF.Info( 'Specifies the available VM network connections'), E.NetworkConnection( E.NetworkConnectionIndex(primary_index), E.IsConnected('true'), E.IpAddressAllocationMode(ip_allocation_mode.upper()), network=network_name))) # Configure cpu, memory, disk of the first vm cpu_params = memory_params = disk_params = None if memory is not None or cpu is not None or disk_size is not None: virtual_hardware_section = E_OVF.VirtualHardwareSection( E_OVF.Info('Virtual hardware requirements')) items = vms[0].xpath('//ovf:VirtualHardwareSection/ovf:Item', namespaces={'ovf': NSMAP['ovf']}) for item in items: if memory is not None and memory_params is None: if item['{' + NSMAP['rasd'] + '}ResourceType'] == 4: item['{' + NSMAP['rasd'] + '}ElementName'] = '%s MB of memory' % memory item['{' + NSMAP['rasd'] + '}VirtualQuantity'] = memory memory_params = item virtual_hardware_section.append(memory_params) if cpu is not None and cpu_params is None: if item['{' + NSMAP['rasd'] + '}ResourceType'] == 3: item['{' + NSMAP['rasd'] + '}ElementName'] = '%s virtual CPU(s)' % cpu item['{' + NSMAP['rasd'] + '}VirtualQuantity'] = cpu cpu_params = item virtual_hardware_section.append(cpu_params) if disk_size is not None and disk_params is None: if item['{' + NSMAP['rasd'] + '}ResourceType'] == 17: item['{' + NSMAP['rasd'] + '}Parent'] = None item['{' + NSMAP['rasd'] + '}HostResource'].attrib[ '{' + NSMAP['vcloud'] + '}capacity'] = '%s' % disk_size item['{' + NSMAP['rasd'] + '}VirtualQuantity'] = disk_size * 1024 * 1024 disk_params = item virtual_hardware_section.append(disk_params) vm_instantiation_param.append(virtual_hardware_section) # Configure guest customization for the vm if password is not None or cust_script is not None or \ hostname is not None: guest_customization_param = E.GuestCustomizationSection( E_OVF.Info('Specifies Guest OS Customization Settings'), E.Enabled('true'), ) if password is None: guest_customization_param.append( E.AdminPasswordEnabled('false')) else: guest_customization_param.append( E.AdminPasswordEnabled('true')) guest_customization_param.append(E.AdminPasswordAuto('false')) guest_customization_param.append(E.AdminPassword(password)) guest_customization_param.append( E.ResetPasswordRequired('false')) if cust_script is not None: guest_customization_param.append( E.CustomizationScript(cust_script)) if hostname is not None: guest_customization_param.append(E.ComputerName(hostname)) vm_instantiation_param.append(guest_customization_param) # Craft the <SourcedItem> element for the first VM sourced_item = E.SourcedItem( E.Source(href=vms[0].get('href'), id=vms[0].get('id'), name=vms[0].get('name'), type=vms[0].get('type'))) vm_general_params = E.VmGeneralParams() if vm_name is not None: vm_general_params.append(E.Name(vm_name)) # TODO(check if it needs customization if network, cpu or memory...) if disk_size is None and \ password is None and \ cust_script is None and \ hostname is None: needs_customization = 'false' else: needs_customization = 'true' vm_general_params.append(E.NeedsCustomization(needs_customization)) sourced_item.append(vm_general_params) sourced_item.append(vm_instantiation_param) if storage_profile is not None: sp = self.get_storage_profile(storage_profile) vapp_storage_profile = E.StorageProfile( href=sp.get('href'), id=sp.get('href').split('/')[-1], type=sp.get('type'), name=sp.get('name')) sourced_item.append(vapp_storage_profile) # Cook the entire vApp Template instantiation element deploy_param = 'true' if deploy else 'false' power_on_param = 'true' if power_on else 'false' all_eulas_accepted = 'true' if accept_all_eulas else 'false' vapp_template_params = E.InstantiateVAppTemplateParams( name=name, deploy=deploy_param, powerOn=power_on_param) if vapp_instantiation_param is not None: vapp_template_params.append(vapp_instantiation_param) vapp_template_params.append( E.Source(href=catalog_item.Entity.get('href'))) vapp_template_params.append(sourced_item) vapp_template_params.append(E.AllEULAsAccepted(all_eulas_accepted)) # TODO(use post_linked_resource?) return self.client.post_resource( self.href + '/action/instantiateVAppTemplate', vapp_template_params, EntityType.INSTANTIATE_VAPP_TEMPLATE_PARAMS.value)
def instantiate_vapp(self, name, catalog, template, network=None, fence_mode='bridged', deploy=True, power_on=True, accept_all_eulas=True, memory=None, cpu=None): if self.vdc_resource is None: self.vdc_resource = self.client.get_resource(self.href) network_href = None if hasattr(self.vdc_resource, 'AvailableNetworks') and \ hasattr(self.vdc_resource.AvailableNetworks, 'Network'): for n in self.vdc_resource.AvailableNetworks.Network: if network is None or n.get('name') == network: network_href = n.get('href') if network_href is None: raise Exception('Network not found in the Virtual Datacenter.') # TODO(cache some of these objects here and in Org object) org_href = find_link(self.vdc_resource, RelationType.UP, EntityType.ORG.value).href org = Org(self.client, org_href) template_resource = org.get_catalog_item(catalog, template) v = self.client.get_resource(template_resource.Entity.get('href')) n = v.xpath( '//ovf:NetworkSection/ovf:Network', namespaces={'ovf': 'http://schemas.dmtf.org/ovf/envelope/1'}) network_name = n[0].get('{http://schemas.dmtf.org/ovf/envelope/1}name') vm_id = v.Children[0].Vm.VAppScopedLocalId.text deploy_param = 'true' if deploy else 'false' power_on_param = 'true' if power_on else 'false' network_configuration = Maker.Configuration( Maker.ParentNetwork(href=network_href), Maker.FenceMode(fence_mode)) if fence_mode == 'natRouted': # network_name = network network_configuration.append( Maker.Features( Maker.NatService( Maker.IsEnabled('true'), Maker.NatType('ipTranslation'), Maker.Policy('allowTraffic'), Maker.NatRule( Maker.OneToOneVmRule( Maker.MappingMode('automatic'), Maker.VAppScopedVmId(vm_id), Maker.VmNicId(0)))))) vapp_template_params = Maker.InstantiateVAppTemplateParams( name=name, deploy=deploy_param, powerOn=power_on_param) vapp_template_params.append( Maker.InstantiationParams( Maker.NetworkConfigSection( E_OVFENV.Info('Configuration for logical networks'), Maker.NetworkConfig(network_configuration, networkName=network_name)))) vapp_template_params.append( Maker.Source(href=template_resource.Entity.get('href'))) vm = v.xpath('//vcloud:VAppTemplate/vcloud:Children/vcloud:Vm', namespaces=NSMAP) # for c in vm[0].NetworkConnectionSection.NetworkConnection: # c.remove(c.MACAddress) # # c.remove(c.IpAddressAllocationMode) # # tmp = c.NetworkAdapterType # # c.remove(c.NetworkAdapterType) # # c.append(Maker.IpAddressAllocationMode('POOL')) # # c.append(tmp) ip = Maker.InstantiationParams() # ip.append(vm[0].NetworkConnectionSection) gc = Maker.GuestCustomizationSection( E_OVFENV.Info('Specifies Guest OS Customization Settings'), Maker.Enabled('false'), # Maker.AdminPasswordEnabled('false'), Maker.ComputerName(name)) ip.append(gc) if memory is not None: items = v.Children[0].Vm.xpath( '//ovf:VirtualHardwareSection/ovf:Item', namespaces={'ovf': 'http://schemas.dmtf.org/ovf/envelope/1'}) for item in items: if item['{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}ResourceType'] == 4: # NOQA item[ '{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}ElementName'] = '%s MB of memory' % memory # NOQA item[ '{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}VirtualQuantity'] = memory # NOQA memory_params = item break if cpu is not None: items = v.Children[0].Vm.xpath( '//ovf:VirtualHardwareSection/ovf:Item', namespaces={'ovf': 'http://schemas.dmtf.org/ovf/envelope/1'}) for item in items: if item['{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}ResourceType'] == 3: # NOQA item[ '{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}ElementName'] = '%s virtual CPU(s)' % cpu # NOQA item[ '{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}VirtualQuantity'] = cpu # NOQA cpu_params = item break if memory is not None or cpu is not None: vhs = E_OVFENV.VirtualHardwareSection( E_OVFENV.Info('Virtual hardware requirements')) if memory is not None: vhs.append(memory_params) if cpu is not None: vhs.append(cpu_params) ip.append(vhs) all_eulas_accepted = 'true' if accept_all_eulas else 'false' vapp_template_params.append( Maker.SourcedItem( Maker.Source(href=vm[0].get('href'), id=vm[0].get('id'), name=vm[0].get('name'), type=vm[0].get('type')), Maker.VmGeneralParams(Maker.Name(name), Maker.NeedsCustomization('false')), ip)) vapp_template_params.append(Maker.AllEULAsAccepted(all_eulas_accepted)) return self.client.post_resource( self.href + '/action/instantiateVAppTemplate', vapp_template_params, EntityType.INSTANTIATE_VAPP_TEMPLATE_PARAMS.value)
def test_0000_setup(self): """Setup the gateway required for the other tests in this module. Create a gateway as per the configuration stated above. This test passes if the gateway is created successfully. """ TestGateway._client = Environment.get_sys_admin_client() TestGateway._vdc = Environment.get_test_vdc(TestGateway._client) TestGateway._org_client = Environment.get_client_in_default_org( CommonRoles.ORGANIZATION_ADMINISTRATOR) TestGateway._config = Environment.get_config() TestGateway._api_version = TestGateway._config['vcd']['api_version'] external_network = Environment.get_test_external_network( TestGateway._client) ext_net_resource = external_network.get_resource() ip_scopes = ext_net_resource.xpath( 'vcloud:Configuration/vcloud:IpScopes/vcloud:IpScope', namespaces=NSMAP) first_ipscope = ip_scopes[0] gateway_ip = first_ipscope.Gateway.text prefix_len = netmask_to_cidr_prefix_len(gateway_ip, first_ipscope.Netmask.text) subnet_addr = gateway_ip + '/' + str(prefix_len) ext_net_to_participated_subnet_with_ip_settings = { ext_net_resource.get('name'): { subnet_addr: self._ip_address_for_config_ip_setting } } ext_net_to_subnet_with_ip_range = { ext_net_resource.get('name'): { subnet_addr: [self._ip_address_for_ip_range] } } ext_net_to_rate_limit = {ext_net_resource.get('name'): {100: 100}} if float(TestGateway._api_version) <= float( ApiVersion.VERSION_30.value): TestGateway._gateway = \ TestGateway._vdc.create_gateway_api_version_30( self._name, [ext_net_resource.get('name')], 'compact', None, True, ext_net_resource.get('name'), gateway_ip, True, False, False, False, True, ext_net_to_participated_subnet_with_ip_settings, True, ext_net_to_subnet_with_ip_range, ext_net_to_rate_limit) elif float(TestGateway._api_version) == float( ApiVersion.VERSION_31.value): TestGateway._gateway = \ TestGateway._vdc.create_gateway_api_version_31( self._name, [ext_net_resource.get('name')], 'compact', None, True, ext_net_resource.get('name'), gateway_ip, True, False, False, False, True, ext_net_to_participated_subnet_with_ip_settings, True, ext_net_to_subnet_with_ip_range, ext_net_to_rate_limit) elif float(TestGateway._api_version) >= float( ApiVersion.VERSION_32.value): TestGateway._gateway = \ TestGateway._vdc.create_gateway_api_version_32( self._name, [ext_net_resource.get('name')], 'compact', None, True, ext_net_resource.get('name'), gateway_ip, True, False, False, False, True, ext_net_to_participated_subnet_with_ip_settings, True, ext_net_to_subnet_with_ip_range, ext_net_to_rate_limit) result = TestGateway._client.get_task_monitor().wait_for_success( task=TestGateway._gateway.Tasks.Task) self.assertEqual(result.get('status'), TaskStatus.SUCCESS.value) TestGateway._extension = Extension(TestGateway._client) TestGateway._extension.get_resource() link = find_link(TestGateway._extension.resource, RelationType.DOWN, EntityType.SYSTEM_SETTINGS.value) settings = TestGateway._client.get_resource(link.href) syslog_server_settings = settings.GeneralSettings.SyslogServerSettings if hasattr(syslog_server_settings, '{' + NSMAP['vcloud'] + '}SyslogServerIp1'): return syslog_server_settings.append( E.SyslogServerIp1(TestGateway._syslog_server_ip1)) TestGateway._client.put_resource(link.href, settings, EntityType.SYSTEM_SETTINGS.value) TestGateway._extension.reload() settings = TestGateway._client.get_resource(link.href) self.assertTrue( hasattr(syslog_server_settings, '{' + NSMAP['vcloud'] + '}SyslogServerIp1'))
def download_catalog_item(self, catalog_name, item_name, file_name, chunk_size=DEFAULT_CHUNK_SIZE, callback=None, task_callback=None): item = self.get_catalog_item(catalog_name, item_name) item_type = item.Entity.get('type') enable_href = item.Entity.get('href') + '/action/enableDownload' task = self.client.post_resource(enable_href, None, None) tm = _TaskMonitor(self.client) tm.wait_for_success(task, 60, 1, callback=task_callback) item = self.client.get_resource(item.Entity.get('href')) bytes_written = 0 if item_type == EntityType.MEDIA.value: size = item.Files.File.get('size') download_href = item.Files.File.Link.get('href') bytes_written = self.client.download_from_uri( download_href, file_name, chunk_size=chunk_size, size=size, callback=callback) elif item_type == EntityType.VAPP_TEMPLATE.value: ovf_descriptor = self.client.get_linked_resource( item, RelationType.DOWNLOAD_DEFAULT, EntityType.TEXT_XML.value) transfer_uri = find_link(item, RelationType.DOWNLOAD_DEFAULT, EntityType.TEXT_XML.value).href transfer_uri = transfer_uri.replace('/descriptor.ovf', '/') tempdir = None cwd = os.getcwd() try: tempdir = tempfile.mkdtemp(dir='.') ovf_file = os.path.join(tempdir, 'descriptor.ovf') with open(ovf_file, 'wb') as f: payload = etree.tostring(ovf_descriptor, pretty_print=True, xml_declaration=True, encoding='utf-8') f.write(payload) ns = '{http://schemas.dmtf.org/ovf/envelope/1}' files = [] for f in ovf_descriptor.References.File: source_file = { 'href': f.get(ns + 'href'), 'name': f.get(ns + 'id'), 'size': f.get(ns + 'size') } target_file = os.path.join(tempdir, source_file['href']) uri = transfer_uri + source_file['href'] num_bytes = self.client.download_from_uri( uri, target_file, chunk_size=chunk_size, size=source_file['size'], callback=callback) if num_bytes != source_file['size']: raise Exception('download incomplete for file %s' % source_file['href']) files.append(source_file) with tarfile.open(file_name, 'w') as tar: os.chdir(tempdir) tar.add('descriptor.ovf') for f in files: tar.add(f['href']) finally: if tempdir is not None: os.chdir(cwd) stat_info = os.stat(file_name) bytes_written = stat_info.st_size # shutil.rmtree(tempdir) return bytes_written
def update(self, status, namespace, operation, operation_name, details, progress, owner_href, owner_name, owner_type, user_href, user_name, org_href=None, task_href=None, error_message=None): """Update a task in vCD. :param str status: new status of the task. :param str namespace: identifier of the service that created the task. It must not start with com.vmware.vcloud and the length must be between 1 and 128 symbols. :param str operation: new message describing the operation that is being tracked by this task. :param str operation_name: new short name of the operation that is being tracked by the task. :param details: new detailed message about the task. :param str progress: read-only indicator of task progress as an approximate percentage between 0 and 100. Not available for all tasks. :param str owner_href: href of the owner of the task. This is typically the object that the task is creating or updating. :param str owner_name: name of the owner of the task. :param str owner_type: XML type of the owner object :param str user_href: href of the user who started the task. :param str user_name: name of the user who started the task. :param str org_href: href of the organization, which the user mentioned above belongs to. :param str task_href: href of the task. :param str error_message: represents error information from a failed task. :return: an object containing EntityType.TASK XML data representing the updated task. :rtype: lxml.objectify.ObjectifiedElement """ t = E.Task(status=status, serviceNamespace=namespace, type=EntityType.TASK.value, operation=operation, operationName=operation_name, name='task') t.append(E.Owner(href=owner_href, name=owner_name, type=owner_type)) if error_message is not None: t.append( E.Error(stackTrace='', majorErrorCode='500', message=error_message, minorErrorCode='INTERNAL_SERVER_ERROR')) t.append( E.User(href=user_href, name=user_name, type=EntityType.USER.value)) if progress is not None: t.append(E.Progress(progress)) t.append(E.Details(details)) if task_href is None: org_resource = self.client.get_resource(org_href) link = find_link(org_resource, RelationType.DOWN, EntityType.TASKS_LIST.value) return self.client.post_resource(link.href, t, EntityType.TASK.value) else: return self.client.put_resource(task_href, t, EntityType.TASK.value)