def _makePccVAppNetwork(self, network_xml, name, href=None): name = name href = href fencemode = None gateway = None netmask = None dns1 = None dns2 = None iprangeF =None iprangeT =None primary = False if name == getOtherProperty("vCloud.PCCNetwork"): primary = True if href is None: link = network_xml.find(fixxpath(network_xml, 'Link')) if link is not None: href = link.get('href') fence = network_xml.find(fixxpath(network_xml, 'Configuration/FenceMode')) if fence is not None: fencemode = fence.text scope = network_xml.find(fixxpath(network_xml, 'Configuration/IpScopes/IpScope')) for elem in scope: if elem.tag == '{http://www.vmware.com/vcloud/v1.5}Gateway': gateway = elem.text if elem.tag == '{http://www.vmware.com/vcloud/v1.5}Netmask': netmask = elem.text if elem.tag == '{http://www.vmware.com/vcloud/v1.5}Dns1': dns1 = elem.text if elem.tag == '{http://www.vmware.com/vcloud/v1.5}Dns2': dns2 = elem.text ipranges = network_xml.findall(fixxpath(network_xml, 'Configuration/IpScopes/IpScope/IpRanges/IpRange')) if ipranges is not None: for iprange in ipranges: for elem in iprange: if elem.tag == '{http://www.vmware.com/vcloud/v1.5}StartAddress': iprangeF = elem.text if elem.tag == '{http://www.vmware.com/vcloud/v1.5}EndAddress': iprangeT = elem.text #複数範囲は現状想定しない break return PccVAppNetwork(name, href, fencemode, gateway, netmask, dns1, dns2, iprangeF, iprangeT, primary)
def describeVolumes(self, vm): rasd_ns = '{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}' # Get virtualHardwareSection/disks section res = self.requestLoop('%s/virtualHardwareSection/disks' % get_url_path(vm["id"])) disks =[] for item in res.object.findall(fixxpath(res.object, 'Item')): if item.find('%sHostResource' % rasd_ns) is not None: name = item.find('%sInstanceID' % rasd_ns).text size = item.find('%sHostResource' % rasd_ns).get(fixxpath(item, 'capacity')) busType = item.find('%sHostResource' % rasd_ns).get(fixxpath(item, 'busType')) unitNo = item.find('%sAddressOnParent' % rasd_ns).text disks.append(PccVMDisk(name, size, busType, unitNo)) return disks
def _wait_for_task_completion(self, task_href, timeout=6000): import time from sys import stdout start_time = time.time() res = self.connection.request(get_url_path(task_href)) status = res.object.get('status') while status != 'success': if status == 'error': # Get error reason from the response body error_elem = res.object.find(fixxpath(res.object, 'Error')) error_msg = "Unknown error" if error_elem is not None: error_msg = error_elem.get('message') raise Exception("Error status returned by task %s.: %s" % (task_href, error_msg)) if status == 'canceled': raise Exception("Canceled status returned by task %s." % task_href) if time.time() - start_time >= timeout: raise Exception("Timeout (%s sec) while waiting for task %s." % (timeout, task_href)) stdout.write('.') stdout.flush() time.sleep(5) res = self.connection.request(get_url_path(task_href)) status = res.object.get('status')
def describeStorageProfile(self, vdc, sp_Name): res = self.requestLoop(get_url_path(vdc.id)).object for storageprofile in res.findall(fixxpath(res, 'VdcStorageProfiles/VdcStorageProfile')): if storageprofile.get('name') == sp_Name: return PccStorageProfile(storageprofile.get('name'), storageprofile.get('href')) return None
def _del_vm_disk(self, vm, disk_id): #ディスクIDが指定されていない場合は何もしない if disk_id is None: return rasd_ns = '{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}' # virtualHardwareSection/disks 取得 res = self.requestLoop('%s/virtualHardwareSection/disks' % get_url_path(vm["id"])) for item in res.object.findall(fixxpath(res.object, 'Item')): if item.find('%sHostResource' % rasd_ns) is not None: name = item.find('%sInstanceID' % rasd_ns).text if str(name) == str(disk_id): res.object.remove(item) self.logger.info(ET.tostring(res.object)) res = self.requestLoop( '%s/virtualHardwareSection/disks' % get_url_path(vm["id"]), data=ET.tostring(res.object), method='PUT', headers={'Content-Type': 'application/vnd.vmware.vcloud.rasditemslist+xml'} ) self._wait_for_task_completion(res.object.get('href'))
def describeVdcMyCloud(self, vdc): res = self.connection.request(get_url_path(vdc.id)) elms = res.object.findall(fixxpath( res.object, "ResourceEntities/ResourceEntity") ) vapps = [ (i.get('name'), i.get('href')) for i in elms if i.get('type') == 'application/vnd.vmware.vcloud.vApp+xml' and i.get('name') ] nodes = [] for vapp_name, vapp_href in vapps: try: res = self.connection.request( get_url_path(vapp_href), headers={'Content-Type': 'application/vnd.vmware.vcloud.vApp+xml'} ) nodes.append(self._to_node(res.object)) except Exception: self.logger.error(traceback.format_exc()) raise return nodes
def _wait_for_task_completion(self, task_href, timeout=6000): import time from sys import stdout start_time = time.time() res = self.connection.request(get_url_path(task_href)) status = res.object.get('status') while status != 'success': if status == 'error': # Get error reason from the response body error_elem = res.object.find(fixxpath(res.object, 'Error')) error_msg = "Unknown error" if error_elem is not None: error_msg = error_elem.get('message') raise Exception("Error status returned by task %s.: %s" % (task_href, error_msg)) if status == 'canceled': raise Exception("Canceled status returned by task %s." % task_href) if (time.time() - start_time >= timeout): raise Exception("Timeout (%s sec) while waiting for task %s." % (timeout, task_href)) stdout.write('.') stdout.flush() time.sleep(5) res = self.connection.request(get_url_path(task_href)) status = res.object.get('status')
def _wait_for_task_completion(self, task_href): #VCloud_1_5_NodeDriver._wait_for_task_completion(self, task_href, timeout = self.timeout) start_time = time.time() res = self.connection.request(get_url_path(task_href)) status = res.object.get('status') retry = 0 while status != 'success': if status == 'error': if retry > self.RETRY_MAX: # Get error reason from the response body error_elem = res.object.find(fixxpath(res.object, 'Error')) error_msg = "Unknown error" if error_elem is not None: error_msg = error_elem.get('message') raise Exception("Error status returned by task %s.: %s" % (task_href, error_msg)) else: retry = retry +1 if status == 'canceled': raise Exception("Canceled status returned by task %s." % task_href) if (time.time() - start_time >= self.timeout): raise Exception("Timeout (%s sec) while waiting for task %s." % (self.timeout, task_href)) time.sleep(5) res = self.connection.request(get_url_path(task_href)) status = res.object.get('status')
def _to_node(self, node_elm): node = super(ImprovedVCloud_5_1_Driver, self)._to_node(node_elm) virt_hardware = node_elm.find('.//ovf:VirtualHardwareSection', namespaces=node_elm.nsmap) n_cpu = 0 n_ram = 0 for item in virt_hardware.findall('ovf:Item', namespaces=node_elm.nsmap): res_type = item.findtext("{%s}ResourceType" % item.nsmap['rasd']) if res_type == '3': # CPU n_cpu = int( item.findtext('{%s}VirtualQuantity' % item.nsmap['rasd'])) elif res_type == '4': # Memory n_ram = int( item.findtext('{%s}VirtualQuantity' % item.nsmap['rasd'])) node.size = self._to_size(n_ram) node.size.cpus = n_cpu node.extra['size'] = _find_node_size(node.size) user = node_elm.find(fixxpath(node_elm, 'Owner/User')) node.extra['creator'] = user.get('name') return node
def describeImageHref(self, imagename): images = self.list_images() for image in images: res = self.requestLoop(image.id).object res_ents = res.findall(fixxpath(res, "Children/Vm")) for i in res_ents: if imagename == i.get("name"): return i.get("href")
def _add_vm_disk(self, vm, vm_disk): #ディスクが存在しない場合は何もしない if vm_disk is None: return rasd_ns = '{http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData}' # virtualHardwareSection/disks 取得 res = self.requestLoop('%s/virtualHardwareSection/disks' % get_url_path(vm["id"])) existing_ids = [] new_disk = None #既存ディスク情報のチェック for item in res.object.findall(fixxpath(res.object, 'Item')): for elem in item: if elem.tag == '%sInstanceID' % rasd_ns: existing_ids.append(int(elem.text)) if item.find('%sHostResource' % rasd_ns) is not None: new_disk = item #追加するディスク情報 new_disk = copy.deepcopy(new_disk) for elem in new_disk: #不要なパラメータを消す if elem.tag in ['%sAddressOnParent' % rasd_ns, '%sParent' % rasd_ns]: new_disk.remove(elem) disk_id = max(existing_ids) + 1 diskName = 'Hard Disk ' + str(disk_id) #new_disk.find('%sAddressOnParent' % rasd_ns).text = str(vm_disk["UNIT_NO"]) new_disk.find('%sInstanceID' % rasd_ns).text = str(disk_id) new_disk.find('%sElementName' % rasd_ns).text = diskName new_disk.find('%sHostResource' % rasd_ns).set(fixxpath(new_disk, 'capacity'), str(int(vm_disk["SIZE"]) * 1024)) res.object.append(new_disk) self.logger.info(ET.tostring(res.object)) res = self.requestLoop( '%s/virtualHardwareSection/disks' % get_url_path(vm["id"]), data=ET.tostring(res.object), method='PUT', headers={'Content-Type': 'application/vnd.vmware.vcloud.rasditemslist+xml'} ) self._wait_for_task_completion(res.object.get('href')) return disk_id
def getVdcStorageprofiles(self, vdc): res = self.requestLoop(get_url_path(vdc.id)).object #ストレージプロファイル storageprofiles = {} for storageprofile in res.findall(fixxpath(res, 'VdcStorageProfiles/VdcStorageProfile')): storageprofiles[storageprofile.get('name')] = PccStorageProfile(storageprofile.get('name'), storageprofile.get('href')) return storageprofiles
def _get_elems(self, uri, xpath): '''Get XML elements from a given URI and XPath search over returned XML content ''' res = self.driver.connection.request(get_url_path(uri)) if xpath.startswith('{'): return res.object.findall(xpath) else: return res.object.findall(fixxpath(res.object, xpath))
def describeVMNetwork(self, vm): res = self.requestLoop('%s/networkConnectionSection' % get_url_path(vm["id"])) print ET.tostring(res.object) primary_index = res.object.find(fixxpath(res.object, 'PrimaryNetworkConnectionIndex')).text net_conns = res.object.findall(fixxpath(res.object, 'NetworkConnection')) retNetworks = [] for item in net_conns: name = item.get('network') ipMode = item.find(fixxpath(item, 'IpAddressAllocationMode')).text ipAddress = item.find(fixxpath(item, 'IpAddress')).text index = item.find(fixxpath(item, 'NetworkConnectionIndex')).text isPrimary = False if index == primary_index: isPrimary = True retNetworks.append(PccVMNetwork(name, ipAddress, ipMode, index, isPrimary)) return retNetworks
def ex_edit_vm(self, vm_harf, **kwargs): storageProfile = kwargs.get('storageProfile') res = self.requestLoop(get_url_path(vm_harf)) #ストレージの変更 if storageProfile is not None: res.object.find(fixxpath(res.object, "StorageProfile")).set('name', storageProfile.name) res.object.find(fixxpath(res.object, "StorageProfile")).set('href', storageProfile.href) self.logger.info(ET.tostring(res.object)) ress = self.requestLoop(get_url_path(vm_harf), data=ET.tostring(res.object), method='PUT', headers={'Content-Type': 'application/vnd.vmware.vcloud.vm+xml'} ) self._wait_for_task_completion(ress.object.get('href'))
def describeImageNames(self, location=None): imageNames = [] images = self.list_images() for image in images: res = self.requestLoop(image.id).object res_ents = res.findall(fixxpath(res, "Children/Vm")) for i in res_ents: imageNames.append(i.get("name")) return imageNames
def _get_edgegateway_rec(self, edgegateway_uri): res = self.driver.connection.request(get_url_path(edgegateway_uri)) _log_etree_elem(res.object) edgegateway_rec_elems = res.object.findall(fixxpath(res.object, "EdgeGatewayRecord")) edgegateway_recs = [] for edgegateway_rec_elem in edgegateway_rec_elems: edgegateway_recs.append(self._et_class_walker(edgegateway_rec_elem)) return edgegateway_recs
def describeVappNetwork(self, vapp): vappnetworks = [] res = self.requestLoop(get_url_path(vapp.id)).object for networkconfig in res.findall(fixxpath(res, 'NetworkConfigSection/NetworkConfig')): name = networkconfig.get('networkName') #未設定用NW「'none'」は無視する if name == 'none': continue vappnetworks.append(self._makePccVAppNetwork(networkconfig, name)) return vappnetworks
def get_edgegateway_recs(self, edgegateway_uri): '''Retrieve Edge Gateway Records from the Edge Gateway query URI ''' res = self.driver.connection.request(get_url_path(edgegateway_uri)) _log_etree_elem(res.object) edgegateway_rec_elems = res.object.findall( fixxpath(res.object, self.__class__.EDGE_GATEWAY_REC_TAG)) edgegateway_recs = [et_utils.obj_from_elem_walker(edgegateway_rec_elem) for edgegateway_rec_elem in edgegateway_rec_elems] return edgegateway_recs
def _get_edgegateway_from_uri(self, edgegateway_rec_uri): res = self.driver.connection.request(get_url_path(edgegateway_rec_uri)) _log_etree_elem(res.object) gateway_iface_elems = res.object.findall(fixxpath(res.object, "GatewayInterface")) gateway = self._et_class_walker(res.object) # Augment gateway object with explicit reference to ElementTree elem gateway._elem = res.object return gateway
def describeVdcNetwork(self): vdc = self.getUseVdc() res = self.requestLoop(get_url_path(vdc.id)).object #VDCネットワーク vdcnetworks = [] for vdcnetworkconfig in res.findall(fixxpath(res, 'AvailableNetworks/Network')): name = vdcnetworkconfig.get('name') href = vdcnetworkconfig.get('href') res2 = self.requestLoop(get_url_path(href)).object vdcnetworks.append(self._makePccVAppNetwork(res2, name, href)) return vdcnetworks
def _get_elems(self, uri, xpath): '''Helper method - Get XML elements from a given URI and XPath search over returned XML content :var uri: URI to retrieve XML response from :var xpath: XPath to search returned XML content with. It can contain the {} delimited namespace or else the default vCloud one is assumed :return: ElementTree Element contain search results ''' res = self.driver.connection.request(get_url_path(uri)) _log_etree_elem(res.object) if xpath.startswith(et_utils.NS_START_DELIM): return res.object.findall(xpath) else: return res.object.findall(fixxpath(res.object, xpath))
def _instantiate_MyCloud(self, name, template, networks): instantiate_xml = InstantiateVAppXML( name=name, template=template, networks=networks ) # Instantiate VM and get identifier. res = self.requestLoop( '%s/action/instantiateVAppTemplate' % get_url_path(self.vdc.id), data=instantiate_xml.tostring(), method='POST', headers={'Content-Type': 'application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml'} ) vapp_href = res.object.get('href') task_href = res.object.find(fixxpath(res.object, "Tasks/Task")).get('href') self._wait_for_task_completion(task_href) return vapp_href
def _compose_MyCloud(self, vdc, name, useNetworks): compose_xml = ComposeVAppXML( name=name, useNetworks=useNetworks ) self.logger.info(compose_xml.tostring()) # Instantiate VM and get identifier. res = self.requestLoop( '%s/action/composeVApp' % get_url_path(vdc.id), data=compose_xml.tostring(), method='POST', headers={'Content-Type': 'application/vnd.vmware.vcloud.composeVAppParams+xml'} ) vapp_href = res.object.get('href') task_href = res.object.find(fixxpath(res.object, "Tasks/Task")).get('href') self._wait_for_task_completion(task_href) return vapp_href
def _to_node(self, node_elm): node = super(ImprovedVCloud_5_1_Driver, self)._to_node(node_elm) virt_hardware = node_elm.find('.//ovf:VirtualHardwareSection', namespaces=node_elm.nsmap) n_cpu = 0 n_ram = 0 for item in virt_hardware.findall('ovf:Item', namespaces=node_elm.nsmap): res_type = item.findtext("{%s}ResourceType" % item.nsmap['rasd']) if res_type == '3': # CPU n_cpu = int(item.findtext('{%s}VirtualQuantity' % item.nsmap['rasd'])) elif res_type == '4': # Memory n_ram = int(item.findtext('{%s}VirtualQuantity' % item.nsmap['rasd'])) node.size = self._to_size(n_ram) node.size.cpus = n_cpu # node.extra['size'] = _find_node_size(node.size) user = node_elm.find(fixxpath(node_elm, 'Owner/User')) node.extra['creator'] = user.get('name') return node
def _change_vm_ipmode(self, vapp_or_vm_id, vm_ipmode): if vm_ipmode[0] is 'MANUAL': vm_ipmode, ip_address, network = vm_ipmode else: vm_ipmode, network = vm_ipmode vms = self._get_vm_elements(vapp_or_vm_id) for vm in vms: res = self.connection.request( '%s/networkConnectionSection' % get_url_path(vm.get('href'))) net_conns = res.object.findall( fixxpath(res.object, 'NetworkConnection')) for c in net_conns: # TODO: What if we want a network other than 'default' # Can we pull the network out of the vm/vapp? c.attrib['network'] = network c.find(fixxpath(c, 'IpAddressAllocationMode')).text = vm_ipmode c.find(fixxpath(c, 'IsConnected')).text = "true" if vm_ipmode == 'MANUAL': # This is quite hacky. We probably don't want the same IP on # each interface etc. # We might not have an IP node ip = c.find(fixxpath(c, 'IpAddress')) if ip is None: ip = ET.SubElement(c, fixxpath(c, 'IpAddress')) # The order of the IpAddress element matter. Has to be after this :( conIdx = c.find(fixxpath(c, 'NetworkConnectionIndex')) c.remove(ip) c.insert(c.index(conIdx)+1, ip) ip.text = ip_address headers = { 'Content-Type': 'application/vnd.vmware.vcloud.networkConnectionSection+xml' } res = self.connection.request( '%s/networkConnectionSection' % get_url_path(vm.get('href')), data=ET.tostring(res.object), method='PUT', headers=headers ) self._wait_for_task_completion(res.object.get('href'))
def _change_vm_ipmode(self, vapp_or_vm_id, vm_ipmode): from IPython import embed embed() if type(vm_ipmode) is not tuple or vm_ipmode[0] is not 'MANUAL': return super(ImprovedVCloud_5_1_Driver, self)._change_vm_ipmode(vapp_or_vm_id, vm_ipmode) vm_ipmode, ip_address = vm_ipmode vms = self._get_vm_elements(vapp_or_vm_id) for vm in vms: res = self.connection.request('%s/networkConnectionSection' % get_url_path(vm.get('href'))) net_conns = res.object.findall( fixxpath(res.object, 'NetworkConnection')) for c in net_conns: # TODO: What if we want a network other than 'default' # c.attrib['network'] = 'Default' c.find(fixxpath(c, 'IpAddressAllocationMode')).text = vm_ipmode c.find(fixxpath(c, 'IsConnected')).text = "true" # This is quite hacky. We probably don't want the same IP on # each interface etc. # We might not have an IP node ip = c.find(fixxpath(c, 'IpAddress')) if ip is None: ip = ET.SubElement(c, fixxpath(c, 'IpAddress')) # The order of the IpAddress element matter. Has to be after this :( conIdx = c.find(fixxpath(c, 'NetworkConnectionIndex')) c.remove(ip) c.insert(c.index(conIdx) + 1, ip) ip.text = ip_address headers = { 'Content-Type': 'application/vnd.vmware.vcloud.networkConnectionSection+xml' } res = self.connection.request('%s/networkConnectionSection' % get_url_path(vm.get('href')), data=ET.tostring(res.object), method='PUT', headers=headers) self._wait_for_task_completion(res.object.get('href'))
def _change_vm_nw(self, vm_id, vm_nw): rasd_ns = "{http://www.vmware.com/vcloud/v1.5}" indexList = ["0","1","2","3","4","5","6","7","8","9","10",] #リストを名称キーのマップへ変換 editmap = {} makemap = {} for nw in vm_nw: if nw["NETWORK_INDEX"] is not None: editmap[str(nw["NETWORK_INDEX"])] = nw else: makemap[str(nw["NETWORK_NO"])] = nw isEdit = False vms = self._get_vm_elements(vm_id) for vm in vms: res = self.requestLoop('%s/networkConnectionSection' % get_url_path(vm.get('href'))) def_primary_index = res.object.find(fixxpath(res.object, 'PrimaryNetworkConnectionIndex')).text primary_index = def_primary_index net_conns = res.object.findall(fixxpath(res.object, 'NetworkConnection')) for item in net_conns: name = item.get('network') index = item.find(fixxpath(item, 'NetworkConnectionIndex')).text #対象の設定を取得 if not editmap.has_key(index): #取得できなければこのNWは削除 res.object.remove(item) isEdit = True else: #利用済インデックスをリストから削除 indexList.remove(index) #取得できれば設定を比較 newNw = editmap.pop(index) #Primary チェック if isBit(newNw["IS_PRIMARY"]): primary_index = newNw["NETWORK_INDEX"] #IPMODE if newNw["IP_MODE"] != item.find(fixxpath(item, 'IpAddressAllocationMode')).text: item.find(fixxpath(item, 'IpAddressAllocationMode')).text = newNw["IP_MODE"] isEdit = True if newNw["IP_MODE"] == "MANUAL": #設定「MANUAL」の場合はアドレスも変更する item.find(fixxpath(item, 'IpAddress')).text = newNw["IP_ADDRESS"] else: if newNw["IP_ADDRESS"] != item.find(fixxpath(item, 'IpAddress')).text: #IPアドレスのみ変更する場合 item.find(fixxpath(item, 'IpAddress')).text = newNw["IP_ADDRESS"] isEdit = True #邪魔なのでLinkタグを消す link = res.object.find(fixxpath(res.object, 'Link')) res.object.remove(link) #追加ネットワークの登録 if len(makemap) > 0: for key in makemap: newNw = makemap[key] networkConnection = ET.Element('%sNetworkConnection' % rasd_ns, {'network': newNw["NETWORK_NAME"]} ) ET.SubElement(networkConnection, '%sNetworkConnectionIndex' % rasd_ns).text = str(indexList[0]) #Primary チェック if isBit(newNw["IS_PRIMARY"]): primary_index = indexList[0] if isNotEmpty(newNw["IP_ADDRESS"]): ET.SubElement(networkConnection, '%sIpAddress' % rasd_ns).text = newNw["IP_ADDRESS"] ET.SubElement(networkConnection, '%sIsConnected' % rasd_ns).text = "true" ET.SubElement(networkConnection, '%sIpAddressAllocationMode' % rasd_ns).text = newNw["IP_MODE"] res.object.append(networkConnection) isEdit = True indexList.remove(indexList[0]) if str(def_primary_index) != str(primary_index): #プライマリの再設定 res.object.find(fixxpath(res.object, 'PrimaryNetworkConnectionIndex')).text = str(primary_index) isEdit = True #取っ払ったLinkを戻す res.object.append(link) self.logger.info(ET.tostring(res.object)) #変更を行った場合のみ通信する if isEdit: self.logger.info(ET.tostring(res.object)) res = self.requestLoop( '%s/networkConnectionSection' % get_url_path(vm.get('href')), data=ET.tostring(res.object), method='PUT', headers={'Content-Type': 'application/vnd.vmware.vcloud.networkConnectionSection+xml'} ) self._wait_for_task_completion(res.object.get('href'))
def _to_node(self, node_elm): publicNetworkName = getOtherProperty("vCloud.PCCNetwork") # Parse VMs as extra field vms = [] for vm_elem in node_elm.findall(fixxpath(node_elm, 'Children/Vm')): public_ips = [] private_ips = [] other_ips = [] for connection in vm_elem.findall(fixxpath(vm_elem, 'NetworkConnectionSection/NetworkConnection')): if connection.attrib['network'] != "none": ip = connection.find(fixxpath(connection, "IpAddress")) if connection.attrib['network'] == publicNetworkName: public_ips.append(ip.text) else: if connection.attrib['network'] == self.defnet: private_ips.append(ip.text) else: other_ips.append(ip.text) #デフォルトネットワークが無い(private_ipが無い)場合 #その他の1つ目をprivate_ipへ設定 if len(private_ips) == 0 and len(other_ips) > 0: private_ips.append(other_ips[0]) ######################################## #プライベートIPの設定に関し別案 ######################################## # primary_ips = [] # def_ips = [] # primary_index = vm_elem.object.find(fixxpath(vm_elem, 'NetworkConnectionSection/PrimaryNetworkConnectionIndex')).text # for connection in vm_elem.findall(fixxpath(vm_elem, 'NetworkConnectionSection/NetworkConnection')): # if connection.attrib['network'] != "none": # ip = connection.find(fixxpath(connection, "IpAddress")) # index = connection.find(fixxpath(connection, "NetworkConnectionIndex")) # if connection.attrib['network'] == publicNetworkName: # public_ips.append(ip.text) # else: # if index == primary_index: # primary_ips.append(ip.text) # # if connection.attrib['network'] == self.defnet: # def_ips.append(ip.text) # else: # other_ips.append(ip.text) # # #プライベートUPの設定順 # # 1:プライマリネットワーク(PCCネットワークの場合は除外) # # 2:デフォルトネットワーク # # 3:その他ネットワーク # if len(primary_ips) != 0: # private_ips.append(primary_ips[0]) # else: # if len(def_ips) != 0: # private_ips.append(other_ips[0]) # elif len(other_ips) > 0: # private_ips.append(other_ips[0]) #VMへ設定 vm = { 'id': vm_elem.get('href'), 'name': vm_elem.get('name'), 'state': self.NODE_STATE_MAP[vm_elem.get('status')], 'public_ips': public_ips, 'private_ips': private_ips, 'storageprofile':vm_elem.find(fixxpath(vm_elem, 'StorageProfile')).get('name'), } vms.append(vm) # Take the node IP addresses from all VMs public_ips = [] private_ips = [] for vm in vms: public_ips.extend(vm['public_ips']) private_ips.extend(vm['private_ips']) # Find vDC vdc_id = next(link.get('href') for link in node_elm.findall(fixxpath(node_elm, 'Link')) if link.get('type') == 'application/vnd.vmware.vcloud.vdc+xml') vdc = next(vdc for vdc in self.vdcs if vdc.id == vdc_id) # Find TASK tasks = node_elm.findall(fixxpath(node_elm, 'Tasks/Task')) isTask = False if len(tasks) > 0: isTask = True node = Node(id=node_elm.get('href'), name=node_elm.get('name'), state=self.NODE_STATE_MAP[node_elm.get('status')], public_ips=public_ips, private_ips=private_ips, driver=self.connection.driver, extra={'vdc': vdc.name, 'vms': vms, 'task': isTask}) return node
def _update_edgegateway(self, gateway, iface_name='EXT-INTERNET-TEST', internal_ip='192.168.0.6', external_ip='130.246.139.249'): '''Update Edge Gateway with settings provided''' # Find update endpoint update_uri = None for link in gateway.link: if link.rel == self.__class__.CONFIG_EDGE_GATEWAY_URI: update_uri = link.href break if update_uri is None: self.fail('No Gateway update URI found in Gateway response') self._ns = et_get_namespace(gateway._elem) # Get the update elements - the update interface expects a # <EdgeGatewayServiceConfiguration/> top-level element gateway_service_conf_elem = gateway._elem.find( fixxpath(gateway._elem, self.__class__.EDGE_GATEWAY_SERVICE_CONF_XPATH)) if gateway_service_conf_elem is None: self.fail('No <EdgeGatewayServiceConfiguration/> element found ' '<EdgeGateway/> settings returned from service') # Check allocation of external IPs # Get interface URI iface_uri = None for interface in \ gateway.configuration.gateway_interfaces.gateway_interface: if interface.name.value_ == iface_name: iface_uri = interface.network.href break if iface_uri is None: self.msg('Interface found with name %r' % iface_name) # Check rule IDs already allocated highest_nat_rule_id = 0 nat_service = \ gateway.configuration.edge_gateway_service_configuration.nat_service for nat_rule in nat_service.nat_rule: if nat_rule.id.value_ > highest_nat_rule_id: highest_nat_rule_id = nat_rule.id.value_ next_nat_rule_id = highest_nat_rule_id + 1 # Check external IP is not already used in an existing rule # TODO: should this necessarily be a fatal error? for nat_rule in nat_service.nat_rule: gw_rule = nat_rule.gateway_nat_rule if (external_ip in (gw_rule.original_ip.value_, gw_rule.translated_ip.value_)): self.fail('Required external IP address %r has already been ' 'used in an existing NAT rule (id %r)' % (external_ip, nat_rule.id.value_)) # Source NAT rule snat_rule = NatRule(rule_type=self.__class__.SRC_NAT_RULE_TYPE, rule_id=str(next_nat_rule_id), rule_is_enabled=True, iface_uri=iface_uri, iface_name=iface_name, orig_ip=internal_ip, transl_ip=external_ip) nat_service_elem = gateway._elem.find( fixxpath(gateway._elem, self.__class__.NAT_SERVICE_XPATH)) if nat_service_elem is None: self.fail('No <NatService/> element found in returned Edge Gateway ' 'configuration') nat_service_elem.append(self._create_nat_rule(snat_rule)) # Destination NAT rule next_nat_rule_id += 1 dnat_rule = NatRule(rule_type=self.__class__.DEST_NAT_RULE_TYPE, rule_id=str(next_nat_rule_id), rule_is_enabled=True, iface_uri=iface_uri, iface_name=iface_name, orig_ip=external_ip, transl_ip=internal_ip) nat_service_elem.append(self._create_nat_rule(dnat_rule)) _log_etree_elem(gateway._elem) # Despatch updated configuration gateway_service_conf_xml = ET.tostring(gateway_service_conf_elem) res = self.driver.connection.request(get_url_path(update_uri), method='POST', data=gateway_service_conf_xml) self.assert_(res) _log_etree_elem(res.object)