예제 #1
0
    def users_unregister(self, users):
        """
        Unregister users
        @type users: list
        @param users: list of users to unregister
        """
        def on_receive_unregistration(conn, iq):
            if iq.getType() == "result":
                for jid in users:
                    self.users.remove({"jid": jid.getStripped(), "type": "human"})
                self.entity.log.info("XMPPSERVER: Successfully unregistered user(s).")
                self.entity.push_change("xmppserver:users", "unregistered")
            else:
                self.entity.push_change("xmppserver:users", "unregisterationerror", iq)
                self.entity.log.error("XMPPSERVER: unable to unregister user. %s" % str(iq))

        iq = xmpp.Iq(typ="set", to=self.entity.jid.getDomain())
        iq_command = iq.addChild("command", namespace="http://jabber.org/protocol/commands", attrs={"node": "http://jabber.org/protocol/admin#delete-user"})
        iq_command_x = iq_command.addChild("x", namespace="jabber:x:data", attrs={"type": "submit"})
        iq_command_x.addChild("field", attrs={"type": "hidden", "var": "FORM_TYPE"}).addChild("value").setData("http://jabber.org/protocol/admin")
        accountjids_node = iq_command_x.addChild("field", attrs={"var": "accountjids"})
        for jid in users:
            accountjids_node.addChild("value").setData(jid.getStripped())
            if jid.getStripped() in self.entities_types_cache:
                del self.entities_types_cache[jid.getStripped()]
        if self.entity.__class__.__name__ == "TNArchipelVirtualMachine":
            self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq, on_receive_unregistration)
        else:
            self.entity.xmppclient.SendAndCallForResponse(iq, on_receive_unregistration)
        self.entity.log.info("XMPPSERVER: Unregistring some users %s" % str(users))
예제 #2
0
    def users_change_password(self, users):
        """
        Change password for users
        @type users: list
        @param users: list of users to change password
        """
        def on_receive_password_changed(conn, iq):
            if iq.getType() == "result":
                self.entity.log.info("XMPPSERVER: Successfully changed paswword for user(s).")
                self.entity.push_change("xmppserver:users", "passwordchanged")
            else:
                self.entity.push_change("xmppserver:users", "changepassworderror", iq)
                self.entity.log.error("XMPPSERVER: Unable to change password for user. %s" % str(iq))
        server = self.entity.jid.getDomain()
        for user in users:
            iq = xmpp.Iq(typ="set", to=self.entity.jid.getDomain())
            iq_command = iq.addChild("command", namespace="http://jabber.org/protocol/commands", attrs={"node": "http://jabber.org/protocol/admin#change-user-password"})
            iq_command_x = iq_command.addChild("x", namespace="jabber:x:data", attrs={"type": "submit"})
            iq_command_x.addChild("field", attrs={"type": "hidden", "var": "FORM_TYPE"}).addChild("value").setData("http://jabber.org/protocol/admin")
            iq_command_x.addChild("field", attrs={"var": "accountjid"}).addChild("value").setData(user["jid"])
            iq_command_x.addChild("field", attrs={"var": "password"}).addChild("value").setData(user["password"])

            if self.entity.__class__.__name__ == "TNArchipelVirtualMachine":
                self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq, on_receive_password_changed)
            else:
                self.entity.xmppclient.SendAndCallForResponse(iq, on_receive_password_changed)
            self.entity.log.info("XMPPSERVER: Changing password for user %s@%s" % (user["jid"], server))
예제 #3
0
                def manage_received_users(conn, iq):
                    items = iq.getTag("query").getTags("item")
                    users = map(lambda x: x.getAttr("jid"), items)

                    def on_receive_vcard(conn, iq):
                        try:
                            entity_type = self._extract_entity_type(iq.getTag("vCard"))
                            self.entities_types_cache[iq.getFrom().getStripped()] = entity_type
                            self.users.append({"jid": iq.getFrom().getStripped(), "type": entity_type})
                            if len(self.users) == total_number_of_users:
                                callback(**args)
                        except Exception as ex:
                            self.entity.log.error("XMPPSERVER: Error while fetching contact vCard: %s" % str(ex))

                    for user in users:
                        if not user in self.entities_types_cache:
                            iq_vcard = xmpp.Iq(typ="get", to=user)
                            iq_vcard.addChild("vCard", namespace="vcard-temp")
                            self.entity.log.debug("XMPPSERVER: Entity type of %s is not cached. fetching..." % user)
                            if self.entity.__class__.__name__ == "TNArchipelVirtualMachine":
                                self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq_vcard, on_receive_vcard)
                            else:
                                self.entity.xmppclient.SendAndCallForResponse(iq_vcard, on_receive_vcard)

                        else:
                            self.entity.log.debug("XMPPSERVER: Entity type of %s is already cached (%s)" % (user, self.entities_types_cache[user]))
                            self.users.append({"jid": user, "type": self.entities_types_cache[user]})
                            if len(self.users) == total_number_of_users:
                                callback(**args)
예제 #4
0
 def users_register(self, users):
     """
     Register new users
     @type users: list
     @param users: list of users to register
     """
     def on_receive_registration(conn, iq):
         if iq.getType() == "result":
             for user in users:
                 entry = {"jid": user["jid"].getStripped(), "type": "human"}
                 if entry not in self.users:
                     self.users.append(entry)
             self.entities_types_cache[user["jid"].getStripped()] = "human"
             self.entity.log.info("XMPPSERVER: Successfully registered user(s).")
             self.entity.push_change("xmppserver:users", "registered")
         else:
             self.entity.push_change("xmppserver:users", "registerationerror", iq)
             self.entity.log.error("XMPPSERVER: Unable to register user. %s" % str(iq))
     server = self.entity.jid.getDomain()
     for user in users:
         iq = xmpp.Iq(typ="set", to=self.entity.jid.getDomain())
         iq_command = iq.addChild("command", namespace="http://jabber.org/protocol/commands", attrs={"node": "http://jabber.org/protocol/admin#add-user"})
         iq_command_x = iq_command.addChild("x", namespace="jabber:x:data", attrs={"type": "submit"})
         iq_command_x.addChild("field", attrs={"type": "hidden", "var": "FORM_TYPE"}).addChild("value").setData("http://jabber.org/protocol/admin")
         iq_command_x.addChild("field", attrs={"var": "accountjid"}).addChild("value").setData(user["jid"])
         iq_command_x.addChild("field", attrs={"var": "password"}).addChild("value").setData(user["password"])
         iq_command_x.addChild("field", attrs={"var": "password-verify"}).addChild("value").setData(user["password"])
         if self.entity.__class__.__name__ == "TNArchipelVirtualMachine":
             self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq, on_receive_registration)
         else:
             self.entity.xmppclient.SendAndCallForResponse(iq, on_receive_registration)
         self.entity.log.info("XMPPSERVER: Registering a new user %s@%s" % (user["jid"], server))
예제 #5
0
    def commit_to_db(self, action, table, callback):
        """
        Sends a command to active central agent for execution
        @type command: string
        @param command: the sql command to execute
        @type table: table
        @param command: the table of dicts of values associated with the command.
        """
        central_agent_jid = self.central_agent_jid()

        if central_agent_jid:

            # send an iq to central agent

            dbCommand = xmpp.Node(tag="event", attrs={"jid": self.entity.jid})

            for entry in table:

                entryTag = xmpp.Node(tag="entry")

                for key, value in entry.iteritems():

                    entryTag.addChild("item",
                                      attrs={
                                          "key": key,
                                          "value": value
                                      })

                dbCommand.addChild(node=entryTag)

            def commit_to_db_callback(conn, resp):

                if callback:

                    unpacked_entries = self.unpack_entries(resp)
                    callback(unpacked_entries)

            iq = xmpp.Iq(typ="set",
                         queryNS=ARCHIPEL_NS_CENTRALAGENT,
                         to=central_agent_jid)
            iq.getTag("query").addChild(name="archipel",
                                        attrs={"action": action})
            iq.getTag("query").getTag("archipel").addChild(node=dbCommand)
            self.entity.log.debug("CENTRALDB: commit to db request %s" % iq)
            xmpp.dispatcher.ID += 1
            iq.setID("%s-%d" % (self.entity.jid.getNode(), xmpp.dispatcher.ID))
            self.entity.xmppclient.SendAndCallForResponse(
                iq, commit_to_db_callback)

        else:

            self.entity.log.warning(
                "CENTRALDB: cannot commit to db because we have not detected any central agent"
            )
예제 #6
0
            def on_receive_users(conn, iq):

                if not iq.getType() == "result":
                    self.entity.log.error("unable to fetch users: %s" % str(iq))
                    return

                def manage_received_users(conn, iq):
                    items = iq.getTag("query").getTags("item")
                    users = map(lambda x: x.getAttr("jid"), items)

                    def on_receive_vcard(conn, iq):
                        try:
                            entity_type = self._extract_entity_type(iq.getTag("vCard"))
                            self.entities_types_cache[iq.getFrom().getStripped()] = entity_type
                            self.users.append({"jid": iq.getFrom().getStripped(), "type": entity_type})
                            if len(self.users) == total_number_of_users:
                                callback(**args)
                        except Exception as ex:
                            self.entity.log.error("XMPPSERVER: Error while fetching contact vCard: %s" % str(ex))

                    for user in users:
                        if not user in self.entities_types_cache:
                            iq_vcard = xmpp.Iq(typ="get", to=user)
                            iq_vcard.addChild("vCard", namespace="vcard-temp")
                            self.entity.log.debug("XMPPSERVER: Entity type of %s is not cached. fetching..." % user)
                            if self.entity.__class__.__name__ == "TNArchipelVirtualMachine":
                                self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq_vcard, on_receive_vcard)
                            else:
                                self.entity.xmppclient.SendAndCallForResponse(iq_vcard, on_receive_vcard)

                        else:
                            self.entity.log.debug("XMPPSERVER: Entity type of %s is already cached (%s)" % (user, self.entities_types_cache[user]))
                            self.users.append({"jid": user, "type": self.entities_types_cache[user]})
                            if len(self.users) == total_number_of_users:
                                callback(**args)

                try:
                    items = iq.getTag("query").getTags("item")
                    if items[0].getAttr("node"):
                        for page in range(0, len(items)):
                            iq_page = xmpp.Iq(typ="get", to=iq.getFrom())
                            iq_page.addChild("query", attrs={"node": iq.getTag("query").getTags("item")[page].getAttr("node")}, namespace="http://jabber.org/protocol/disco#items")
                            if self.entity.__class__.__name__ == "TNArchipelVirtualMachine":
                                self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq_page, manage_received_users)
                            else:
                                self.entity.xmppclient.SendAndCallForResponse(iq_page, manage_received_users)
                    else:
                        manage_received_users(conn, iq)

                except Exception as ex:
                    self.entity.log.error("XMPPSERVER: Unable to manage to get users or their vcards. error is %s" % str(ex))
예제 #7
0
    def read_from_db(self, action, columns, where_statement, callback):
        """
        Send a select statement to central db.
        @type command: string
        @param command: the sql command to execute
        @type columns: string
        @param columns: the list of database columns to return
        @type where_statement: string
        @param where_statement: for database reads, provides "where" constraint
        """
        central_agent_jid = self.central_agent_jid()

        if central_agent_jid:

            # send an iq to central agent
            dbCommand = xmpp.Node(tag="event", attrs={"jid": self.entity.jid})

            if where_statement:
                dbCommand.setAttr("where_statement", where_statement)

            if columns:
                dbCommand.setAttr("columns", columns)

            self.entity.log.debug("CENTRALDB: central agent jid %s" %
                                  central_agent_jid)
            iq = xmpp.Iq(typ="set",
                         queryNS=ARCHIPEL_NS_CENTRALAGENT,
                         to=central_agent_jid)
            iq.getTag("query").addChild(name="archipel",
                                        attrs={"action": action})
            iq.getTag("query").getTag("archipel").addChild(node=dbCommand)
            xmpp.dispatcher.ID += 1
            iq.setID("%s-%d" % (self.entity.jid.getNode(), xmpp.dispatcher.ID))

            def _read_from_db_callback(conn, resp):

                self.entity.log.debug("CENTRALDB: reply to read statement %s" %
                                      resp)
                unpacked_entries = self.unpack_entries(resp)
                self.entity.log.debug("CENTRALDB: unpacked reply %s" %
                                      unpacked_entries)
                callback(unpacked_entries)

            self.entity.xmppclient.SendAndCallForResponse(
                iq, _read_from_db_callback)

        else:

            self.entity.log.warning(
                "CENTRALDB: cannot read from db because we have not detected any central agent"
            )
예제 #8
0
    def get_management_capabilities(self, base_reply):
        """
        Build the xmpp management capabilities dictionnary
        """
        reply = base_reply.buildReply("result")

        def on_receive_info(conn, iq):

            _users_management_capabilities  = {"xmpp": False, "xmlrpc": False}
            _groups_management_capabilities = {"xmpp": False, "xmlrpc": False}

            _info_msg="XMPPSERVER - User and SRG Management : "
            if iq.getType() == "result":
               _users_management_capabilities["xmpp"] = True
               _info_msg += "XEP-133 allowed"
            else:
               _users_management_capabilities["xmpp"] = False
               _info_msg += "XEP-133 NOT allowed"

            # next try to use xmlrpc and mod_admin_extra to manage srg
            try:
                answer = self._send_xmlrpc_call("srg_list", {"host": self.xmlrpc_host})
                _groups_management_capabilities["xmlrpc"] = True
                _info_msg += " and SRG allowed through xmlrpc"
            except Exception as ex:
                _groups_management_capabilities["xmlrpc"] = False
                _info_msg += " and SRG NOT allowed through xmlrpc, reason : %s" % str(ex)


            # now send back the reply
            _users_node  = xmpp.Node("users",  attrs={"xmpp":_users_management_capabilities["xmpp"],  "xmlrpc":_users_management_capabilities["xmlrpc"]})
            _groups_node = xmpp.Node("groups", attrs={"xmpp":_groups_management_capabilities["xmpp"], "xmlrpc":_groups_management_capabilities["xmlrpc"]})
            reply.setQueryPayload([_users_node, _groups_node])
            self.entity.log.debug(_info_msg)
            self.entity.xmppclient.send(reply)

        # use disco#info to see if we can use admin-server command XEP-133

        iq = xmpp.Iq(typ="get", to=self.entity.jid.getDomain())
        iq.addChild("query", attrs={"node": "http://jabber.org/protocol/admin#get-registered-users-num"}, namespace="http://jabber.org/protocol/disco#info")

        if self.entity.__class__.__name__ == "TNArchipelVirtualMachine":
            self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq, on_receive_info)
        else:
            self.entity.xmppclient.SendAndCallForResponse(iq, on_receive_info)
예제 #9
0
    def handle_first_keepalive(self, keepalive_jid):
        """
        this is the first keepalive. We query hypervisors that have started somewhere else
        then we trigger method manage_persistence to start the vms.
        """
        vms_from_local_db = self.entity.get_vms_from_local_db()

        if len(vms_from_local_db) > 0:

            dbCommand = xmpp.Node(tag="event", attrs={"jid": self.entity.jid})

            for vm in vms_from_local_db:

                entryTag = xmpp.Node(tag="entry")
                uuid = xmpp.JID(vm["string_jid"]).getNode()
                entryTag.addChild("item", attrs={"key": "uuid", "value": uuid})
                dbCommand.addChild(node=entryTag)

            iq = xmpp.Iq(typ="set",
                         queryNS=ARCHIPEL_NS_CENTRALAGENT,
                         to=keepalive_jid)
            iq.getTag("query").addChild(
                name="archipel",
                attrs={"action": "read_vms_started_elsewhere"})
            iq.getTag("query").getTag("archipel").addChild(node=dbCommand)
            xmpp.dispatcher.ID += 1
            iq.setID("%s-%d" % (self.entity.jid.getNode(), xmpp.dispatcher.ID))

            def _read_vms_started_elsewhere_callback(conn, packed_vms):

                vms_started_elsewhere = self.unpack_entries(packed_vms)
                self.entity.manage_persistence(vms_from_local_db,
                                               vms_started_elsewhere)

            self.entity.xmppclient.SendAndCallForResponse(
                iq, _read_vms_started_elsewhere_callback)

        else:

            # update status to Online(0)
            self.entity.manage_persistence([], [])
예제 #10
0
    def handle_first_keepalive(self, keepalive_jid):
        """
        this is the first keepalive. We query hypervisors that have vm entities somewhere else
        then we trigger method manage_persistence to instantiate vm entities.
        """
        vms_from_local_db = self.entity.get_vms_from_local_db()

        if len(vms_from_local_db) > 0:

            dbCommand = xmpp.Node(tag="event", attrs={"jid": self.entity.jid})

            for vm in vms_from_local_db:

                entryTag = xmpp.Node(tag="entry")
                uuid = xmpp.JID(vm["string_jid"]).getNode()
                entryTag.addChild("item", attrs={"key": "uuid", "value": uuid})
                dbCommand.addChild(node=entryTag)

            iq = xmpp.Iq(typ="set",
                         queryNS=ARCHIPEL_NS_CENTRALAGENT,
                         to=keepalive_jid)
            iq.getTag("query").addChild(
                name="archipel",
                attrs={"action": "get_existing_vms_instances"})
            iq.getTag("query").getTag("archipel").addChild(node=dbCommand)

            def _get_existing_vms_instances_callback(conn, packed_vms):

                existing_vms_entities = self.unpack_entries(packed_vms)
                self.entity.manage_persistence(vms_from_local_db,
                                               existing_vms_entities)

            self.entity.xmppclient.SendAndCallForResponse(
                iq, _get_existing_vms_instances_callback)

        else:

            # update status to Online(0)
            self.entity.manage_persistence()
예제 #11
0
    def _fetch_users(self, xmppserver, callback, args=None):
        """
        Fetch users and populate the internal list
        @type xmppserver: String
        @param xmppserver: the xmpp server to query
        @type callback: function
        @param callback: the callback to call when fetching is complete
        @type args: dict
        @param args: optional kwards of the callback
        """
        self.users = []
        self.need_user_refresh = False

        def on_receive_users_num(conn, iq):
            if iq.getType() != "result":
                self.entity.log.error("unable to get user number: %s" % str(iq))
                return
            total_number_of_users = int(iq.getTag("command").getTag("x").getTags("field")[1].getTag("value").getData())

            def on_receive_users(conn, iq):

                if not iq.getType() == "result":
                    self.entity.log.error("unable to fetch users: %s" % str(iq))
                    return

                def manage_received_users(conn, iq):
                    items = iq.getTag("query").getTags("item")
                    users = map(lambda x: x.getAttr("jid"), items)

                    def on_receive_vcard(conn, iq):
                        try:
                            entity_type = self._extract_entity_type(iq.getTag("vCard"))
                            self.entities_types_cache[iq.getFrom().getStripped()] = entity_type
                            self.users.append({"jid": iq.getFrom().getStripped(), "type": entity_type})
                            if len(self.users) == total_number_of_users:
                                callback(**args)
                        except Exception as ex:
                            self.entity.log.error("XMPPSERVER: Error while fetching contact vCard: %s" % str(ex))

                    for user in users:
                        if not user in self.entities_types_cache:
                            iq_vcard = xmpp.Iq(typ="get", to=user)
                            iq_vcard.addChild("vCard", namespace="vcard-temp")
                            self.entity.log.debug("XMPPSERVER: Entity type of %s is not cached. fetching..." % user)
                            if self.entity.__class__.__name__ == "TNArchipelVirtualMachine":
                                self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq_vcard, on_receive_vcard)
                            else:
                                self.entity.xmppclient.SendAndCallForResponse(iq_vcard, on_receive_vcard)

                        else:
                            self.entity.log.debug("XMPPSERVER: Entity type of %s is already cached (%s)" % (user, self.entities_types_cache[user]))
                            self.users.append({"jid": user, "type": self.entities_types_cache[user]})
                            if len(self.users) == total_number_of_users:
                                callback(**args)

                try:
                    items = iq.getTag("query").getTags("item")
                    if items[0].getAttr("node"):
                        for page in range(0, len(items)):
                            iq_page = xmpp.Iq(typ="get", to=iq.getFrom())
                            iq_page.addChild("query", attrs={"node": iq.getTag("query").getTags("item")[page].getAttr("node")}, namespace="http://jabber.org/protocol/disco#items")
                            if self.entity.__class__.__name__ == "TNArchipelVirtualMachine":
                                self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq_page, manage_received_users)
                            else:
                                self.entity.xmppclient.SendAndCallForResponse(iq_page, manage_received_users)
                    else:
                        manage_received_users(conn, iq)

                except Exception as ex:
                    self.entity.log.error("XMPPSERVER: Unable to manage to get users or their vcards. error is %s" % str(ex))

            user_iq = xmpp.Iq(typ="get", to=xmppserver)
            user_iq.addChild("query", attrs={"node": "all users"}, namespace="http://jabber.org/protocol/disco#items")
            if self.entity.__class__.__name__ == "TNArchipelVirtualMachine":
                self.entity.hypervisor.xmppclient.SendAndCallForResponse(user_iq, on_receive_users)
            else:
                self.entity.xmppclient.SendAndCallForResponse(user_iq, on_receive_users)

        iq = xmpp.Iq(typ="set", to=xmppserver)
        iq.addChild("command", attrs={"action": "execute", "node": "http://jabber.org/protocol/admin#get-registered-users-num"}, namespace="http://jabber.org/protocol/commands")
        if self.entity.__class__.__name__ == "TNArchipelVirtualMachine":
            self.entity.hypervisor.xmppclient.SendAndCallForResponse(iq, on_receive_users_num)
        else:
            self.entity.xmppclient.SendAndCallForResponse(iq, on_receive_users_num)