def ex_get_node(self, node_id, project=None):
        """
        Return a Node object based on its ID.

        :param  node_id: The id of the node
        :type   node_id: ``str``

        :keyword    project: Limit node returned to those configured under
                             the defined project.
        :type       project: :class:`.CloudStackProject`

        :rtype: :class:`CloudStackNode`
        """
        list_nodes_args = {'id': node_id}
        list_ips_args = {}
        if project:
            list_nodes_args['projectid'] = project.id
            list_ips_args['projectid'] = project.id
        vms = self._sync_request('listVirtualMachines', params=list_nodes_args)
        if not vms:
            raise Exception("Node '%s' not found" % node_id)
        vm = vms['virtualmachine'][0]
        addrs = self._sync_request('listPublicIpAddresses',
                                   params=list_ips_args)

        public_ips = {}
        for addr in addrs.get('publicipaddress', []):
            if 'virtualmachineid' not in addr:
                continue
            public_ips[addr['ipaddress']] = addr['id']

        node = self._to_node(data=vm, public_ips=list(public_ips.keys()))

        addresses = [CloudStackAddress(id=address_id, address=address,
                                       driver=node.driver) for
                     address, address_id in public_ips.items()]
        node.extra['ip_addresses'] = addresses

        rules = []
        list_fw_rules = {'virtualmachineid': node_id}
        for addr in addresses:
            result = self._sync_request('listIpForwardingRules',
                                        params=list_fw_rules)
            for r in result.get('ipforwardingrule', []):
                if str(r['virtualmachineid']) == node.id:
                    rule = CloudStackIPForwardingRule(node, r['id'],
                                                      addr,
                                                      r['protocol']
                                                      .upper(),
                                                      r['startport'],
                                                      r['endport'])
                    rules.append(rule)
        node.extra['ip_forwarding_rules'] = rules

        rules = []
        public_ips = self.ex_list_public_ips()
        result = self._sync_request('listPortForwardingRules',
                                    params=list_fw_rules)
        for r in result.get('portforwardingrule', []):
            if str(r['virtualmachineid']) == node.id:
                addr = [a for a in public_ips if
                        a.address == r['ipaddress']]
                rule = CloudStackPortForwardingRule(node, r['id'],
                                                    addr[0],
                                                    r['protocol'].upper(),
                                                    r['publicport'],
                                                    r['privateport'],
                                                    r['publicendport'],
                                                    r['privateendport'])
                if not addr[0].address in node.public_ips:
                    node.public_ips.append(addr[0].address)
                rules.append(rule)
        node.extra['port_forwarding_rules'] = rules
        return node
dataset/ETHPy150Open apache/libcloud/libcloud/compute/drivers/cloudstack.py/CloudStackNodeDriver.ex_get_node/original