def catalog_item_exists(catalog_item, catalog_name=None): if catalog_name is None: catalog_name = CATALOG_NAME org = Org(CLIENT, href=ORG_HREF) try: org.get_catalog_item(catalog_name, catalog_item) return True except EntityNotFoundException: return False
def catalog_item_exists(catalog_item, catalog_name=None): if catalog_name is None: catalog_name = CATALOG_NAME org = Org(CLIENT, href=ORG_HREF) try: # DEV NOTE: With api v33.0 and onwards, get_catalog_item operation will # fail for non admin users of an an org which is not hosting the # catalog, even if the catalog is explicitly shared with the org in # question. Please use this method only for org admin and sys admins. org.get_catalog_item(catalog_name, catalog_item) return True except EntityNotFoundException: return False
def ova_check_resolved(client, context, ovaInfo): logging.debug("===== INIT ova_check_resolved %s called === \n", ovaInfo.item_name) cresult = pyvcloudprovider_pb2.CheckResolvedResult() cresult.resolved = False try: logged_in_org = client.get_org() org = Org(client, resource=logged_in_org) source_ova_item = org.get_catalog_item(ovaInfo.catalog_name, ovaInfo.item_name) if source_ova_item is None: #TODO WRITE A TEST CASE raise error.ItemFoundError('Item = {0}'.format(ovaInfo.item_name)) check_resolved(client, source_ova_item) cresult.resolved = True logging.debug( "===== DONE upload/capture ova to catalog %s %s === \n", ovaInfo.catalog_name, ovaInfo.item_name) return cresult except Exception as e: error_message = 'ERROR.. ova_check_resolved {0} '.format( ovaInfo.item_name) logging.warn(error_message, e) context.set_code(grpc.StatusCode.INVALID_ARGUMENT) context.set_details(error_message) raise
def add_vm(ctx, name, source_vapp, source_vm, catalog, target_vm, hostname, network, ip_allocation_mode, storage_profile, password_auto, accept_all_eulas): try: client = ctx.obj['client'] in_use_org_href = ctx.obj['profiles'].get('org_href') org = Org(client, in_use_org_href) vdc_href = ctx.obj['profiles'].get('vdc_href') vdc = VDC(client, href=vdc_href) source_vapp_resource = None if catalog is None: source_vapp_resource = vdc.get_vapp(source_vapp) else: catalog_item = org.get_catalog_item(catalog, source_vapp) source_vapp_resource = client.get_resource( catalog_item.Entity.get('href')) assert source_vapp_resource is not None vapp_resource = vdc.get_vapp(name) vapp = VApp(client, resource=vapp_resource) spec = {'source_vm_name': source_vm, 'vapp': source_vapp_resource} if target_vm is not None: spec['target_vm_name'] = target_vm if hostname is not None: spec['hostname'] = hostname if network is not None: spec['network'] = network spec['ip_allocation_mode'] = ip_allocation_mode if storage_profile is not None: spec['storage_profile'] = vdc.get_storage_profile(storage_profile) if password_auto is not None: spec['password_auto'] = password_auto task = vapp.add_vms([spec], all_eulas_accepted=accept_all_eulas) stdout(task, ctx) except Exception as e: stderr(e, ctx)
def info(ctx, catalog_name, item_name): try: restore_session(ctx) client = ctx.obj['client'] in_use_org_href = ctx.obj['profiles'].get('org_href') org = Org(client, in_use_org_href) if item_name is None: catalog = org.get_catalog(catalog_name) result = to_dict(catalog) # We don't have a way to know in advance if a user has access to a # catalog's ACL or not. So we try to retrieve it always. If the # call fails due to permission issues, we silently eat the # exception and exclude ACL settings from the output of the current # command. Users who have access to ACL of the catalog will remain # unaffected. Also any other errors/exceptions will bubble up as # usual. try: access_control_settings = access_settings_to_dict( org.get_catalog_access_settings(catalog_name)) result.update(access_control_settings) except AccessForbiddenException as e: pass else: catalog_item = org.get_catalog_item(catalog_name, item_name) result = to_dict(catalog_item) vapp = VApp(client, href=catalog_item.Entity.get('href')) vapp.reload() template = vapp_to_dict(vapp.resource) for k, v in template.items(): result['template-%s' % k] = v stdout(result, ctx) except Exception as e: stderr(e, ctx)
def test_0002_add_vm(self): logged_in_org = self.client.get_org() org = Org(self.client, resource=logged_in_org) vdc_resource = org.get_vdc(self.config['vcd']['vdc']) vdc = VDC(self.client, href=vdc_resource.get('href')) assert self.config['vcd']['vdc'] == vdc.get_resource().get('name') vapp_resource = vdc.get_vapp(self.config['vcd']['vapp']) assert vapp_resource.get('name') == self.config['vcd']['vapp'] vapp = VApp(self.client, resource=vapp_resource) catalog_item = org.get_catalog_item(self.config['vcd']['catalog'], self.config['vcd']['template']) source_vapp_resource = self.client.get_resource( catalog_item.Entity.get('href')) spec = {'source_vm_name': self.config['vcd']['vm'], 'vapp': source_vapp_resource} spec['target_vm_name'] = self.config['vcd']['hostname'] spec['hostname'] = self.config['vcd']['hostname'] spec['network'] = self.config['vcd']['network'] spec['ip_allocation_mode'] = self.config['vcd']['ip_allocation_mode'] spec['storage_profile'] = vdc.get_storage_profile( self.config['vcd']['storage_profile']) vms = [spec] result = vapp.add_vms(vms) task = self.client.get_task_monitor().wait_for_status( task=result, timeout=60, poll_frequency=2, fail_on_statuses=None, expected_target_statuses=[ TaskStatus.SUCCESS, TaskStatus.ABORTED, TaskStatus.ERROR, TaskStatus.CANCELED], callback=None) assert task.get('status') == TaskStatus.SUCCESS.value
def test_0002_add_vm(self): org_resource = self.client.get_org_by_name( self.config['vcd']['org_to_use']) self.logger.debug('org: %s' % org_resource.get('name')) org = Org(self.client, href=org_resource.get('href')) vdc_resource = org.get_vdc(self.config['vcd']['vdc']) vdc = VDC(self.client, href=vdc_resource.get('href')) assert self.config['vcd']['vdc'] == vdc.get_resource().get('name') vapp_resource = vdc.get_vapp(self.config['vcd']['vapp']) assert vapp_resource.get('name') == self.config['vcd']['vapp'] vapp = VApp(self.client, resource=vapp_resource) catalog_item = org.get_catalog_item(self.config['vcd']['catalog'], self.config['vcd']['template']) source_vapp_resource = self.client.get_resource( catalog_item.Entity.get('href')) spec = { 'source_vm_name': self.config['vcd']['vm'], 'vapp': source_vapp_resource } spec['target_vm_name'] = self.config['vcd']['hostname'] spec['hostname'] = self.config['vcd']['hostname'] spec['network'] = self.config['vcd']['network'] spec['ip_allocation_mode'] = self.config['vcd']['ip_allocation_mode'] spec['storage_profile'] = vdc.get_storage_profile( self.config['vcd']['storage_profile']) vms = [spec] result = vapp.add_vms(vms, all_eulas_accepted=True) task = self.client.get_task_monitor().wait_for_status(task=result) assert task.get('status') == TaskStatus.SUCCESS.value
def upload_media(cls): """Uploads the test media to the test catalog. If media already exists in the catalog then skips uploading it. :raises: Exception: if the class variable _org_href is not populated. """ cls._basic_check() if cls._org_href is None: raise Exception('Org ' + cls._config['vcd']['default_org_name'] + ' doesn\'t exist.') try: catalog_author_client = Environment.get_client_in_default_org( CommonRoles.CATALOG_AUTHOR) org = Org(catalog_author_client, href=cls._org_href) catalog_name = cls._config['vcd']['default_catalog_name'] catalog_items = org.list_catalog_items(catalog_name) media_name = cls._config['vcd']['default_media_name'] for item in catalog_items: if item.get('name').lower() == media_name.lower(): cls._logger.debug('Reusing existing media ' + media_name) cls._media_resource = org.get_catalog_item( catalog_name, media_name) return cls._logger.debug('Uploading media ' + media_name + ' to catalog ' + catalog_name + '.') org.upload_media(catalog_name=catalog_name, file_name=media_name) # wait for the template import to finish in vCD. catalog_item = org.get_catalog_item(name=catalog_name, item_name=media_name) media = catalog_author_client.get_resource( catalog_item.Entity.get('href')) if hasattr(media, "Tasks"): catalog_author_client.get_task_monitor().wait_for_success( task=media.Tasks.Task[0]) cls._media_resource = org.get_catalog_item(catalog_name, media_name) finally: catalog_author_client.logout()
def upload_media(cls): """Uploads the test media to the test catalog. If media already exists in the catalog then skips uploading it. :raises: Exception: if the class variable _org_href is not populated. """ cls._basic_check() if cls._org_href is None: raise Exception('Org ' + cls._config['vcd']['default_org_name'] + ' doesn\'t exist.') try: catalog_author_client = Environment.get_client_in_default_org( CommonRoles.CATALOG_AUTHOR) org = Org(catalog_author_client, href=cls._org_href) catalog_name = cls._config['vcd']['default_catalog_name'] catalog_items = org.list_catalog_items(catalog_name) media_name = cls._config['vcd']['default_media_name'] for item in catalog_items: if item.get('name').lower() == media_name.lower(): cls._logger.debug('Reusing existing media ' + media_name) cls._media_resource = org.get_catalog_item(catalog_name,media_name) return cls._logger.debug('Uploading media ' + media_name + ' to catalog ' + catalog_name + '.') org.upload_media(catalog_name=catalog_name, file_name=media_name) # wait for the template import to finish in vCD. catalog_item = org.get_catalog_item( name=catalog_name, item_name=media_name) media = catalog_author_client.get_resource( catalog_item.Entity.get('href')) catalog_author_client.get_task_monitor().wait_for_success( task=media.Tasks.Task[0]) cls._media_resource = org.get_catalog_item(catalog_name,media_name) finally: catalog_author_client.logout()
def get_source_resource(self): source_catalog_name = self.params.get('source_catalog_name') source_template_name = self.params.get('source_template_name') org_resource = Org(self.client, resource=self.client.get_org()) source_vapp_resource = None if source_catalog_name: catalog_item = org_resource.get_catalog_item( source_catalog_name, source_template_name) source_vapp_resource = self.client.get_resource( catalog_item.Entity.get('href')) return source_vapp_resource
def validate_broker_config_content(config, client, template='*'): from container_service_extension.config import bool_to_msg logged_in_org = client.get_org() org = Org(client, resource=logged_in_org) org.get_catalog(config['broker']['catalog']) click.echo('Find catalog \'%s\': %s' % (config['broker']['catalog'], bool_to_msg(True))) default_template_found = False for t in config['broker']['templates']: if template == '*' or template == t['name']: click.secho('Validating template: %s' % t['name']) if config['broker']['default_template'] == t['name']: default_template_found = True click.secho(' Is default template: %s' % True) else: click.secho(' Is default template: %s' % False) org.get_catalog_item(config['broker']['catalog'], t['catalog_item']) click.echo('Find template \'%s\', \'%s\': %s' % (config['broker']['catalog'], t['catalog_item'], bool_to_msg(True))) assert default_template_found
def is_present(client, catalog_name, item_name): logging.basicConfig(level=logging.DEBUG) logging.debug("=== isPresent catalog item called === \n") try: logged_in_org = client.get_org() org = Org(client, resource=logged_in_org) result = catalog_item_pb2.IsPresentCatalogItemResult() result.present = False try: catalog = org.get_catalog_item(catalog_name, item_name) result.present = True except Exception as e: logging.info("catalog item is not present") return result except Exception as e: logging.warn("__ERROR__ occured", e)
def info(ctx, catalog_name, item_name): try: client = ctx.obj['client'] org_name = ctx.obj['profiles'].get('org') in_use_org_href = ctx.obj['profiles'].get('org_href') org = Org(client, in_use_org_href, org_name == 'System') if item_name is None: catalog = org.get_catalog(catalog_name) result = to_dict(catalog) else: catalog_item = org.get_catalog_item(catalog_name, item_name) result = to_dict(catalog_item) vapp = VApp(client, href=catalog_item.Entity.get('href')) vapp.reload() template = vapp_to_dict(vapp.resource) for k, v in template.items(): result['template-%s' % k] = v stdout(result, ctx) except Exception as e: stderr(e, ctx)
def upload_template(cls): """Uploads the test template to the test catalog. If template already exists in the catalog then skips uploading it. :return: Nothing :raises: Exception: if the class variable _org_href is not populated. """ cls._basic_check() if cls._org_href is None: raise Exception('Org ' + cls._config['vcd']['default_org_name'] + ' doesn\'t exist.') try: catalog_author_client = Environment.get_client_in_default_org( CommonRoles.CATALOG_AUTHOR) org = Org(catalog_author_client, href=cls._org_href) catalog_name = cls._config['vcd']['default_catalog_name'] catalog_items = org.list_catalog_items(catalog_name) template_name = cls._config['vcd']['default_template_file_name'] for item in catalog_items: if item.get('name').lower() == template_name.lower(): cls._logger.debug('Reusing existing template ' + template_name) return cls._logger.debug('Uploading template ' + template_name + ' to catalog ' + catalog_name + '.') org.upload_ovf(catalog_name=catalog_name, file_name=template_name) catalog_item = org.get_catalog_item(name=catalog_name, item_name=template_name) template = catalog_author_client.get_resource( catalog_item.Entity.get('href')) catalog_author_client.get_task_monitor().wait_for_success( task=template.Tasks.Task[0]) finally: catalog_author_client.logout()
def info(ctx, catalog_name, item_name): try: client = ctx.obj['client'] in_use_org_href = ctx.obj['profiles'].get('org_href') org = Org(client, in_use_org_href) if item_name is None: catalog = org.get_catalog(catalog_name) result = to_dict(catalog) access_control_settings = access_settings_to_dict( org.get_catalog_access_settings(catalog_name)) result.update(access_control_settings) else: catalog_item = org.get_catalog_item(catalog_name, item_name) result = to_dict(catalog_item) vapp = VApp(client, href=catalog_item.Entity.get('href')) vapp.reload() template = vapp_to_dict(vapp.resource) for k, v in template.items(): result['template-%s' % k] = v stdout(result, ctx) except Exception as e: stderr(e, ctx)
def get_source_resource(self): source_catalog_name = self.params.get('source_catalog_name') source_template_name = self.params.get('source_template_name') source_vdc = self.params.get('source_vdc') source_vapp = self.params.get('source_vapp') org_resource = Org(self.client, resource=self.client.get_org()) source_vapp_resource = None if source_vapp: source_vdc_resource = VDC( self.client, resource=org_resource.get_vdc(source_vdc)) source_vapp_resource_href = source_vdc_resource.get_resource_href( name=source_vapp, entity_type=EntityType.VAPP) source_vapp_resource = self.client.get_resource( source_vapp_resource_href) if source_catalog_name: catalog_item = org_resource.get_catalog_item( source_catalog_name, source_template_name) source_vapp_resource = self.client.get_resource( catalog_item.Entity.get('href')) return source_vapp_resource
def get_vapp_resources(module): ''' If source_vapp and source_catalog both are given then priority will be given to source_catalog. ''' client = module.client source_catalog_name = module.params.get('source_catalog_name', None) source_template_name = module.params.get('source_template_name', None) target_vapp = module.params.get('target_vapp', None) target_vdc = module.params.get('target_vdc', None) source_vdc = module.params.get('source_vdc', None) source_vapp = module.params.get('source_vapp', None) org_resource = Org(client, resource=client.get_org()) if source_vapp: source_vdc_resource = VDC(client, resource=org_resource.get_vdc(source_vdc)) target_vdc_resource = VDC(client, resource=org_resource.get_vdc(target_vdc)) source_vapp_resource_href = source_vdc_resource.get_resource_href( name=source_vapp, entity_type=EntityType.VAPP) target_vapp_resource_href = target_vdc_resource.get_resource_href( name=target_vapp, entity_type=EntityType.VAPP) source_vapp_resource = client.get_resource(source_vapp_resource_href) target_vapp_resource = client.get_resource(target_vapp_resource_href) if source_catalog_name: target_vdc_resource = VDC(client, resource=org_resource.get_vdc(target_vdc)) target_vapp_resource = target_vdc_resource.get_vapp(target_vapp) catalog_item = org_resource.get_catalog_item(source_catalog_name, source_template_name) source_vapp_resource = client.get_resource( catalog_item.Entity.get('href')) return source_vapp_resource, target_vapp_resource
def add_vm(ctx, name, source_vapp, source_vm, catalog, target_vm, hostname, network, ip_allocation_mode, storage_profile, password_auto, accept_all_eulas): try: restore_session(ctx, vdc_required=True) client = ctx.obj['client'] in_use_org_href = ctx.obj['profiles'].get('org_href') org = Org(client, in_use_org_href) vdc_href = ctx.obj['profiles'].get('vdc_href') vdc = VDC(client, href=vdc_href) source_vapp_resource = None if catalog is None: source_vapp_resource = vdc.get_vapp(source_vapp) else: catalog_item = org.get_catalog_item(catalog, source_vapp) source_vapp_resource = client.get_resource( catalog_item.Entity.get('href')) assert source_vapp_resource is not None vapp_resource = vdc.get_vapp(name) vapp = VApp(client, resource=vapp_resource) spec = {'source_vm_name': source_vm, 'vapp': source_vapp_resource} if target_vm is not None: spec['target_vm_name'] = target_vm if hostname is not None: spec['hostname'] = hostname if network is not None: spec['network'] = network spec['ip_allocation_mode'] = ip_allocation_mode if storage_profile is not None: spec['storage_profile'] = vdc.get_storage_profile(storage_profile) if password_auto is not None: spec['password_auto'] = password_auto task = vapp.add_vms([spec], all_eulas_accepted=accept_all_eulas) stdout(task, ctx) except Exception as e: stderr(e, ctx)
def test_0002_add_vm(self): logged_in_org = self.client.get_org() org = Org(self.client, resource=logged_in_org) vdc_resource = org.get_vdc(self.config['vcd']['vdc']) vdc = VDC(self.client, href=vdc_resource.get('href')) assert self.config['vcd']['vdc'] == vdc.get_resource().get('name') vapp_resource = vdc.get_vapp(self.config['vcd']['vapp']) assert vapp_resource.get('name') == self.config['vcd']['vapp'] vapp = VApp(self.client, resource=vapp_resource) catalog_item = org.get_catalog_item(self.config['vcd']['catalog'], self.config['vcd']['template']) source_vapp_resource = self.client.get_resource( catalog_item.Entity.get('href')) spec = { 'source_vm_name': self.config['vcd']['vm'], 'vapp': source_vapp_resource } spec['target_vm_name'] = self.config['vcd']['hostname'] spec['hostname'] = self.config['vcd']['hostname'] spec['network'] = self.config['vcd']['network'] spec['ip_allocation_mode'] = self.config['vcd']['ip_allocation_mode'] spec['storage_profile'] = vdc.get_storage_profile( self.config['vcd']['storage_profile']) vms = [spec] result = vapp.add_vms(vms) task = self.client.get_task_monitor().wait_for_status( task=result, timeout=60, poll_frequency=2, fail_on_statuses=None, expected_target_statuses=[ TaskStatus.SUCCESS, TaskStatus.ABORTED, TaskStatus.ERROR, TaskStatus.CANCELED ], callback=None) assert task.get('status') == TaskStatus.SUCCESS.value
def create(client): print("=============== __LOG__Create_VDC =======================\n\n") vdc_name = "ACME_PAYG" vapp_name = "test2" org_resource = client.get_org() org = Org(client, resource=org_resource) print("Org name: ", org.get_name()) print("Vdc name: ", vdc_name) try: vdc_resource = org.get_vdc(vdc_name) vdc = VDC(client, name=vdc_name, resource=vdc_resource) vapp_resource = vdc.get_vapp(vapp_name) vapp = VApp(client, name=vapp_name, resource=vapp_resource) print("vapp : ", vapp) catalog_item = org.get_catalog_item('ACME', 'tinyova') source_vapp_resource = client.get_resource( catalog_item.Entity.get('href')) print("source_vapp_resource: ", source_vapp_resource) spec = { 'source_vm_name': 'Tiny Linux template', 'vapp': source_vapp_resource } storage_profiles = [{ 'name': 'Performance', 'enabled': True, 'units': 'MB', 'limit': 0, 'default': True }] spec['target_vm_name'] = 'ubuntu_pcp_11' spec['hostname'] = 'ubuntu' spec['network'] = 'global' spec['ip_allocation_mode'] = 'dhcp' #spec['storage_profile'] = storage_profiles vms = [spec] result = vapp.add_vms(vms) print("result: ", result) #task = client.get_task_monitor().wait_for_status( # task=result, # timeout=60, # poll_frequency=2, # fail_on_statuses=None, # expected_target_statuses=[ # TaskStatus.SUCCESS, # TaskStatus.ABORTED, # TaskStatus.ERROR, # TaskStatus.CANCELED], # callback=None) #st = task.get('status') #if st == TaskStatus.SUCCESS.value: # message = 'status : {0} '.format(st) # logging.info(message) #else: # print("st : ", st) # raise Exception(task) print("=============================================\n\n") return True except Exception as e: error_message = '__ERROR_ [create_vdc] failed for vdc {0} '.format( vdc_name) logging.warn(error_message, e) return False
# so that it's visible in future calls. try: catalog_resource = org.get_catalog_resource(cfg.catalog['name']) print("Catalog already exists: {0}".format(cfg.catalog['name'])) except Exception: print("Catalog does not exist, creating: {0}".format(cfg.catalog['name'])) catalog_kwargs = cfg.catalog catalog_resource = org.create_catalog(**catalog_kwargs) org.reload() print("Catalog now exists: {0}".format(catalog_resource.get('name'))) # Check for catalog_items containing OVF templates in the catalog and # upload them if they are missing. for catalog_item in cfg.catalog_items: try: catalog_item_resource = org.get_catalog_item( catalog_item['catalog_name'], catalog_item['item_name']) print("Catalog item exists: {0}".format(catalog_item['item_name'])) except Exception: # Define a progress reporter to track upload, since it takes # a while. def progress_reporter(transferred, total): print("{:,} of {:,} bytes, {:.0%}".format( transferred, total, transferred / total)) print("Loading catalog item: catalog={0}, item={1}, file={2}".format( catalog_item['catalog_name'], catalog_item['item_name'], catalog_item['file_name'])) catalog_item['callback'] = progress_reporter org.upload_ovf(**catalog_item) print("Upload completed")
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 test_validate_ova(self): logged_in_org = self.client.get_org() org = Org(self.client, resource=logged_in_org) template = org.get_catalog_item(self.config['vcd']['catalog'], self.config['vcd']['template']) assert self.config['vcd']['template'] == template.get('name')
def create_from_catalog(self, request): logging.info("__INIT__create[VappVm] source_catalog_name[%s]", request.source_catalog_name) res = vapp_vm_pb2.CreateVappVmResult() res.created = False logged_in_org = self.client.get_org() org = Org(self.client, resource=logged_in_org) try: vdc_resource = org.get_vdc(request.target_vdc) vdc = VDC(self.client, name=request.target_vdc, resource=vdc_resource) vapp_resource = vdc.get_vapp(request.target_vapp) vapp = VApp(self.client, name=request.target_vapp, resource=vapp_resource) catalog_item = org.get_catalog_item(request.source_catalog_name, request.source_template_name) source_vapp_resource = self.client.get_resource( catalog_item.Entity.get('href')) specs = [{ 'source_vm_name': request.source_vm_name, 'vapp': source_vapp_resource, 'target_vm_name': request.target_vm_name, 'hostname': request.hostname, 'network': request.network, 'ip_allocation_mode': request.ip_allocation_mode, # 'storage_profile': request.storage_profile }] create_vapp_vm_resp = vapp.add_vms(specs, power_on=request.power_on, all_eulas_accepted=request.all_eulas_accepted) task_monitor = self.client.get_task_monitor() task = task_monitor.wait_for_status( task=create_vapp_vm_resp, timeout=60, poll_frequency=2, fail_on_statuses=None, expected_target_statuses=[ TaskStatus.SUCCESS, TaskStatus.ABORTED, TaskStatus.ERROR, TaskStatus.CANCELED ], callback=None) st = task.get('status') if st != TaskStatus.SUCCESS.value: raise errors.VappVmCreateError( etree.tostring(task, pretty_print=True)) message = 'status : {0} '.format(st) logging.info(message) res.created = True except Exception as e: errmsg = '''__ERROR_create[VappVm] failed for vm {0}. __ErrorMessage__ {1}''' logging.warn(errmsg.format(request.target_vm_name, str(e))) self.context.set_code(grpc.StatusCode.INVALID_ARGUMENT) self.context.set_details(errmsg) return res logging.info("__DONE__create[VappVm]") return res
#except Exception: # print("Catalog items fetch error") # exit(0) # Ensure the catalog (vApp template) and catalog item (VM template) exists for vm_cfg in cfg.vapp['vms']: try: catalog = org.get_catalog(vm_cfg['catalog']) print(" Catalog '{0}' ... OK".format(vm_cfg['catalog'])) except Exception: print(" Catalog '{0}' ... KO. Exiting.".format(vm_cfg['catalog'])) exit(0) try: catalog_item = org.get_catalog_item(vm_cfg['catalog'], vm_cfg['catalog_item']) print(" Catalog item '{0} / {1}' ... OK".format( vm_cfg['catalog'], vm_cfg['catalog_item'])) except Exception: print(" Catalog item '{0} / {1}' ... KO. Exiting.".format( vm_cfg['catalog'], vm_cfg['catalog_item'])) exit(0) # Check for vApps and create them if they don't exist. We have to # reload the VDC object so it has all the links to current vApps. vdc.reload() try: vapp = vdc.get_vapp(cfg.vapp['name']) print("vApp exists: {0}".format(cfg.vapp['name'])) except Exception:
class CatalogItem(VcdAnsibleModule): def __init__(self, **kwargs): super(CatalogItem, self).__init__(**kwargs) logged_in_org = self.client.get_org() self.org = Org(self.client, resource=logged_in_org) def manage_states(self): state = self.params.get('state') if state == "present": return self.upload() if state == "absent": return self.delete() def manage_operations(self): operation = self.params.get('operation') if operation == "capturevapp": return self.capture_vapp() if operation == "list_vms": return self.list_vms() def is_present(self): params = self.params catalog_name = params.get('catalog_name') item_name = params.get('item_name') try: self.org.get_catalog_item(catalog_name, item_name) except EntityNotFoundException: return False return True def upload(self): params = self.params catalog_name = params.get('catalog_name') item_name = params.get('item_name') file_name = params.get('file_name') chunk_size = params.get('chunk_size') response = dict() response['changed'] = False item_details = { "catalog_name": catalog_name, "item_name": item_name, "file_name": file_name, "chunk_size": chunk_size } if self.is_present(): response['warnings'] = "Catalog Item {} is already present.".format(item_name) return response if file_name.endswith(".ova") or file_name.endswith(".ovf"): self.org.upload_ovf(**item_details) self.ova_check_resolved() if not file_name.endswith(".ova"): self.org.upload_media(**item_details) response['msg'] = "Catalog item {} is uploaded.".format(item_name) response['changed'] = True return response def delete(self): params = self.params catalog_name = params.get('catalog_name') item_name = params.get('item_name') response = dict() response['changed'] = False if not self.is_present(): response['warnings'] = "Catalog Item {} is not present.".format(item_name) return response self.org.delete_catalog_item(name=catalog_name, item_name=item_name) response['msg'] = "Catalog Item {} has been deleted.".format(item_name) response['changed'] = True return response def capture_vapp(self): params = self.params vapp_name = params.get('vapp_name') vdc_name = params.get('vdc_name') catalog_name = params.get('catalog_name') item_name = params.get('item_name') desc = params.get('description') customize_on_instantiate = params.get('customize_on_instantiate') overwrite = params.get('overwrite') client = self.client response = dict() response['changed'] = False v = self.org.get_vdc(vdc_name) vdc = VDC(client, href=v.get('href')) vapp = vdc.get_vapp(vapp_name) catalog = self.org.get_catalog(catalog_name) self.org.capture_vapp( catalog_resource=catalog, vapp_href=vapp.get('href'), catalog_item_name=item_name, description=desc, customize_on_instantiate=customize_on_instantiate, overwrite=overwrite) self.ova_check_resolved() response['msg'] = "Catalog Item {} has been captured".format(item_name) response['changed'] = True return response def ova_check_resolved(self): params = self.params catalog_name = params.get('catalog_name') item_name = params.get('item_name') response = False source_ova_item = self.org.get_catalog_item(catalog_name, item_name) self.check_resolved(source_ova_item, catalog_name, item_name) response = True return response def check_resolved(self, source_ova_item, catalog_name, item_name): client = self.client item_id = source_ova_item.get('id') while True: q = client.get_typed_query( 'catalogItem', query_result_format=QueryResultFormat.ID_RECORDS, qfilter='id==%s' % item_id ) records = list(q.execute()) if records[0].get('status') == 'RESOLVED': break else: time.sleep(5) # TODO might have to check when status goes to other state than resolved def list_vms(self): params = self.params catalog_name = params.get('catalog_name') item_name = params.get('item_name') response = dict() result = list() response['changed'] = False catalog_item = self.org.get_catalog_item(catalog_name, item_name) vapp_template_resource = self.client.get_resource( catalog_item.Entity.get('href')) vapp_template = VApp(self.client, name=item_name, resource=vapp_template_resource) for vm in vapp_template.get_all_vms(): result.append(vm.get('name')) response['msg'] = result response['changed'] = False return response
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 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 add_nodes(client, num_nodes, node_type, org, vdc, vapp, catalog_name, template, network_name, num_cpu=None, memory_in_mb=None, storage_profile=None, ssh_key=None): specs = [] try: if num_nodes < 1: return None # DEV NOTE: With api v33.0 and onwards, get_catalog operation will fail # for non admin users of an an org which is not hosting the catalog, # even if the catalog is explicitly shared with the org in question. # This happens because for api v 33.0 and onwards, the Org XML no # longer returns the href to catalogs accessible to the org, and typed # queries hide the catalog link from non admin users. # As a workaround, we will use a sys admin client to get the href and # pass it forward. Do note that the catalog itself can still be # accessed by these non admin users, just that they can't find by the # href on their own. sys_admin_client = None try: sys_admin_client = vcd_utils.get_sys_admin_client() org_name = org.get_name() org_resource = sys_admin_client.get_org_by_name(org_name) org_sa = Org(sys_admin_client, resource=org_resource) catalog_item = org_sa.get_catalog_item( catalog_name, template[LocalTemplateKey.CATALOG_ITEM_NAME]) catalog_item_href = catalog_item.Entity.get('href') finally: if sys_admin_client: sys_admin_client.logout() source_vapp = VApp(client, href=catalog_item_href) source_vm = source_vapp.get_all_vms()[0].get('name') if storage_profile is not None: storage_profile = vdc.get_storage_profile(storage_profile) cust_script = None if ssh_key is not None: cust_script = \ "#!/usr/bin/env bash\n" \ "if [ x$1=x\"postcustomization\" ];\n" \ "then\n" \ "mkdir -p /root/.ssh\n" \ f"echo '{ssh_key}' >> /root/.ssh/authorized_keys\n" \ "chmod -R go-rwx /root/.ssh\n" \ "fi" for n in range(num_nodes): name = None while True: name = f"{node_type}-{''.join(random.choices(string.ascii_lowercase + string.digits, k=4))}" # noqa: E501 try: vapp.get_vm(name) except Exception: break spec = { 'source_vm_name': source_vm, 'vapp': source_vapp.resource, 'target_vm_name': name, 'hostname': name, 'password_auto': True, 'network': network_name, 'ip_allocation_mode': 'pool' } if cust_script is not None: spec['cust_script'] = cust_script if storage_profile is not None: spec['storage_profile'] = storage_profile specs.append(spec) task = vapp.add_vms(specs, power_on=False) client.get_task_monitor().wait_for_status(task) vapp.reload() if not num_cpu: num_cpu = template[LocalTemplateKey.CPU] if not memory_in_mb: memory_in_mb = template[LocalTemplateKey.MEMORY] for spec in specs: vm_name = spec['target_vm_name'] vm_resource = vapp.get_vm(vm_name) vm = VM(client, resource=vm_resource) task = vm.modify_cpu(num_cpu) client.get_task_monitor().wait_for_status(task) task = vm.modify_memory(memory_in_mb) client.get_task_monitor().wait_for_status(task) task = vm.power_on() client.get_task_monitor().wait_for_status(task) vapp.reload() if node_type == NodeType.NFS: LOGGER.debug(f"Enabling NFS server on {vm_name}") script_filepath = get_local_script_filepath( template[LocalTemplateKey.NAME], template[LocalTemplateKey.REVISION], ScriptFile.NFSD) script = utils.read_data_file(script_filepath, logger=LOGGER) exec_results = execute_script_in_nodes(vapp=vapp, node_names=[vm_name], script=script) errors = _get_script_execution_errors(exec_results) if errors: raise ScriptExecutionError( f"VM customization script execution failed on node " f"{vm_name}:{errors}") except Exception as e: # TODO: get details of the exception to determine cause of failure, # e.g. not enough resources available. node_list = [entry.get('target_vm_name') for entry in specs] raise NodeCreationError(node_list, str(e)) vapp.reload() return {'task': task, 'specs': specs}
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 create_from_catalog(self, request): logging.info("__INIT__create[VappVm] source_catalog_name[%s]", request.source_catalog_name) res = vapp_vm_pb2.CreateVappVmResult() res.created = False logged_in_org = self.client.get_org() org = Org(self.client, resource=logged_in_org) try: vdc_resource = org.get_vdc(request.target_vdc) vdc = VDC( self.client, name=request.target_vdc, resource=vdc_resource) vapp_resource = vdc.get_vapp(request.target_vapp) vapp = VApp( self.client, name=request.target_vapp, resource=vapp_resource) catalog_item = org.get_catalog_item(request.source_catalog_name, request.source_template_name) source_vapp_resource = self.client.get_resource( catalog_item.Entity.get('href')) specs = [{ 'source_vm_name': request.source_vm_name, 'vapp': source_vapp_resource, 'target_vm_name': request.target_vm_name, 'hostname': request.hostname, 'network': request.network, 'ip_allocation_mode': request.ip_allocation_mode, # 'storage_profile': request.storage_profile }] create_vapp_vm_resp = vapp.add_vms( specs, power_on=request.power_on, all_eulas_accepted=request.all_eulas_accepted) task_monitor = self.client.get_task_monitor() task = task_monitor.wait_for_status( task=create_vapp_vm_resp, timeout=60, poll_frequency=2, fail_on_statuses=None, expected_target_statuses=[ TaskStatus.SUCCESS, TaskStatus.ABORTED, TaskStatus.ERROR, TaskStatus.CANCELED ], callback=None) st = task.get('status') if st != TaskStatus.SUCCESS.value: raise errors.VappVmCreateError( etree.tostring(task, pretty_print=True)) message = 'status : {0} '.format(st) logging.info(message) res.created = True except Exception as e: errmsg = '''__ERROR_create[VappVm] failed for vm {0}. __ErrorMessage__ {1}''' logging.warn(errmsg.format(request.target_vm_name, str(e))) self.context.set_code(grpc.StatusCode.INVALID_ARGUMENT) self.context.set_details(errmsg) return res logging.info("__DONE__create[VappVm]") return res
def install_cse(ctx, config_file_name, template_name, no_capture, update, amqp_install, ext_install): check_config(config_file_name) click.secho('Installing CSE on vCD from file: %s, template: %s' % (config_file_name, template_name)) config = get_config(config_file_name) client = Client(config['vcd']['host'], api_version=config['vcd']['api_version'], verify_ssl_certs=config['vcd']['verify'], log_file='cse-install.log', log_headers=True, log_bodies=True) client.set_credentials( BasicLoginCredentials(config['vcd']['username'], 'System', config['vcd']['password'])) click.echo( 'Connected to vCloud Director as system ' 'administrator (%s:%s): %s' % (config['vcd']['host'], config['vcd']['port'], bool_to_msg(True))) click.secho('Installing \'%s\' service broker' % config['broker']['type']) if config['broker']['type'] == 'default': orgs = client.get_org_list() org_href = None for org in [o for o in orgs.Org if hasattr(orgs, 'Org')]: if org.get('name') == config['broker']['org']: org_href = org.get('href') org = Org(client, href=org_href) click.echo('Find org \'%s\': %s' % (org.get_name(), bool_to_msg(True))) vdc_resource = org.get_vdc(config['broker']['vdc']) click.echo('Find vdc \'%s\': %s' % (vdc_resource.get('name'), bool_to_msg(True))) try: catalog = org.get_catalog(config['broker']['catalog']) except Exception: click.secho('Creating catalog %s ' % config['broker']['catalog'], nl=False, fg='green') catalog = org.create_catalog(config['broker']['catalog'], 'CSE catalog') org.share_catalog(config['broker']['catalog']) click.secho('done', fg='blue') catalog = org.get_catalog(config['broker']['catalog']) click.echo( 'Find catalog \'%s\': %s' % (config['broker']['catalog'], bool_to_msg(catalog is not None))) for template in config['broker']['templates']: if template_name == '*' or template['name'] == template_name: click.secho('Processing template: %s' % template['name']) k8s_template = None try: k8s_template = org.get_catalog_item( config['broker']['catalog'], template['catalog_item']) click.echo( 'Find template \'%s\', \'%s\': %s' % (config['broker']['catalog'], template['catalog_item'], bool_to_msg(k8s_template is not None))) except Exception: pass try: if k8s_template is None or update: if update: click.secho('Updating template') else: click.secho('Creating template') create_template(ctx, config, client, org, vdc_resource, catalog, no_capture, template) k8s_template = org.get_catalog_item( config['broker']['catalog'], template['catalog_item']) if update: click.echo('Updated template \'%s\', \'%s\': %s' % (config['broker']['catalog'], template['catalog_item'], bool_to_msg(k8s_template is not None))) else: click.echo('Find template \'%s\', \'%s\': %s' % (config['broker']['catalog'], template['catalog_item'], bool_to_msg(k8s_template is not None))) except Exception: LOGGER.error(traceback.format_exc()) click.echo('Can\'t create or update template \'%s\' ' '\'%s\': %s' % (template['name'], config['broker']['catalog'], template['catalog_item'])) configure_amqp_settings(ctx, client, config, amqp_install) register_extension(ctx, client, config, ext_install) click.secho('Start CSE with: \'cse run %s\'' % config_file_name)