def set_dhcp_service(self, ip_range, default_lease_time, max_lease_time): """Set DHCP to vApp network. :param str ip_range: IP range in StartAddress-EndAddress format. :param str default_lease_time: default lease time. :param str max_lease_time: max lease time :return: an object containing EntityType.TASK XML data which represents the asynchronous task that is updating the vApp network. :rtype: lxml.objectify.ObjectifiedElement :raises: InvalidParameterException: Set DHCP service failed as given network's connection is Direct """ self._get_resource() if self.resource.Configuration.FenceMode == 'bridged': raise InvalidParameterException( "Set DHCP service failed as given network's connection is " "Direct") ip_ranges = ip_range.split('-') if not hasattr(self.resource.Configuration, 'Features'): index = self.resource.Configuration.index( self.resource.Configuration.GuestVlanAllowed) self.resource.Configuration.insert(index, E.Features()) if not hasattr(self.resource.Configuration.Features, 'DhcpService'): self.resource.Configuration.Features.append(E.DhcpService()) dhcp = self.resource.Configuration.Features.DhcpService if hasattr(dhcp, 'IsEnabled'): dhcp.IsEnabled = E.IsEnabled(True) else: dhcp.append(E.IsEnabled(True)) if hasattr(dhcp, 'DefaultLeaseTime'): dhcp.DefaultLeaseTime = E.DefaultLeaseTime(default_lease_time) else: dhcp.append(E.DefaultLeaseTime(default_lease_time)) if hasattr(dhcp, 'MaxLeaseTime'): dhcp.MaxLeaseTime = E.MaxLeaseTime(max_lease_time) else: dhcp.append(E.MaxLeaseTime(max_lease_time)) if hasattr(dhcp, 'IpRange'): dhcp.IpRange.StartAddress = E.StartAddress(ip_ranges[0]) dhcp.IpRange.EndAddress = E.EndAddress(ip_ranges[1]) else: dhcp.append( E.IpRange(E.StartAddress(ip_ranges[0]), E.EndAddress(ip_ranges[1]))) return self.client.put_linked_resource(self.resource, RelationType.EDIT, EntityType.vApp_Network.value, self.resource)
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 add_network(self): network_name = self.params.get('network') fence_mode = self.params.get('fence_mode') parent_network = self.params.get('parent_network') ip_scope = self.params.get('ip_scope') ip_range_start = self.params.get('ip_range_start') ip_range_end = self.params.get('ip_range_end') dns1 = self.params.get('dns1') dns2 = self.params.get('dns2') dns_suffix = self.params.get('dns_suffix') nat_state = self.params.get('nat_state') fw_state = self.params.get('fw_state') response = dict() response['changed'] = False try: self.get_network() except EntityNotFoundException: network_config_section = self.vapp.resource.NetworkConfigSection config = E.Configuration() if parent_network: vdc = self.params.get('vdc') org_resource = Org(self.client, resource=self.client.get_org()) vdc_resource = VDC(self.client, resource=org_resource.get_vdc(vdc)) orgvdc_networks = vdc_resource.list_orgvdc_network_resources(parent_network) parent = next((network for network in orgvdc_networks if network.get('name') == parent_network), None) if parent: if ip_scope: scope = E.IpScope( E.IsInherited('false'), E.Gateway(str(ip_network(ip_scope, strict=False).network_address+1)), E.Netmask(str(ip_network(ip_scope, strict=False).netmask)), E.Dns1(dns1), E.Dns2(dns2)) if ip_range_start: if not ip_range_end: ip_range_end = ip_range_start ip_range = E.IpRange( E.StartAddress(ip_range_start), E.EndAddress(ip_range_end)) scope.append(E.IpRanges(ip_range)) config.append(E.IpScopes(scope)) config.append(E.ParentNetwork(href=parent.get('href'))) else: raise EntityNotFoundException('Parent network \'%s\' does not exist'.format(parent_network)) elif ip_scope: scope = E.IpScope( E.IsInherited('false'), E.Gateway(str(ip_network(ip_scope, strict=False).network_address+1)), E.Netmask(str(ip_network(ip_scope, strict=False).netmask)), E.Dns1(dns1), E.Dns2(dns2), E.DnsSuffix(dns_suffix)) if ip_range_start: if not ip_range_end: ip_range_end = ip_range_start ip_range = E.IpRange( E.StartAddress(ip_range_start), E.EndAddress(ip_range_end)) scope.append(E.IpRanges(ip_range)) config.append(E.IpScopes(scope)) else: raise VappNetworkCreateError('Either parent_network or ip_scope must be set') config.append(E.FenceMode(fence_mode)) features = E.Features() if fw_state == 'disabled': features.append(E.FirewallService(E.IsEnabled('false'))) if nat_state == 'disabled': features.append(E.NatService(E.IsEnabled('false'))) config.append(features) network_config = E.NetworkConfig(config, networkName=network_name) network_config_section.append(network_config) add_network_task = self.client.put_linked_resource( self.vapp.resource.NetworkConfigSection, RelationType.EDIT, EntityType.NETWORK_CONFIG_SECTION.value, network_config_section) self.execute_task(add_network_task) response['msg'] = 'Vapp Network {} has been added'.format(network_name) response['changed'] = True else: response['warnings'] = 'Vapp Network {} is already present.'.format(network_name) return response