<commit_before>#
# Copyright (c) 2010 rPath, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.rpath.com/permanent/licenses/CPL-1.0.
#
# This program is distributed in the hope that it will be useful, but
# without any warranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the Common Public License for
# full details.
#

import logging

from twisted.internet import error as internet_error
from twisted.internet import reactor
from rmake3.core import plug_dispatcher
from rmake3.lib import netlink
from rpath_repeater.utils import base_forwarding_plugin as bfp

log = logging.getLogger(__name__)

class NodeReportingPlugin(plug_dispatcher.DispatcherPlugin):
    HEARTBEAT = 600
    def dispatcher_post_setup(self, dispatcher):
        self.setUpHeartbeat(dispatcher)
        self.getLocalAddressses(dispatcher)

    def setUpHeartbeat(self, dispatcher):
        reactor.callLater(self.HEARTBEAT, self.setUpHeartbeat, dispatcher)
        self.syncWorkers(dispatcher)

    def dispatcher_worker_up(self, dispatcher, worker):
        self.syncWorkers(dispatcher)

    def dispatcher_worker_down(self, dispatcher, worker):
        self.syncWorkers(dispatcher)

    def getLocalAddressses(self, dispatcher):
        rtnl = netlink.RoutingNetlink()
        self.localAddresses = set(x[1] for x in rtnl.getAllAddresses())
        return self.localAddresses

    def syncWorkers(self, dispatcher):
        children = []
        for workerJid, worker in dispatcher.workers.items():
            children.append(self._getWorkerData(worker))
        if not children:
            # Cowardly refuse to update the list if all nodes are marked as
            # being down
            return
        node = bfp.XML.Element('management_nodes', *children)
        data = self.toXml(node)
        self.postResults(data)

    @classmethod
    def toXml(self, elt):
        return bfp.XML.toString(elt)

    def _getWorkerData(self, worker):
        E = bfp.XML.Element
        T = bfp.XML.Text
        children = []
        children.append(T("node_jid", worker.jid.full()))
        if worker.zoneNames:
            # We only support one zone per management node
            children.append(E('zone', T('name', worker.zoneNames[0])))
        ipv4, ipv6 = self._splitAddressTypes(worker.addresses)
        # Prefer the ipv4 address for display purposes
        if ipv4:
            hname = min(ipv4)
        else:
            hname = min(ipv6)
        children.append(T("hostname", "rPath Update Service - %s" % hname))
        isLocal = str(bool(self.localAddresses.intersection(worker.addresses))).lower()
        networks = [ E("network",
            T("ip_address", x), T("dns_name", x), T("device_name", "eth0"))
            for x in sorted(ipv4) ]
        networks.extend(E("network",
            T("ipv6_address", x), T("dns_name", x), T("device_name", "eth0"))
            for x in sorted(ipv6))
        children.append(E("networks", *networks))
        children.append(T("local", isLocal))
        node = E("management_node", *children)
        return node

    @classmethod
    def _splitAddressTypes(cls, addresses):
        "Separate ipv4 and ipv6 addresses"
        ipv4 = set()
        ipv6 = set()
        for addr in addresses:
            if ':' in addr:
                ipv6.add(addr)
            else:
                ipv4.add(addr)
        return ipv4, ipv6

    def postResults(self, data):
        path = "/api/v1/inventory/management_nodes"
        host = "localhost"
        port = 80
        headers = {
            'Content-Type' : 'application/xml; charset="utf-8"',
            'Host' : host, }
        fact = bfp.HTTPClientFactory(path, method='PUT', postdata=data,
            headers = headers)
        @fact.deferred.addCallback
        def processResult(result):
            print "Received result for %s: %s" % (host, result)
            return result

        @fact.deferred.addErrback
        def processError(error):
            err = error.value
            if isinstance(err, internet_error.ConnectionDone):
                return
            print "Error: %s" % error.getErrorMessage()

        reactor.connectTCP(host, port, fact)

<commit_msg>Using the proper HTTPClientFactory<commit_after>#
# Copyright (c) 2010 rPath, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.rpath.com/permanent/licenses/CPL-1.0.
#
# This program is distributed in the hope that it will be useful, but
# without any warranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the Common Public License for
# full details.
#

import logging

from twisted.internet import error as internet_error
from twisted.internet import reactor
from rmake3.core import plug_dispatcher
from rmake3.lib import netlink
from rpath_repeater.utils import base_forwarding_plugin as bfp
from rpath_repeater.utils import http

log = logging.getLogger(__name__)

class NodeReportingPlugin(plug_dispatcher.DispatcherPlugin):
    HEARTBEAT = 600
    def dispatcher_post_setup(self, dispatcher):
        self.setUpHeartbeat(dispatcher)
        self.getLocalAddressses(dispatcher)

    def setUpHeartbeat(self, dispatcher):
        reactor.callLater(self.HEARTBEAT, self.setUpHeartbeat, dispatcher)
        self.syncWorkers(dispatcher)

    def dispatcher_worker_up(self, dispatcher, worker):
        self.syncWorkers(dispatcher)

    def dispatcher_worker_down(self, dispatcher, worker):
        self.syncWorkers(dispatcher)

    def getLocalAddressses(self, dispatcher):
        rtnl = netlink.RoutingNetlink()
        self.localAddresses = set(x[1] for x in rtnl.getAllAddresses())
        return self.localAddresses

    def syncWorkers(self, dispatcher):
        children = []
        for workerJid, worker in dispatcher.workers.items():
            children.append(self._getWorkerData(worker))
        if not children:
            # Cowardly refuse to update the list if all nodes are marked as
            # being down
            return
        node = bfp.XML.Element('management_nodes', *children)
        data = self.toXml(node)
        self.postResults(data)

    @classmethod
    def toXml(self, elt):
        return bfp.XML.toString(elt)

    def _getWorkerData(self, worker):
        E = bfp.XML.Element
        T = bfp.XML.Text
        children = []
        children.append(T("node_jid", worker.jid.full()))
        if worker.zoneNames:
            # We only support one zone per management node
            children.append(E('zone', T('name', worker.zoneNames[0])))
        ipv4, ipv6 = self._splitAddressTypes(worker.addresses)
        # Prefer the ipv4 address for display purposes
        if ipv4:
            hname = min(ipv4)
        else:
            hname = min(ipv6)
        children.append(T("hostname", "rPath Update Service - %s" % hname))
        isLocal = str(bool(self.localAddresses.intersection(worker.addresses))).lower()
        networks = [ E("network",
            T("ip_address", x), T("dns_name", x), T("device_name", "eth0"))
            for x in sorted(ipv4) ]
        networks.extend(E("network",
            T("ipv6_address", x), T("dns_name", x), T("device_name", "eth0"))
            for x in sorted(ipv6))
        children.append(E("networks", *networks))
        children.append(T("local", isLocal))
        node = E("management_node", *children)
        return node

    @classmethod
    def _splitAddressTypes(cls, addresses):
        "Separate ipv4 and ipv6 addresses"
        ipv4 = set()
        ipv6 = set()
        for addr in addresses:
            if ':' in addr:
                ipv6.add(addr)
            else:
                ipv4.add(addr)
        return ipv4, ipv6

    def postResults(self, data):
        path = "/api/v1/inventory/management_nodes"
        host = "localhost"
        port = 80
        headers = {
            'Content-Type' : 'application/xml; charset="utf-8"',
            'Host' : host, }
        fact = http.HTTPClientFactory(path, method='PUT', postdata=data,
            headers = headers)
        @fact.deferred.addCallback
        def processResult(result):
            print "Received result for %s: %s" % (host, result)
            return result

        @fact.deferred.addErrback
        def processError(error):
            err = error.value
            if isinstance(err, internet_error.ConnectionDone):
                return
            print "Error: %s" % error.getErrorMessage()

        reactor.connectTCP(host, port, fact)


{'fraction_non_alphanumeric': 0.09865621500559911, 'fraction_numerical': 0.00851063829787234, 'mean_word_length': 2.5539196179864705, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1547105', 'n_tokens_mistral': 2631, 'n_tokens_neox': 2577, 'n_words': 707}