403Webshell
Server IP : 198.38.94.13  /  Your IP : 216.73.217.33
Web Server : Apache
System : Linux d4744.dxb1.stableserver.net 5.14.0-611.49.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Apr 21 16:39:08 EDT 2026 x86_64
User : revivere ( 1140)
PHP Version : 8.2.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /opt/saltstack/salt/lib/python3.10/site-packages/salt/netapi/rest_cherrypy/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /opt/saltstack/salt/lib/python3.10/site-packages/salt/netapi/rest_cherrypy/event_processor.py
import logging

import salt.netapi
import salt.utils.json

logger = logging.getLogger(__name__)


class SaltInfo:
    """
    Class to  handle processing and publishing of "real time" Salt upates.
    """

    def __init__(self, handler):
        """
        handler is expected to be the server side end of a websocket
        connection.
        """
        self.handler = handler

        # These represent a "real time" view into Salt's jobs.
        self.jobs = {}

        # This represents a "real time" view of minions connected to Salt.
        self.minions = {}

    def publish_minions(self):
        """
        Publishes minions as a list of dicts.
        """
        minions = []

        for minion, minion_info in self.minions.items():
            curr_minion = {}
            curr_minion.update(minion_info)
            curr_minion.update({"id": minion})
            minions.append(curr_minion)

        ret = {"minions": minions}
        self.handler.send(salt.utils.json.dumps(ret), False)

    def publish(self, key, data):
        """
        Publishes the data to the event stream.
        """
        publish_data = {key: data}
        self.handler.send(salt.utils.json.dumps(publish_data), False)

    def process_minion_update(self, event_data):
        """
        Associate grains data with a minion and publish minion update
        """
        tag = event_data["tag"]
        event_info = event_data["data"]

        _, _, _, _, mid = tag.split("/")

        if not self.minions.get(mid, None):
            self.minions[mid] = {}

        minion = self.minions[mid]

        minion.update({"grains": event_info["return"]})

        self.publish_minions()

    def process_ret_job_event(self, event_data):
        """
        Process a /ret event returned by Salt for a particular minion.
        These events contain the returned results from a particular execution.
        """
        tag = event_data["tag"]
        event_info = event_data["data"]

        _, _, jid, _, mid = tag.split("/")
        job = self.jobs.setdefault(jid, {})

        minion = job.setdefault("minions", {}).setdefault(mid, {})
        minion.update({"return": event_info["return"]})
        minion.update({"retcode": event_info["retcode"]})
        minion.update({"success": event_info["success"]})

        job_complete = all(
            [minion["success"] for mid, minion in job["minions"].items()]
        )

        if job_complete:
            job["state"] = "complete"

        self.publish("jobs", self.jobs)

    def process_new_job_event(self, event_data):
        """
        Creates a new job with properties from the event data
        like jid, function, args, timestamp.

        Also sets the initial state to started.

        Minions that are participating in this job are also noted.

        """
        job = None
        tag = event_data["tag"]
        event_info = event_data["data"]
        minions = {}
        for mid in event_info["minions"]:
            minions[mid] = {"success": False}

        job = {
            "jid": event_info["jid"],
            "start_time": event_info["_stamp"],
            "minions": minions,  # is a dictionary keyed by mids
            "fun": event_info["fun"],
            "tgt": event_info["tgt"],
            "tgt_type": event_info["tgt_type"],
            "state": "running",
        }
        self.jobs[event_info["jid"]] = job
        self.publish("jobs", self.jobs)

    def process_key_event(self, event_data):
        """
        Tag: salt/key
        Data:
        {'_stamp': '2014-05-20T22:45:04.345583',
         'act': 'delete',
         'id': 'compute.home',
         'result': True}
        """

        tag = event_data["tag"]
        event_info = event_data["data"]

        if event_info["act"] == "delete":
            self.minions.pop(event_info["id"], None)
        elif event_info["act"] == "accept":
            self.minions.setdefault(event_info["id"], {})

        self.publish_minions()

    def process_presence_events(self, event_data, token, opts):
        """
        Check if any minions have connected or dropped.
        Send a message to the client if they have.
        """
        tag = event_data["tag"]
        event_info = event_data["data"]

        minions_detected = event_info["present"]
        curr_minions = self.minions.keys()

        changed = False

        # check if any connections were dropped
        dropped_minions = set(curr_minions) - set(minions_detected)

        for minion in dropped_minions:
            changed = True
            self.minions.pop(minion, None)

        # check if any new connections were made
        new_minions = set(minions_detected) - set(curr_minions)

        tgt = ",".join(new_minions)

        if tgt:
            changed = True
            client = salt.netapi.NetapiClient(opts)
            client.run(
                {
                    "fun": "grains.items",
                    "tgt": tgt,
                    "expr_type": "list",
                    "mode": "client",
                    "client": "local",
                    "asynchronous": "local_async",
                    "token": token,
                }
            )

        if changed:
            self.publish_minions()

    def process(self, salt_data, token, opts):
        """
        Process events and publish data
        """
        parts = salt_data["tag"].split("/")
        if len(parts) < 2:
            return

        # TBD: Simplify these conditional expressions
        if parts[1] == "job":
            if parts[3] == "new":
                self.process_new_job_event(salt_data)
                if salt_data["data"]["fun"] == "grains.items":
                    self.minions = {}
            elif parts[3] == "ret":
                self.process_ret_job_event(salt_data)
                if salt_data["data"]["fun"] == "grains.items":
                    self.process_minion_update(salt_data)
        if parts[1] == "key":
            self.process_key_event(salt_data)
        if parts[1] == "presence":
            self.process_presence_events(salt_data, token, opts)

Youez - 2016 - github.com/yon3zu
LinuXploit