Beispiel #1
0
    def addClient(self, device_uuid):
        cfg_file = os.path.join(self.__repo_path, "config")
        config = self._git_get_config(cfg_file)

        section = 'remote "%s"' % device_uuid
        if not config.has_section(section):
            cs = PluginRegistry.getInstance("ClientService")
            key = self._get_public_key()

            if not key[1] in [p["data"] for p in cs.clientDispatch(device_uuid, "puppetListKeys").values()]:
                cs.clientDispatch(device_uuid, "puppetAddKey", [key])

            # Update git if needed
            release = self.__get_client_release(device_uuid)
            self.gitPush(self.getBaseDir(release))

            # Update nodes.pp
            self.__update_node(device_uuid)

            # Add git configuration
            config.add_section(section)

            # Build push URL for client, it needs to be online
            try:
                url = cs.clientDispatch(device_uuid, "puppetGetPushPath")
                config.set(section, "url", url)
                with open(cfg_file, "w") as f:
                    config.write(f)
            except:
                return False

            # Reset "P" flag for client
            cs = PluginRegistry.getInstance("ClientService")
            cs.systemSetStatus(device_uuid, "-P")
            return True
Beispiel #2
0
    def serve(self):
        """ Start MQTT service for this gosa service provider. """
        # Load MQTT and Command registry instances
        self.client = PluginRegistry.getInstance('MQTTClientHandler')
        self.client.get_client().add_connection_listener(self._on_connection_change)
        self.__cr = PluginRegistry.getInstance('ClientCommandRegistry')

        self.client.set_subscription_callback(self._handle_message)
Beispiel #3
0
    def serve(self):
        self.log.info("listening for asterisk events...")
        amqp = PluginRegistry.getInstance('AMQPHandler')
        EventConsumer(self.env,
            amqp.getConnection(),
            xquery="""
                declare namespace f='http://www.gonicus.de/Events';
                let $e := ./f:Event
                return $e/f:AsteriskNotification
            """,
            callback=self.process)

        self.__cr = PluginRegistry.getInstance("CommandRegistry")
Beispiel #4
0
    def serve(self):
        """ Start MQTT service for this gosa service provider. """
        # Load MQTT and Command registry instances
        mqtt = PluginRegistry.getInstance('MQTTClientHandler')
        self.__cr = PluginRegistry.getInstance('ClientCommandRegistry')

        mqtt.set_subscription_callback(self._handle_message)

        self.__announce(True)

        # Send a ping on a regular base
        timeout = float(self.env.config.get('client.ping-interval', default=600))
        sched = PluginRegistry.getInstance("SchedulerService").get_scheduler()
        sched.add_interval_job(self.__ping, seconds=timeout, start_date=datetime.datetime.now() + datetime.timedelta(seconds=1))
Beispiel #5
0
def shutdown(a=None, b=None):
    """ Function to shut down the client. """
    global loop

    env = Environment.getInstance()
    env.log.info("GOsa DBUS is shutting down")

    # Shutdown plugins
    PluginRegistry.shutdown()
    if loop:
        loop.quit()

    logging.shutdown()
    exit(0)
Beispiel #6
0
    def _on_connection_change(self, connected):
        if connected is True:
            if self.__last_announce is None or self.__last_announce < (datetime.datetime.now() - datetime.timedelta(minutes=5)):
                self.__announce(send_client_announce=True, send_user_session=True)

            # Send a ping on a regular base
            if self._ping_job is None:
                timeout = float(self.env.config.get('client.ping-interval', default=600))
                sched = PluginRegistry.getInstance("SchedulerService").getScheduler()
                self._ping_job = sched.add_interval_job(self.__ping, seconds=timeout, start_date=datetime.datetime.now() + datetime.timedelta(seconds=1))
        else:
            if self._ping_job is not None:
                sched = PluginRegistry.getInstance("SchedulerService").getScheduler()
                sched.unschedule_job(self._ping_job)
                self._ping_job = None
Beispiel #7
0
    def __init__(self):
        env = Environment.getInstance()
        self.log = logging.getLogger(__name__)
        self.log.debug("initializing AMQP handler")
        self.env = env
        self.config = env.config

        # Initialize parser
        schema_root = etree.XML(PluginRegistry.getEventSchema())
        schema = etree.XMLSchema(schema_root)
        self._parser = objectify.makeparser(schema=schema)

        # Evaluate username
        user = self.config.get("amqp.id", default=None)
        if not user:
            user = self.env.uuid
        password = self.config.get("amqp.key")

        # Load configuration
        self.url = parseURL(makeAuthURL(self.config.get('amqp.url'), user, password))
        self.reconnect = self.config.get('amqp.reconnect', True)
        self.reconnect_interval = self.config.get('amqp.reconnect_interval', 3)
        self.reconnect_limit = self.config.get('amqp.reconnect_limit', 0)

        # Go for it
        self.start()
Beispiel #8
0
    def _handleClientAnnounce(self, data):
        data = data.ClientAnnounce
        client = data.Id.text
        self.log.info("client '%s' is joining us" % client)
        self.systemSetStatus(client, "+O-o")

        # Assemble network information
        network = {}
        for interface in data.NetworkInformation.NetworkDevice:
            network[interface.Name.text] = {
                'IPAddress': interface.IPAddress.text,
                'IPv6Address': interface.IPv6Address.text,
                'MAC': interface.MAC.text,
                'Netmask': interface.Netmask.text,
                'Broadcast': interface.Broadcast.text}

        # Add recieve time to be able to sort out dead nodes
        t = datetime.datetime.utcnow()
        info = {
            'name': data.Name.text,
            'last-seen': t,
            'online': True,
            'caps': {},
            'network': network
        }

        self.__client[data.Id.text] = info

        # Handle pending "P"repare actions for that client
        if "P" in self.systemGetStatus(client):
            try:
                rm = PluginRegistry.getInstance("RepositoryManager")
                rm.prepareClient(client)
            except ValueError:
                pass
Beispiel #9
0
    def preUserSession(self, client_id, user_name, skip_config=False):
        sobj = PluginRegistry.getInstance("SchedulerService")
        # delay changes, send configuration first
        if client_id not in self.__user_session:
            self.__user_session[client_id] = [user_name]
        elif user_name not in self.__user_session[client_id]:
            self.__user_session[client_id].append(user_name)

        if self.env.mode == "proxy":
            # answer config locally and proceed the write-part of the call to the GOsa backend
            if self.__current_backend_rpc is None or self.__current_backend_rpc.done() is True:
                self.log.info("calling preUserSession(%s, %s, skip_config=True) on master backend" % (client_id, user_name))
                self.__current_backend_rpc = self.__cr.dispatchRemote(client_id, None, 'preUserSession', client_id, user_name, skip_config=True)

            if skip_config is False:
                user_config = self.__collect_user_configuration(client_id, [user_name])
                if user_config is not None and user_name in user_config:
                    return user_config[user_name]

        elif skip_config is True:
            self.__maintain_user_session(client_id, user_name)
        else:
            # normal (non-proxy) mode -> return the config and schedule the user_session maintenance
            # to prevent it from blocking the config generation
            sobj.getScheduler().add_date_job(self.__maintain_user_session,
                                             datetime.datetime.now() + datetime.timedelta(milliseconds=250),
                                             args=(client_id, user_name),
                                             tag='_internal', jobstore='ram')

            user_config = self.__collect_user_configuration(client_id, [user_name])
            if user_config is not None and user_name in user_config:
                return user_config[user_name]

        return None
Beispiel #10
0
    def clientDispatch(self, client, method, *arg, **larg):
        """
        Dispatch a method on the client.

        ========= ================================
        Parameter Description
        ========= ================================
        client    Device UUID of the client
        method    Method name to call
        *         Method arguments
        ========= ================================

        ``Return:`` varies
        """

        # Bail out if the client is not available
        if not client in self.__client:
            raise JSONRPCException("client '%s' not available" % client)

        # Generate tage queue name
        queue = '%s.client.%s' % (self.env.domain, client)
        self.log.debug("got client dispatch: '%s(%s)', sending to %s" % (method, arg, queue))

        # client queue -> amqp rpc proxy
        if not client in self.__proxy:
            amqp = PluginRegistry.getInstance("AMQPHandler")
            self.__proxy[client] = AMQPServiceProxy(amqp.url['source'], queue)

        # Call her to the moon...
        methodCall = getattr(self.__proxy[client], method)

        # Do the call
        res = methodCall(*arg, **larg)
        return res
Beispiel #11
0
def netactivity(online):
    global netstate
    env = Environment.getInstance()
    if online:
        netstate = True
        env.active = True
    else:
        env = Environment.getInstance()
        netstate = False

        # Function to shut down the client. Do some clean up and close sockets.
        try:
            mqtt = PluginRegistry.getInstance("MQTTClientHandler")

            # Tell others that we're away now
            e = EventMaker()
            goodbye = e.Event(e.ClientLeave(e.Id(env.uuid)))
            if mqtt:
                mqtt.send_event(goodbye, qos=1)

        except ValueError:
            pass
        finally:
            env.reset_requested = True
            env.active = False
Beispiel #12
0
    def commandReceived(self, topic, message):
        """
        Process incoming commands, coming in with session and message
        information.

        ================= ==========================
        Parameter         Description
        ================= ==========================
        message           Received MQTT message
        ================= ==========================

        Incoming messages are coming from an
        :class:`gosa.common.components.mqtt_proxy.MQTTServiceProxy`. The command
        result is written to the '<domain>.client.<client-uuid>' queue.
        """
        err = None
        res = None
        name = None
        args = None
        id_ = ''

        response_topic = "%s/to-backend" % "/".join(topic.split("/")[0:4])

        try:
            req = loads(message)
        except Exception as e:
            err = str(e)
            self.log.error("ServiceRequestNotTranslatable: %s" % err)
            req = {'id': topic.split("/")[-2]}

        if err is None:
            try:
                id_ = req['id']
                name = req['method']
                args = req['params']

            except KeyError as e:
                self.log.error("KeyError: %s" % e)
                err = str(BadServiceRequest(message))

        self.log.debug("received call [%s] for %s: %s(%s)" % (id_, topic, name, args))

        # Try to execute
        if err is None:
            try:
                res = self.__cr.dispatch(name, *args)
            except Exception as e:
                err = str(e)

                # Write exception to log
                exc_type, exc_value, exc_traceback = sys.exc_info()
                self.log.error(traceback.format_exception(exc_type, exc_value, exc_traceback))

        self.log.debug("returning call [%s]: %s / %s" % (id_, res, err))

        response = dumps({"result": res, "id": id_})

        # Get rid of it...
        mqtt = PluginRegistry.getInstance('MQTTClientHandler')
        mqtt.send_message(response, topic=response_topic)
Beispiel #13
0
 def process_IN_CREATE(self, event):
     self.log.debug("logwatch detected change for '%s'" % event.pathname)
     if event.pathname.endswith(".yaml"):
         sleep(1)
         amqp = PluginRegistry.getInstance("AMQPClientHandler")
         self.log.debug("puppet logwatch detected change for '%s', producing event" % event.pathname)
         amqp.sendEvent(self.report_to_event(event.pathname))
Beispiel #14
0
def shutdown(a=None, b=None):
    env = Environment.getInstance()

    # Function to shut down the client. Do some clean up and close sockets.
    amqp = PluginRegistry.getInstance("AMQPClientHandler")

    # Tell others that we're away now
    e = EventMaker()
    goodbye = e.Event(e.ClientLeave(e.Id(env.uuid)))
    amqp.sendEvent(goodbye)

    # Shutdown plugins
    PluginRegistry.shutdown()

    logging.shutdown()
    exit(0)
Beispiel #15
0
    def process(self, data):

        # for some reason we need to convert to string and back
        cstr = etree.tostring(data, pretty_print = True)
        dat = etree.fromstring(cstr)

        event = {}
        for t in dat[0]:
            tag = re.sub(r"^\{.*\}(.*)$", r"\1", t.tag)
            if t.tag == 'From':
                event[tag] = t.text.split(" ")[0]
            else:
                event[tag] = str(t.text)

        # Resolve numbers with all resolvers, sorted by priority
        i_from = None
        i_to = None

        for mod, info in sorted(self.resolver.iteritems(),
                key=lambda k: k[1]['priority']):
            if not i_from:
                i_from = info['object'].resolve(event['From'])
            if not i_to:
                i_to = info['object'].resolve(event['To'])
            if i_from and i_to:
                break

        # Fallback to original number if nothing has been found
        if not i_from:
            i_from = {'contact_phone': event['From'], 'contact_name': event['From'],
                    'company_name': None, 'resource': 'none'}
        if not i_to:
            i_to = {'contact_phone': event['To'], 'contact_name': event['To'],
                    'company_name': None, 'resource': 'none'}

        # Render messages
        to_msg = from_msg = ""
        for mod, info in sorted(self.renderer.iteritems(),
                key=lambda k: k[1]['priority']):

            if 'ldap_uid' in i_to and i_to['ldap_uid']:
                to_msg += info['object'].getHTML(i_from, event)
                to_msg += "\n\n"

            if 'ldap_uid' in i_from and i_from['ldap_uid'] and event['Type'] == 'CallEnded':
                from_msg += info['object'].getHTML(i_to, event)
                from_msg += "\n\n"

        # Send from/to messages as needed
        amqp = PluginRegistry.getInstance('AMQPHandler')
        if from_msg:
            self.__cr.dispatch(amqp.url['user'], None, "notifyUser",
                i_from['ldap_uid'], self.TYPE_MAP[event['Type']],
                from_msg.strip())

        if to_msg:
            self.__cr.dispatch(amqp.url['user'], None, "notifyUser",
                    i_to['ldap_uid'], self.TYPE_MAP[event['Type']],
                    to_msg.strip())
Beispiel #16
0
def shutdown(a=None, b=None):
    global dr

    env = Environment.getInstance()
    log = logging.getLogger(__name__)

    # Function to shut down the client. Do some clean up and close sockets.

    # Function to shut down the client. Do some clean up and close sockets.
    mqtt = PluginRegistry.getInstance("MQTTClientHandler")

    # Tell others that we're away now
    e = EventMaker()
    goodbye = e.Event(e.ClientLeave(e.Id(env.uuid)))
    if mqtt:
        log.info("sending ClientLeave")
        mqtt.send_event(goodbye, qos=1)

    # Shutdown plugins
    PluginRegistry.shutdown()

    #TODO: remove this hack
    wait = 1
    for t in env.threads:
        if t.isAlive():
            log.warning("thread %s still alive" % t.getName())
            if hasattr(t, 'stop'):
                log.warning("calling 'stop' for thread %s" % t.getName())
                t.stop()
            if hasattr(t, 'cancel'):
                log.warning("calling 'cancel' for thread %s" % t.getName())
                t.cancel()
            t.join(wait)

        if t.is_alive():
            try:
                log.warning("calling built in 'stop' for thread %s" % t.getName())
                t._stop()
            except:
                log.error("could not stop thread %s" % t.getName())

    dr.stop()

    log.info("shut down")
    logging.shutdown()
Beispiel #17
0
    def __open_device(self, device_uuid, read_only=False):
        device_uuid = self.get_client_uuid(device_uuid)
        index = PluginRegistry.getInstance("ObjectIndex")

        res = index.search({'_type': 'Device', 'deviceUUID': device_uuid},
                           {'dn': 1})
        if len(res) != 1:
            raise ValueError(C.make_error("CLIENT_NOT_FOUND", client=device_uuid, status_code=404))
        return ObjectProxy(res[0]['dn'], read_only=read_only, from_db_only=True)
Beispiel #18
0
    def serve(self):
        # Add event processor
        mqtt = self.__get_handler()
        mqtt.get_client().add_subscription('%s/client/+' % self.env.domain)
        self.log.debug("subscribing to %s event queue" % '%s/client/+' % self.env.domain)
        mqtt.set_subscription_callback(self.__eventProcessor)

        # Get registry - we need it later on
        self.__cr = PluginRegistry.getInstance("CommandRegistry")

        # Start maintenance with a delay of 5 seconds
        timer = Timer(5.0, self.__refresh)
        timer.start()
        self.env.threads.append(timer)

        # Register scheduler task to remove outdated clients
        sched = PluginRegistry.getInstance('SchedulerService').getScheduler()
        sched.add_interval_job(self.__gc, minutes=1, tag='_internal', jobstore="ram")
Beispiel #19
0
def shutdown(a=None, b=None):
    global dr

    env = Environment.getInstance()
    log = logging.getLogger(__name__)

    # Function to shut down the client. Do some clean up and close sockets.
    mqtt = PluginRegistry.getInstance("MQTTClientHandler")

    # Tell others that we're away now
    e = EventMaker()
    goodbye = e.Event(e.ClientLeave(e.Id(env.uuid)))
    if mqtt:
        mqtt.send_event(goodbye)
        mqtt.close()

    # Shutdown plugins
    PluginRegistry.shutdown()

    #TODO: remove this hack
    wait = 1
    for t in env.threads:
        if t.isAlive():
            log.warning("thread %s still alive" % t.getName())
            if hasattr(t, 'stop'):
                log.warning("calling 'stop' for thread %s" % t.getName())
                t.stop()
            if hasattr(t, 'cancel'):
                log.warning("calling 'cancel' for thread %s" % t.getName())
                t.cancel()
            t.join(wait)

        if t.is_alive():
            try:
                log.warning("calling built in 'stop' for thread %s" %
                            t.getName())
                t._stop()
            except:
                log.error("could not stop thread %s" % t.getName())

    dr.stop()

    log.info("shut down")
    logging.shutdown()
Beispiel #20
0
    def serve(self):
        # Add event processor
        mqtt = self.__get_handler()
        # listen to client topics
        mqtt.get_client().add_subscription('%s/client/+' % self.env.domain, qos=1)
        self.log.debug("subscribing to %s event queue on %s" % ('%s/client/+' % self.env.domain, mqtt.host))
        mqtt.set_subscription_callback(self.__eventProcessor)

        # Get registry - we need it later on
        self.__cr = PluginRegistry.getInstance("CommandRegistry")

        # Start maintenance when index scan is finished
        zope.event.subscribers.append(self.__handle_events)

        # Register scheduler task to remove outdated clients
        sched = PluginRegistry.getInstance('SchedulerService').getScheduler()
        sched.add_interval_job(self.__gc, minutes=1, tag='_internal', jobstore="ram")

        # self.register_listener("configureHostPrinters", self._on_client_caps)
        self.ppd_proxy = PluginRegistry.getInstance("PPDProxy")
Beispiel #21
0
    def sendSessionNotification(self):
        # Build event
        mqtt = PluginRegistry.getInstance("MQTTClientHandler")
        e = EventMaker()
        more = set([x['uid'] for x in self.__sessions.values()])
        more = map(e.Name, more)
        info = e.Event(
            e.UserSession(
                e.Id(self.env.uuid),
                e.User(*more)))

        mqtt.send_event(info)
Beispiel #22
0
    def __open_device(self, device_uuid):
        device_uuid = self.get_client_uuid(device_uuid)
        index = PluginRegistry.getInstance("ObjectIndex")

        res = index.search({
            '_type': 'Device',
            'deviceUUID': device_uuid
        }, {'dn': 1})
        if len(res) != 1:
            raise ValueError(
                C.make_error("CLIENT_NOT_FOUND", device_uuid, status_code=404))
        return ObjectProxy(res[0]['dn'])
Beispiel #23
0
    def serve(self):
        # Add event processor
        amqp = PluginRegistry.getInstance('AMQPHandler')
        EventConsumer(self.env,
            amqp.getConnection(),
            xquery="""
                declare namespace f='http://www.gonicus.de/Events';
                let $e := ./f:Event
                return $e/f:ClientAnnounce
                    or $e/f:ClientLeave
                    or $e/f:UserSession
            """,
            callback=self.__eventProcessor)

        # Get registry - we need it later on
        self.__cr = PluginRegistry.getInstance("CommandRegistry")

        # Start maintainence timer
        timer = Timer(10.0, self.__refresh)
        timer.start()
        self.env.threads.append(timer)
Beispiel #24
0
    def sendSessionNotification(self):
        if self.__notify_backend is True:
            # Build event
            mqtt = PluginRegistry.getInstance("MQTTClientHandler")
            e = EventMaker()
            more = set([x['uid'] for x in self.__sessions.values()])
            more = map(e.Name, more)
            info = e.Event(
                e.UserSession(
                    e.Id(self.env.uuid),
                    e.User(*more)))

            mqtt.send_event(info)
Beispiel #25
0
    def serve(self):
        """ Start AMQP service for this GOsa service provider. """
        # Load AMQP and Command registry instances
        amqp = PluginRegistry.getInstance('AMQPClientHandler')
        self.__cr = PluginRegistry.getInstance('ClientCommandRegistry')

        # Add private processor for client queue
        # pylint: disable=E1101
        self.__cmdWorker = AMQPWorker(self.env, connection=amqp.getConnection(),
                r_address="""%s.client.%s; {
                    create:always,
                    node:{
                        type:queue,
                        durable:false,
                        x-declare: {
                            exclusive: True,
                            auto-delete: True },
                        x-bindings:[ {
                                exchange:"amq.direct",
                                queue:"%s.client.%s" } ]
                        }
                    }""" % (self.env.domain, self.env.uuid, self.env.domain, self.env.uuid),
            workers=self.env.config.get('amqp.command-worker', default=1),
            callback=self.commandReceived)

        # Add event processor
        EventConsumer(self.env,
            amqp.getConnection(),
            xquery="""
                declare namespace f='http://www.gonicus.de/Events';
                let $e := ./f:Event
                return $e/f:ClientPoll
            """,
            callback=self.__handleClientPoll)


        # Gather interface information
        self.__announce(True)
Beispiel #26
0
    def systemGetStatus(self, device_uuid):
        """
        TODO
        """

        index = PluginRegistry.getInstance("ObjectIndex")

        res = index.search({'_type': 'Device', 'deviceUUID': device_uuid},
                           {'_uuid': 1})
        if len(res) != 1:
            raise ValueError(C.make_error("CLIENT_NOT_FOUND", device_uuid))

        device = ObjectProxy(res[0]['_uuid'])
        return device.deviceStatus
Beispiel #27
0
    def __init__(self):
        super(DebianPreseed, self).__init__()
        self.env = Environment.getInstance()
        self.path = self.env.config.get('libinst.path', default="/preseed")

        try:
            # Get http service instance
            self.__http = PluginRegistry.getInstance('HTTPService')

            # Register ourselves
            self.__http.register(self.path, self)

        except:
            pass
Beispiel #28
0
    def getDestinationIndicator(self, client_id, uid, cn_query, rotate=True):
        """

        :param client_id: UUID of the client used to find the closest destinationIndicators
        :param uid: uid of the user
        :param cn_query: filter for destinationIndicator-cns (e.g. 'lts-% for wildcards)
        :param rotate: rotate the destinationIndicators (do not use the last one twice in a row)
        :return: FQDN of the server marked as destinationIndicator
        """
        index = PluginRegistry.getInstance('ObjectIndex')
        res = index.search({'_type': 'User', 'uid': uid}, {'dn': 1})
        if len(res) == 0:
            raise ValueError(C.make_error("USER_NOT_FOUND", user=uid, status_code=404))

        user = ObjectProxy(res[0]['dn'])

        if rotate is False and user.destinationIndicator is not None:
            # nothing to rotate, take the stored one
            return user.destinationIndicator

        client = self.__open_device(client_id, read_only=True)
        parent_dn = client.get_adjusted_parent_dn()
        res = index.search({'_type': 'Device', 'extension': 'GoServer', 'cn': cn_query, '_adjusted_parent_dn': parent_dn}, {'dn': 1})

        while len(res) == 0 and len(parent_dn) > len(self.env.base):
            parent_dn = dn2str(str2dn(parent_dn, flags=ldap.DN_FORMAT_LDAPV3)[1:])
            res = index.search({'_type': 'Device', 'cn': cn_query, '_adjusted_parent_dn': parent_dn}, {'dn': 1})

        if len(res) > 0:
            di_pool = sorted([x['dn'] for x in res])
            if user.destinationIndicator is None:
                # nothing to rotate, take the first one
                user.destinationIndicator = di_pool[0]
                user.commit()

            elif rotate is True:
                if user.destinationIndicator in di_pool:
                    # take the next one from list
                    position = di_pool.index(user.destinationIndicator)+1
                    if position >= len(di_pool):
                        position = 0
                    user.destinationIndicator = di_pool[position]
                    user.commit()
                else:
                    # nothing to rotate, take the first one
                    user.destinationIndicator = di_pool[0]
                    user.commit()

            return user.destinationIndicator
        return None
Beispiel #29
0
    def __maintain_user_session(self, client_id, user_name):
        # save login time and system<->user references
        client = self.__open_device(client_id)
        client.gotoLastUser = user_name
        self.systemSetStatus(client, "+B")

        index = PluginRegistry.getInstance("ObjectIndex")
        res = index.search({"_type": "User", "uid": user_name}, {"dn": 1})
        for u in res:
            user = ObjectProxy(u["dn"])
            if not user.is_extended_by("GosaAccount"):
                user.extend("GosaAccount")
            user.gotoLastSystemLogin = datetime.datetime.now()
            user.gotoLastSystem = client.dn
            user.commit()
Beispiel #30
0
    def __maintain_user_session(self, client_id, user_name):
        # save login time and system<->user references
        client = self.__open_device(client_id)
        client.gotoLastUser = user_name
        self.systemSetStatus(client, "+B")

        index = PluginRegistry.getInstance("ObjectIndex")
        res = index.search({"_type": "User", "uid": user_name}, {"dn": 1})
        for u in res:
            user = ObjectProxy(u["dn"])
            if not user.is_extended_by("GosaAccount"):
                user.extend("GosaAccount")
            user.gotoLastSystemLogin = datetime.datetime.now()
            user.gotoLastSystem = client.dn
            user.commit()
Beispiel #31
0
    def serve(self):
        # Add event processor
        mqtt = self.__get_handler()
        # listen to client topics
        mqtt.get_client().add_subscription('%s/client/+' % self.env.domain)
        self.log.debug("subscribing to %s event queue" % '%s/client/+' %
                       self.env.domain)
        mqtt.set_subscription_callback(self.__eventProcessor)

        # Get registry - we need it later on
        self.__cr = PluginRegistry.getInstance("CommandRegistry")

        # Start maintenance when index scan is finished
        zope.event.subscribers.append(self.__handle_events)

        # Register scheduler task to remove outdated clients
        sched = PluginRegistry.getInstance('SchedulerService').getScheduler()
        sched.add_interval_job(self.__gc,
                               minutes=1,
                               tag='_internal',
                               jobstore="ram")

        # self.register_listener("configureHostPrinters", self._on_client_caps)
        self.ppd_proxy = PluginRegistry.getInstance("PPDProxy")
Beispiel #32
0
 def __eventProcessor(self, topic, message):
     if message[0:1] == "{":
         # RPC response
         self.log.debug("RPC response received in channel %s: '%s'" % (topic, message))
     else:
         try:
             data = etree.fromstring(message, PluginRegistry.getEventParser())
             eventType = stripNs(data.xpath('/g:Event/*', namespaces={'g': "http://www.gonicus.de/Events"})[0].tag)
             self.log.debug("'%s' event received from local MQTT broker" % eventType)
             if hasattr(self, "_handle"+eventType):
                 func = getattr(self, "_handle" + eventType)
                 func(data)
             else:
                 self.log.debug("unhandled event %s" % eventType)
         except etree.XMLSyntaxError as e:
             self.log.error("XML parse error %s on message %s" % (e, message))
Beispiel #33
0
 def __eventProcessor(self, topic, message):
     if message[0:1] == "{":
         # RPC response
         self.log.debug("RPC response received in channel %s: '%s'" % (topic, message))
     else:
         try:
             data = etree.fromstring(message, PluginRegistry.getEventParser())
             eventType = stripNs(data.xpath('/g:Event/*', namespaces={'g': "http://www.gonicus.de/Events"})[0].tag)
             self.log.debug("Incoming MQTT event[%s]: '%s'" % (eventType, data))
             if hasattr(self, "_handle"+eventType):
                 func = getattr(self, "_handle" + eventType)
                 func(data)
             else:
                 self.log.debug("unhandled event %s" % eventType)
         except etree.XMLSyntaxError as e:
             self.log.error("XML parse error %s on message %s" % (e, message))
Beispiel #34
0
    def _handleClientAnnounce(self, data):
        data = data.ClientAnnounce
        client = data.Id.text
        self.log.info("client '%s' is joining us" % client)
        self.systemSetStatus(client, "+O")

        # Remove remaining proxy values for this client
        if client in self.__proxy:
            self.__proxy[client].close()
            del self.__proxy[client]

        # Assemble caps
        caps = {}
        for method in data.ClientCapabilities.ClientMethod:
            caps[method.Name.text] = {
                'path': method.Path.text,
                'sig': method.Signature.text,
                'doc': method.Documentation.text}

        # Assemble network information
        network = {}
        for interface in data.NetworkInformation.NetworkDevice:
            network[interface.Name.text] = {
                'IPAddress': interface.IPAddress.text,
                'IPv6Address': interface.IPv6Address.text,
                'MAC': interface.MAC.text,
                'Netmask': interface.Netmask.text,
                'Broadcast': interface.Broadcast.text}

        # Add recieve time to be able to sort out dead nodes
        t = datetime.datetime.utcnow()
        info = {
            'name': data.Name.text,
            'received': time.mktime(t.timetuple()),
            'caps': caps,
            'network': network
        }

        self.__client[data.Id.text] = info

        # Handle pending "P"repare actions for that client
        if "P" in self.systemGetStatus(client):
            try:
                rm = PluginRegistry.getInstance("RepositoryManager")
                rm.prepareClient(client)
            except ValueError:
                pass
Beispiel #35
0
    def report_to_event(self, file_name):
        e = EventMaker()
        amqp_service = PluginRegistry.getInstance("AMQPClientService")

        with open(file_name, "r") as f:
            yml = yaml.load(f)
            logs = [e.Id(self.env.id)]

            for log in yml.logs:
                data = [
                    e.Timestamp(str(mktime(log.time.timetuple()))),
                    e.Level(log.level),
                    e.Message(log.message),
                ]

                # Append <Tag> tag
                try:
                    tags = e.Tag()
                    for tag in log.tags:
                        tags.append(e.value(tag))
                    data.append(tags)
                except:
                    pass

                # Add optional tags
                try:
                    data.append[e.Source(log.source)]
                except:
                    pass
                try:
                    data.append[e.Line(log.line)]
                except:
                    pass
                try:
                    data.append[e.File(log.file)]
                except:
                    pass
                try:
                    data.append[e.Version(log.version)]
                except:
                    pass

                logs.append(e.PuppetLog(*data))

        return e.Event(e.PuppetReport(*logs))
Beispiel #36
0
    def systemSetStatus(self, device_uuid, status):
        """
        TODO
        """

        # Write to backend
        index = PluginRegistry.getInstance("ObjectIndex")

        res = index.search({'_type': 'Device', 'deviceUUID': device_uuid}, {'_uuid': 1})
        if len(res) != 1:
            raise ValueError(C.make_error("CLIENT_NOT_FOUND", device_uuid))
        device = ObjectProxy(res[0]['_uuid'])
        r = re.compile(r"([+-].)")
        for stat in r.findall(status):
            if stat[1] not in mapping:
                raise ValueError(C.make_error("CLIENT_STATUS_INVALID", device_uuid, status=stat[1]))
            setattr(device, mapping[stat[1]], stat.startswith("+"))
        device.commit()
Beispiel #37
0
def netactivity(online):
    global netstate
    env = Environment.getInstance()
    if online:
        netstate = True
        env.active = True
    else:
        env = Environment.getInstance()
        netstate = False

        # Function to shut down the client. Do some clean up and close sockets.
        mqtt = PluginRegistry.getInstance("MQTTClientHandler")

        # Tell others that we're away now
        e = EventMaker()
        goodbye = e.Event(e.ClientLeave(e.Id(env.uuid)))
        if mqtt:
            mqtt.send_event(goodbye)
            mqtt.close()

        env.reset_requested = True
        env.active = False
Beispiel #38
0
def mainLoop(env):
    global loop

    log = logging.getLogger(__name__)

    try:
        # connect to dbus and setup loop
        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
        get_system_bus()

        # Instanciate dbus objects
        PluginRegistry(component='gosa.dbus.module')

        # Enter main loop
        loop = GLib.MainLoop()
        loop.run()

    except Exception as detail:
        log.critical("unexpected error in mainLoop")
        log.exception(detail)
        log.debug(traceback.format_exc())

    finally:
        shutdown()
Beispiel #39
0
    def joinClient(self, user, device_uuid, mac, info=None):
        """
        TODO
        """

        index = PluginRegistry.getInstance("ObjectIndex")

        uuid_check = re.compile(
            r"^[0-9a-f]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$",
            re.IGNORECASE)
        if not uuid_check.match(device_uuid):
            raise ValueError(C.make_error("CLIENT_UUID_INVALID", device_uuid))

        # Handle info, if present
        more_info = []

        if info:
            # Check string entries
            for entry in filter(
                    lambda x: x in info,
                ["serialNumber", "ou", "o", "l", "description"]):

                if not re.match(r"^[\w\s]+$", info[entry]):
                    raise ValueError(
                        C.make_error("CLIENT_DATA_INVALID",
                                     device_uuid,
                                     entry=entry,
                                     data=info[entry]))

                more_info.append((entry, info[entry]))

            # Check desired device type if set
            if "deviceType" in info:
                if re.match(
                        r"^(terminal|workstation|server|sipphone|switch|router|printer|scanner)$",
                        info["deviceType"]):

                    more_info.append(("deviceType", info["deviceType"]))
                else:
                    raise ValueError(
                        C.make_error("CLIENT_TYPE_INVALID",
                                     device_uuid,
                                     type=info["deviceType"]))

            # Check owner for presence
            if "owner" in info:
                # Take a look at the directory to see if there's  such an owner DN
                res = index.search({'_dn': info["owner"]}, {'_dn': 1})
                if len(res) == 0:
                    raise ValueError(
                        C.make_error("CLIENT_OWNER_NOT_FOUND",
                                     device_uuid,
                                     owner=info["owner"]))
                more_info.append(("owner", info["owner"]))

        # Generate random client key
        h, key, salt = generate_random_key()

        # Take a look at the directory to see if there's already a joined client with this uuid
        res = index.search(
            {
                '_type': 'Device',
                'macAddress': mac,
                'extension': 'RegisteredDevice'
            }, {'dn': 1})

        if len(res) > 0:
            record = ObjectProxy(res[0]['dn'])
            for ext in ["simpleSecurityObject", "ieee802Device"]:
                if not record.is_extended_by(ext):
                    record.extend(ext)

            if record.is_extended_by("ForemanHost") and record.otp is not None:
                record.otp = None

            record.userPassword = [
                "{SSHA}" + encode(h.digest() + salt).decode()
            ]
            for k, value in more_info:
                setattr(record, k, value)
            cn = record.deviceUUID
            record.status_Online = False
            record.status_Offline = True
            record.status_InstallationInProgress = False

            record.commit()
            self.log.info("UUID '%s' joined as %s" % (device_uuid, record.dn))
        else:

            # While the client is going to be joined, generate a random uuid and an encoded join key
            cn = str(uuid4())
            device_key = encrypt_key(device_uuid.replace("-", ""), cn + key)

            # Resolve manager
            res = index.search({'_type': 'User', 'uid': user}, {'dn': 1})

            if len(res) != 1:
                raise GOtoException(
                    C.make_error("USER_NOT_UNIQUE" if res else "UNKNOWN_USER",
                                 target=user))
            manager = res[0]['dn']

            # Create new machine entry
            dn = ",".join([
                self.env.config.get("goto.machine-rdn", default="ou=systems"),
                self.env.base
            ])
            record = ObjectProxy(dn, "Device")
            record.extend("RegisteredDevice")
            record.extend("ieee802Device")
            record.extend("simpleSecurityObject")
            record.deviceUUID = cn
            record.deviceKey = Binary(device_key)
            record.cn = "mac%s" % mac.replace(":", "")
            record.manager = manager
            record.status_Offline = True
            record.macAddress = mac.encode("ascii", "ignore")
            record.userPassword = [
                "{SSHA}" + encode(h.digest() + salt).decode()
            ]
            for k, value in more_info:
                setattr(record, k, value)

            record.commit()
            self.log.info("UUID '%s' joined as %s" % (device_uuid, record.dn))

        # make sure the client has the access rights he needs
        self.applyClientRights(cn)

        return [key, cn]
Beispiel #40
0
    def joinClient(self, user, device_uuid, mac, info=None):
        """
        TODO
        """

        index = PluginRegistry.getInstance("ObjectIndex")

        uuid_check = re.compile(r"^[0-9a-f]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$", re.IGNORECASE)
        if not uuid_check.match(device_uuid):
            raise ValueError(C.make_error("CLIENT_UUID_INVALID", device_uuid))

        # Handle info, if present
        more_info = []

        if info:
            # Check string entries
            for entry in filter(lambda x: x in info, ["serialNumber", "ou", "o", "l", "description"]):

                if not re.match(r"^[\w\s]+$", info[entry]):
                    raise ValueError(C.make_error("CLIENT_DATA_INVALID", device_uuid, entry=entry, data=info[entry]))

                more_info.append((entry, info[entry]))

            # Check desired device type if set
            if "deviceType" in info:
                if re.match(r"^(terminal|workstation|server|sipphone|switch|router|printer|scanner)$", info["deviceType"]):

                    more_info.append(("deviceType", info["deviceType"]))
                else:
                    raise ValueError(C.make_error("CLIENT_TYPE_INVALID", device_uuid, type=info["deviceType"]))

            # Check owner for presence
            if "owner" in info:
                # Take a look at the directory to see if there's  such an owner DN
                res = index.search({'_dn': info["owner"]}, {'_dn': 1})
                if len(res) == 0:
                    raise ValueError(C.make_error("CLIENT_OWNER_NOT_FOUND", device_uuid, owner=info["owner"]))
                more_info.append(("owner", info["owner"]))

        # Generate random client key
        random.seed()
        key = ''.join(random.Random().sample(string.ascii_letters + string.digits, 32))
        salt = os.urandom(4)
        h = hashlib.sha1(key.encode('ascii'))
        h.update(salt)

        # Take a look at the directory to see if there's already a joined client with this uuid
        res = index.search({'_type': 'Device', 'macAddress': mac},
                           {'_uuid': 1})

        if len(res):
            raise GOtoException(C.make_error("DEVICE_EXISTS", mac))

        # While the client is going to be joined, generate a random uuid and an encoded join key
        cn = str(uuid4())
        device_key = self.__encrypt_key(device_uuid.replace("-", ""), cn + key)

        # Resolve manager
        res = index.search({'_type': 'User', 'uid': user},
                           {'dn': 1})

        if len(res) != 1:
            raise GOtoException(C.make_error("USER_NOT_UNIQUE" if res else "UNKNOWN_USER", target=user))
        manager = res[0]['dn']

        # Create new machine entry
        # dn = ",".join([self.env.config.get("goto.machine-rdn", default="ou=systems"), self.env.base])
        # container = ObjectProxy(dn, "DeviceContainer")
        # container.commit()
        dn = ",".join([self.env.config.get("goto.machine-rdn", default="ou=devices,ou=systems"), self.env.base])
        record = ObjectProxy(dn, "Device")
        record.extend("RegisteredDevice")
        record.extend("ieee802Device")
        record.extend("simpleSecurityObject")
        record.deviceUUID = cn
        record.deviceKey = Binary(device_key)
        record.cn = cn
        record.manager = manager
        record.status_Offline = True
        record.macAddress = mac.encode("ascii", "ignore")
        record.userPassword = "******" + encode(h.digest() + salt).decode()
        for key, value in more_info:
            setattr(record, key, value)

        record.commit()
        self.log.info("UUID '%s' joined as %s" % (device_uuid, record.dn))

        return [key, cn]

        return None
Beispiel #41
0
    def __collect_user_configuration(self, client_id, users):
        """
        :param client_id: deviceUUID or hostname
        :param users: list of currently logged in users on the client
        """
        if isinstance(client_id, ObjectProxy):
            client = client_id
        else:
            client = self.__open_device(client_id)
        group = None
        index = PluginRegistry.getInstance("ObjectIndex")
        res = index.search({
            "_type": "GroupOfNames",
            "member": client.dn
        }, {"dn": 1})
        if len(res) > 0:
            group = ObjectProxy(res[0]["dn"])
        config = {}

        resolution = None
        if group is not None and group.is_extended_by(
                "GotoEnvironment") and group.gotoXResolution is not None:
            resolution = group.gotoXResolution

        if client.is_extended_by(
                "GotoEnvironment") and client.gotoXResolution is not None:
            resolution = client.gotoXResolution

        release = None
        if client.is_extended_by("GotoMenu"):
            release = client.getReleaseName()
        elif group is not None and group.is_extended_by("ForemanHostGroup"):
            release = group.getReleaseName()
            parent_group = group
            while release is None and parent_group is not None and parent_group.parent_id is not None:
                res = index.search(
                    {
                        "_type": "GroupOfNames",
                        "extension": "ForemanHostGroup",
                        "foremanGroupId": parent_group.parent_id
                    }, {"dn": 1})
                if len(res) == 0:
                    break
                else:
                    parent_group = ObjectProxy(res[0]["dn"])
                    release = parent_group.getReleaseName()

        if release is None:
            self.log.error(
                "no release found for client/user combination (%s/%s)" %
                (client_id, users))

        client_menu = None

        if hasattr(client, "gotoMenu") and client.gotoMenu is not None:
            client_menu = loads(client.gotoMenu)

        # collect users DNs
        query_result = index.search({
            "_type": "User",
            "uid": {
                "in_": users
            }
        }, {"dn": 1})
        for entry in query_result:
            user = ObjectProxy(entry["dn"])
            config[user.uid] = {}

            if release is not None:
                menus = []
                if client_menu is not None:
                    menus.append(client_menu)

                # get all groups the user is member of which have a menu for the given release
                query = {
                    '_type': 'GroupOfNames',
                    "member": user.dn,
                    "extension": "GotoMenu",
                    "gotoLsbName": release
                }

                for res in index.search(query, {"gotoMenu": 1}):
                    # collect user menus
                    for m in res["gotoMenu"]:
                        menus.append(loads(m))

                if len(menus):
                    user_menu = None
                    for menu_entry in menus:
                        if user_menu is None:
                            user_menu = self.get_submenu(menu_entry)
                        else:
                            self.merge_submenu(user_menu,
                                               self.get_submenu(menu_entry))
                    config[user.uid]["menu"] = user_menu

            # collect printer settings for user, starting with the clients printers
            settings = self.__collect_printer_settings(group)
            printer_names = [x["cn"] for x in settings["printers"]]
            for res in index.search(
                {
                    '_type': 'GroupOfNames',
                    "member": user.dn,
                    "extension": "GotoEnvironment"
                }, {"dn": 1}):
                user_group = ObjectProxy(res["dn"])
                if user_group.dn == group.dn:
                    continue
                s = self.__collect_printer_settings(user_group)

                if user_group.gotoXResolution is not None:
                    resolution = user_group.gotoXResolution

                for p in s["printers"]:
                    if p["cn"] not in printer_names:
                        settings["printers"].append(p)
                        printer_names.append(p["cn"])

                if s["defaultPrinter"] is not None:
                    settings["defaultPrinter"] = s["defaultPrinter"]

            # override group environment settings if the client has one
            s = self.__collect_printer_settings(client)
            if len(s["printers"]) > 0:
                settings["printers"] = s["printers"]
                settings["defaultPrinter"] = s["defaultPrinter"]

            if user.is_extended_by(
                    "GosaAccount") and user.gosaDefaultPrinter is not None:
                # check if the users default printer is send to the client
                found = False
                for printer_settings in settings["printers"]:
                    if printer_settings["cn"] == user.gosaDefaultPrinter:
                        found = True
                        break

                def process(res):
                    if len(res) == 0:
                        self.log.warning("users defaultPrinter not found: %s" %
                                         user.gosaDefaultPrinter)
                        return None
                    elif len(res) == 1:
                        # add this one to the result set
                        printer = ObjectProxy(res[0]["dn"])
                        p_conf = {}
                        for attr in self.printer_attributes:
                            p_conf[attr] = getattr(printer, attr)
                        return p_conf
                    return False

                if found is False:
                    # find the printer and add it to the settings
                    res = index.search(
                        {
                            "_type": "GotoPrinter",
                            "cn": user.gosaDefaultPrinter
                        }, {"dn": 1})
                    printer_config = process(res)
                    if printer_config is False:
                        # more than 1 printers found by this CN, try to look in the users subtree
                        res = index.search(
                            {
                                "_type":
                                "GotoPrinter",
                                "cn":
                                user.gosaDefaultPrinter,
                                "_adjusted_parent_dn":
                                user.get_adjusted_parent_dn()
                            }, {"dn": 1})
                        printer_config = process(res)

                    if isinstance(printer_config, dict):
                        settings["printers"].append(printer_config)
                        settings["defaultPrinter"] = user.gosaDefaultPrinter
                    else:
                        self.log.warning("users defaultPrinter not found: %s" %
                                         user.gosaDefaultPrinter)
                else:
                    settings["defaultPrinter"] = user.gosaDefaultPrinter

            config[user.uid]["printer-setup"] = settings
            config[user.uid]["resolution"] = None

            if resolution is not None:
                config[user.uid]["resolution"] = [
                    int(x) for x in resolution.split("x")
                ]

            # TODO: collect and send login scripts to client
        return config
Beispiel #42
0
def mainLoop(env):
    global netstate, dr

    # Enable DBus runner
    dr = DBusRunner()
    dr.start()

    # Do network monitoring
    nm = Monitor(netactivity)
    netactivity(nm.is_online())
    """ Main event loop which will process all registered threads in a loop.
        It will run as long env.active is set to True."""
    try:
        log = logging.getLogger(__name__)

        while True:

            # Check netstate and wait until we're back online
            if not netstate:
                log.info("waiting for network connectivity")
            while not netstate:
                time.sleep(1)

            # Load plugins
            PluginRegistry(component='gosa.client.module')

            # Sleep and slice
            wait = 2
            while True:
                # Threading doesn't seem to work well with python...
                for p in env.threads:

                    # Bail out if we're active in the meanwhile
                    if not env.active:
                        break

                    p.join(wait)

                # No break, go to main loop
                else:
                    continue

                # Break, leave main loop
                break

            # Break, leave main loop
            if not env.reset_requested:
                break

            # Wait for threads to shut down
            for t in env.threads:
                if hasattr(t, 'stop'):
                    t.stop()
                if hasattr(t, 'cancel'):
                    t.cancel()
                t.join(wait)

                #TODO: remove me
                if t.is_alive():
                    try:
                        t._stop()
                    except:
                        print(str(t.getName()) + ' could not be terminated')

            # Lets do an environment reset now
            PluginRegistry.shutdown()

            # Make us active and loop from the beginning
            env.reset_requested = False
            env.active = True

            if not netstate:
                log.info("waiting for network connectivity")
            while not netstate:
                time.sleep(1)

            sleep = randint(30, 60)
            env.log.info(
                "waiting %s seconds to try an MQTT connection recovery" %
                sleep)
            time.sleep(sleep)

    except Exception as detail:
        log.critical("unexpected error in mainLoop")
        log.exception(detail)
        log.debug(traceback.format_exc())

    except KeyboardInterrupt:
        log.info("console requested shutdown")

    finally:
        shutdown()
Beispiel #43
0
 def __ping(self):
     e = EventMaker()
     mqtt = PluginRegistry.getInstance('MQTTClientHandler')
     info = e.Event(e.ClientPing(e.Id(self.env.uuid)))
     mqtt.send_event(info)
Beispiel #44
0
    def commandReceived(self, topic, message):
        """
        Process incoming commands, coming in with session and message
        information.

        ================= ==========================
        Parameter         Description
        ================= ==========================
        message           Received MQTT message
        ================= ==========================

        Incoming messages are coming from an
        :class:`gosa.common.components.mqtt_proxy.MQTTServiceProxy`. The command
        result is written to the '<domain>.client.<client-uuid>' queue.
        """
        err = None
        res = None
        name = None
        args = None
        id_ = ''

        response_topic = "%s/to-backend" % "/".join(topic.split("/")[0:4])

        try:
            req = loads(message)
        except Exception as e:
            err = str(e)
            self.log.error("ServiceRequestNotTranslatable: %s" % err)
            req = {'id': topic.split("/")[-2]}

        if err is None:
            try:
                id_ = req['id']
                name = req['method']
                args = req['params']

            except KeyError as e:
                self.log.error("KeyError: %s" % e)
                err = str(BadServiceRequest(message))

        self.log.debug("received call [%s] for %s: %s(%s)" %
                       (id_, topic, name, args))

        # Try to execute
        if err is None:
            try:
                res = self.__cr.dispatch(name, *args)
            except Exception as e:
                err = str(e)

                # Write exception to log
                exc_type, exc_value, exc_traceback = sys.exc_info()
                self.log.error(
                    traceback.format_exception(exc_type, exc_value,
                                               exc_traceback))

        self.log.debug("returning call [%s]: %s / %s" % (id_, res, err))

        response = dumps({"result": res, "id": id_})

        # Get rid of it...
        mqtt = PluginRegistry.getInstance('MQTTClientHandler')
        mqtt.send_message(response, topic=response_topic)
Beispiel #45
0
    def __announce(self, initial=False):
        mqtt = PluginRegistry.getInstance('MQTTClientHandler')
        e = EventMaker()

        # Assemble network information
        more = []
        netinfo = []
        for interface in netifaces.interfaces():
            i_info = netifaces.ifaddresses(interface)

            # Skip lo interfaces
            if not netifaces.AF_INET in i_info:
                continue

            # Skip lo interfaces
            if not netifaces.AF_LINK in i_info:
                continue
            if i_info[netifaces.AF_LINK][0]['addr'] == '00:00:00:00:00:00':
                continue

            # Assemble ipv6 information
            ip6 = ""
            if netifaces.AF_INET6 in i_info:
                ip = IPNetwork(
                    "%s/%s" % (i_info[netifaces.AF_INET6][0]['addr'].split(
                        "%", 1)[0], i_info[netifaces.AF_INET6][0]['netmask']))
                ip6 = str(ip)

            netinfo.append(
                e.NetworkDevice(
                    e.Name(interface),
                    e.IPAddress(i_info[netifaces.AF_INET][0]['addr']),
                    e.IPv6Address(ip6),
                    e.MAC(i_info[netifaces.AF_LINK][0]['addr']),
                    e.Netmask(i_info[netifaces.AF_INET][0]['netmask']),
                    e.Broadcast(i_info[netifaces.AF_INET][0]['broadcast'])))

        more.append(e.NetworkInformation(*netinfo))

        # Build event
        if initial:
            info = e.Event(
                e.ClientAnnounce(e.Id(self.env.uuid), e.Name(self.env.id),
                                 *more))

            mqtt.send_event(info)

        # Assemble capabilities
        more = []
        caps = []
        for command, dsc in self.__cr.commands.items():
            caps.append(
                e.ClientMethod(e.Name(command), e.Path(dsc['path']),
                               e.Signature(','.join(dsc['sig'])),
                               e.Documentation(dsc['doc'])))
        more.append(e.ClientCapabilities(*caps))

        info = e.Event(
            e.ClientSignature(e.Id(self.env.uuid), e.Name(self.env.id), *more))

        mqtt.send_event(info)

        if not initial:
            try:
                sk = PluginRegistry.getInstance('SessionKeeper')
                sk.sendSessionNotification()
            except:  # pragma: nocover
                pass