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
Пример #3
0
    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
Пример #19
0
    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
Пример #22
0
 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
Пример #25
0
    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)