Ejemplo n.º 1
0
Archivo: nsca.py Proyecto: zothar/pynag
def send_nsca(code, message, nscahost, hostname=None, service=None, nscabin="send_nsca", nscaconf=None):
    """ Send data via send_nsca for passive service checks

    Args:

        code (int): Return code of plugin.

        message (str): Message to pass back.

        nscahost (str): Hostname or IP address of NSCA server.

        hostname (str): Hostname the check results apply to.

        service (str): Service the check results apply to.

        nscabin (str): Location of send_nsca binary. If none specified whatever
        is in the path will be used.

        nscaconf (str): Location of the NSCA configuration to use if any.

    Returns:

        [result,stdout,stderr] of the command being run
    """

    if not hostname:
        hostname = platform.node()

    # Build command
    command = [nscabin, '-H', nscahost]
    if nscaconf:
        command += ['-c', nscaconf]

    # Just in case, status code was sent in as an integer:
    code = str(code)

    # Build the input string
    if service:
        input_string = '\t'.join([hostname, service, code, message]) + '\n'
    else:
        input_string = '\t'.join([hostname, code, message]) + '\n'

    # Execute command

    if not six.PY2 and not isinstance(input_string, six.binary_type):
        input_string = input_string.encode()
    proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
    stdout, stderr = proc.communicate(input=input_string)
    stdout = bytes2str(stdout)
    stderr = bytes2str(stderr)
    result = proc.returncode, stdout, stderr

    return result
Ejemplo n.º 2
0
 def _run_command(self, command):
     """ Run a specified command from the command line. Return stdout """
     cwd = self.gitdir
     proc = subprocess.Popen(command, cwd=cwd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,)
     stdout, stderr = proc.communicate('through stdin to stdout')
     stdout = bytes2str(stdout)
     stderr = bytes2str(stderr)
     returncode = proc.returncode
     if returncode > 0 and self.ignore_errors is False:
         errorstring = "Command '%s' returned exit status %s.\n stdout: %s \n stderr: %s\n Current user: %s"
         errorstring = errorstring % (command, returncode, stdout, stderr, getuser())
         raise EventHandlerError(errorstring, errorcode=returncode, errorstring=stderr)
     return stdout
Ejemplo n.º 3
0
    def log(self, **kwargs):
        """ Returns a log of previous commits. Log is is a list of dict objects.

        Any arguments provided will be passed directly to pynag.Utils.grep() to filter the results.

        Args:
            kwargs: Arguments passed to pynag.Utils.grep()

        Returns:
            List of dicts. Log of previous commits.

        Examples:
          self.log(author_name='nagiosadmin')

          self.log(comment__contains='localhost')
        """
        raw_log = self._run_command("git log --pretty='%H\t%an\t%ae\t%at\t%s'")
        result = []
        for line in raw_log.splitlines():
            line = bytes2str(line)
            hash, author, authoremail, authortime, comment = line.split("\t", 4)
            result.append({
                "hash": hash,
                "author_name": author,
                "author_email": authoremail,
                "author_time": datetime.datetime.fromtimestamp(float(authortime)),
                "timestamp": float(authortime),
                "comment": comment,
            })
        return grep(result, **kwargs)
Ejemplo n.º 4
0
    def get_uncommited_files(self):
        """ Returns a list of files that are have unstaged changes

        Returns:
            List. All files that have unstaged changes.
        """
        output = self._run_command("git status --porcelain")
        result = []

        output = bytes2str(output)
        for line in output.split('\n'):
            line = line.split(None, 1)
            if len(line) < 2:
                continue
            status, filename = line[0], line[1]
            # If file has been renamed, git status shows output in the form of:
            # R nrpe.cfg -> nrpe.cfg~
            # We want only the last part of the filename
            if status == 'R':
                filename = filename.split('->')[1].strip()
            # If there are special characters in the name, git will double-quote the output
            # We will remove those quotes, but we cannot use strip because it will damage:
            # files like this: "\"filename with actual doublequotes\""
            if filename.startswith('"') and filename.endswith('"'):
                filename = filename[1:-1]

            result.append({'status': status, 'filename': filename})
        return result
Ejemplo n.º 5
0
    def start(self, start_command=None, timeout=10):
        self.configure_p1_file()
        start_command = bytes2str(start_command)
        if not start_command:
            nagios_binary = self.config.guess_nagios_binary()
            start_command = "%s -d %s" % (nagios_binary, self.config.cfg_file)
        result = pynag.Utils.runCommand(command=start_command)
        code, stdout, stderr = result

        pid_file = os.path.join(self.tempdir, "nagios.pid")
        while not os.path.exists(pid_file) and timeout:
            timeout -= 1
            time.sleep(1)

        start_error = None
        if not os.path.exists(pid_file):
            start_error = "Nagios pid file did not materialize"
        if result[0] != 0:
            start_error = "Nagios did not start, bad return code"

        if start_error:
            if os.path.exists(os.path.join(self.tempdir, "nagios.log")):
                log_file_output = open(os.path.join(self.tempdir, "nagios.log")).read()
            else:
                log_file_output = "No log file found."
            message = start_error
            message += "Command: {start_command}\n"
            message += "Exit Code: {code}\n"
            message += "============\nStandard out\n{stdout}\n"
            message += "=============\nStandard Err\n{stderr}\n"
            message += "=============\nLog File output\n{log_file_output}\n"
            message = message.format(**locals())
            raise Exception(message)
        time.sleep(.2)
        return result
Ejemplo n.º 6
0
    def parse(self):
        """ Parses your status.dat file and stores in a dictionary under self.data

        Returns:

            None

        Raises:

            :py:class:`ParserError`: if problem arises while reading status.dat

            :py:class:`ParserError`: if status.dat is not found

            :py:class:`IOError`: if status.dat cannot be read
        """
        self.data = {}
        status = {}  # Holds all attributes of a single item
        key = None  # if within definition, store everything before =
        value = None  # if within definition, store everything after =
        if not self.filename:
            raise ParserError("status.dat file not found")
        lines = open(self.filename, 'rb').readlines()

        meta_type_begin_pattern = re.compile(r"^[a-zA-Z0-9]+ \{$")
        for sequence_no, line in enumerate(lines):
            line = bytes2str(line)
            line_num = sequence_no + 1
            # Cleanup and line skips
            line = line.strip()
            if line == "":
                pass
            elif line[0] == "#" or line[0] == ';':
                pass
            elif meta_type_begin_pattern.match(line):
                status = {}
                status['meta'] = {}
                status['meta']['type'] = line.split("{")[0].strip()
            elif line == "}":
                # Status definition has finished, lets add it to
                # self.data
                if status['meta']['type'] not in self.data:
                    self.data[status['meta']['type']] = []
                self.data[status['meta']['type']].append(status)
            else:
                tmp = line.split("=", 1)
                if len(tmp) == 2:
                    (key, value) = line.split("=", 1)
                    status[key] = value
                elif key == "long_plugin_output":
                    # special hack for long_output support. We get here if:
                    # * line does not contain {
                    # * line does not contain }
                    # * line does not contain =
                    # * last line parsed started with long_plugin_output=
                    status[key] += "\n" + line
                else:
                    raise ParserError(
                        "Error on %s:%s: Could not parse line: %s" %
                        (self.filename, line_num, line))