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
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
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)
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
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
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))