Пример #1
0
func (chk PHPConfig) Status() (int, string, error) {
	// getPHPVariable returns the value of a PHP configuration value as a string
	// or just "" if it doesn't exist
	getPHPVariable := func(name string) (val string) {
		quote := func(str string) string {
			return "\"" + str + "\""
		}
		// php -r 'echo get_cfg_var("default_mimetype");
		echo := fmt.Sprintf("echo get_cfg_var(%s);", quote(name))
		cmd := exec.Command("php", "-r", echo)
		out, err := cmd.CombinedOutput()
		if err != nil {
			errutil.ExecError(cmd, string(out), err)
		}
		return string(out)
	}
	actualValue := getPHPVariable(chk.variable)
	if actualValue == chk.value {
		return errutil.Success()
	} else if actualValue == "" {
		msg := "PHP configuration variable not set"
		return errutil.GenericError(msg, chk.value, []string{actualValue})
	}
	msg := "PHP variable did not match expected value"
	return errutil.GenericError(msg, chk.value, []string{actualValue})
}
Пример #2
0
func (chk SystemctlUnitFileStatus) Status() (int, string, error) {
	units, statuses, err := systemdstatus.UnitFileStatuses()
	if err != nil {
		return 1, "", err
	}
	var actualStatus string
	found := false
	for _, unit := range units {
		if unit == chk.unit {
			found = true
		}
	}
	if !found {
		return 1, "Unit file could not be found: " + chk.unit, nil
	}
	for i, un := range units {
		if un == chk.unit {
			actualStatus = statuses[i]
			if actualStatus == chk.status {
				return errutil.Success()
			}
		}
	}
	msg := "Unit didn't have status"
	return errutil.GenericError(msg, chk.status, []string{actualStatus})
}
Пример #3
0
// RoutingTableMatch asks: Is this value in this column of the routing table?
func RoutingTableMatch(col string, str string) (int, string, error) {
	column := RoutingTableColumn(col)
	if tabular.StrIn(str, column) {
		return errutil.Success()
	}
	return errutil.GenericError("Not found in routing table", str, column)
}
Пример #4
0
// freeMemOrSwap is an abstraction of FreeMemory and FreeSwap, which measures
// if the desired resource has a quantity free above the amount specified
func freeMemOrSwap(input string, swapOrMem string) (int, string, error) {
	amount, units, err := chkutil.SeparateByteUnits(input)
	if err != nil {
		log.WithFields(log.Fields{
			"err": err.Error(),
		}).Fatal("Couldn't separate string into a scalar and units")
	}
	var actualAmount int
	switch strings.ToLower(swapOrMem) {
	case "memory":
		actualAmount, err = memstatus.FreeMemory(units)
	case "swap":
		actualAmount, err = memstatus.FreeSwap(units)
	default:
		log.Fatalf("Invalid option passed to freeMemoOrSwap: %s", swapOrMem)
	}
	if err != nil {
		return 1, "", err
	} else if actualAmount > amount {
		return errutil.Success()
	}
	msg := "Free " + swapOrMem + " lower than defined threshold"
	actualString := fmt.Sprint(actualAmount) + units
	return errutil.GenericError(msg, input, []string{actualString})
}
Пример #5
0
func (chk DockerRunningAPI) Status() (int, string, error) {
	running := getRunningContainersAPI(chk.path)
	if tabular.StrContainedIn(chk.name, running) {
		return errutil.Success()
	}
	msg := "Docker container not runnning"
	return errutil.GenericError(msg, chk.name, running)
}
Пример #6
0
// ResponseMatchesGeneral is an abstraction of ResponseMatches and
// ResponseMatchesInsecure that simply varies in the security of the connection
func ResponseMatchesGeneral(urlstr string, re *regexp.Regexp, secure bool) (int, string, error) {
	body := chkutil.URLToBytes(urlstr, secure)
	if re.Match(body) {
		return errutil.Success()
	}
	msg := "Response didn't match regexp"
	return errutil.GenericError(msg, re.String(), []string{string(body)})
}
Пример #7
0
// timerCheck is pure DRY for SystemctlTimer and SystemctlTimerLoaded
func timerCheck(unit string, all bool) (int, string, error) {
	timers, err := systemdstatus.Timers(all)
	if err != nil {
		return 1, "", err
	} else if tabular.StrIn(unit, timers) {
		return errutil.Success()
	}
	return errutil.GenericError("Timer not found", unit, timers)
}
Пример #8
0
// ipCheck(int, string, error) is an abstraction of IP4 and
// IP6
func ipCheck(name string, address *net.IP, version int) (int, string, error) {
	ips := netstatus.InterfaceIPs(name)
	for _, ip := range ips {
		if ip.Equal(*address) {
			return errutil.Success()
		}
	}
	return errutil.GenericError("Interface does not have IP", address, ips)
}
Пример #9
0
func (chk SystemctlSockListening) Status() (int, string, error) {
	listening, err := systemdstatus.ListeningSockets()
	if err != nil {
		return 1, "", err
	}
	if tabular.StrIn(chk.path, listening) {
		return errutil.Success()
	}
	return errutil.GenericError("Socket wasn't listening", chk.path, listening)
}
Пример #10
0
func (chk DockerImage) Status() (int, string, error) {
	images, err := dockerstatus.DockerImageRepositories()
	if err != nil {
		return 1, "", err
	}
	if tabular.StrIn(chk.name, images) {
		return errutil.Success()
	}
	return errutil.GenericError("Docker image was not found", chk.name, images)
}
Пример #11
0
func (chk DockerImageRegexp) Status() (int, string, error) {
	images, err := dockerstatus.DockerImageRepositories()
	if err != nil {
		return 1, "", err
	}
	if tabular.ReIn(chk.re, images) {
		return errutil.Success()
	}
	msg := "Docker image was not found."
	return errutil.GenericError(msg, chk.re.String(), images)
}
Пример #12
0
func (chk PortTCP) Status() (int, string, error) {
	if netstatus.PortOpen("tcp", chk.port) {
		return errutil.Success()
	}
	// convert ports to string to send to errutil.GenericError
	var strPorts []string
	for _, port := range netstatus.OpenPorts("tcp") {
		strPorts = append(strPorts, fmt.Sprint(port))
	}
	return errutil.GenericError("Port not open", fmt.Sprint(chk.port), strPorts)
}
Пример #13
0
func (chk DockerRunningRegexp) Status() (int, string, error) {
	running, err := dockerstatus.RunningContainers()
	if err != nil {
		return 1, "", err
	}
	if tabular.ReIn(chk.re, running) {
		return errutil.Success()
	}
	msg := "Docker container not runnning"
	return errutil.GenericError(msg, chk.re.String(), running)
}
Пример #14
0
func (chk SwapUsage) Status() (int, string, error) {
	actualPercentUsed, err := memstatus.UsedSwap("percent")
	if err != nil {
		return 1, "", err
	}
	if actualPercentUsed < int(chk.maxPercentUsed) {
		return errutil.Success()
	}
	msg := "Swap usage above defined maximum"
	slc := []string{fmt.Sprint(actualPercentUsed)}
	return errutil.GenericError(msg, fmt.Sprint(chk.maxPercentUsed), slc)
}
Пример #15
0
func (chk CommandOutputMatches) Status() (int, string, error) {
	cmd := exec.Command("bash", "-c", chk.Command)
	out, err := cmd.CombinedOutput()
	if err != nil {
		errutil.ExecError(cmd, string(out), err)
	}
	if chk.re.Match(out) {
		return errutil.Success()
	}
	msg := "Command output did not match regexp"
	return errutil.GenericError(msg, chk.re.String(), []string{string(out)})
}
Пример #16
0
func (chk InodeUsage) Status() (int, string, error) {
	actualPercentUsed, err := fsstatus.PercentInodesUsed(chk.filesystem)
	if err != nil {
		return 1, "Unexpected error", err
	}
	if actualPercentUsed < chk.maxPercentUsed {
		return errutil.Success()
	}
	msg := "More disk space used than expected"
	slc := []string{fmt.Sprint(actualPercentUsed) + "%"}
	return errutil.GenericError(msg, fmt.Sprint(chk.maxPercentUsed)+"%", slc)
}
Пример #17
0
// groupNotFound creates generic error messages and exit codes for groupExits,
// UserInGroup, and GroupID
func groupNotFound(name string) (int, string, error) {
	// get a nicely formatted list of groups that do exist
	var existing []string
	groups, err := usrstatus.Groups()
	if err != nil {
		return 1, "", err
	}
	for _, group := range groups {
		existing = append(existing, group.Name)
	}
	return errutil.GenericError("Group not found", name, existing)
}
Пример #18
0
func (chk Module) Status() (int, string, error) {
	// kernelModules returns a list of all Modules that are currently loaded
	// TODO just read from /proc/Modules
	kernelModules := func() (Modules []string) {
		cmd := exec.Command("/sbin/lsmod")
		return chkutil.CommandColumnNoHeader(0, cmd)
	}
	Modules := kernelModules()
	if tabular.StrIn(chk.name, Modules) {
		return errutil.Success()
	}
	return errutil.GenericError("Module is not loaded", chk.name, Modules)
}
Пример #19
0
func (chk GroupID) Status() (int, string, error) {
	groups, err := usrstatus.Groups()
	if err != nil {
		return 0, "", err
	}
	for _, g := range groups {
		if g.Name == chk.name {
			if g.ID == chk.id {
				return errutil.Success()
			}
			msg := "Group does not have expected ID"
			return errutil.GenericError(msg, chk.id, []int{g.ID})
		}
	}
	return groupNotFound(chk.name)
}
Пример #20
0
func (chk InterfaceExists) Status() (int, string, error) {
	// getInterfaceNames returns the names of all network interfaces
	getInterfaceNames := func() (interfaces []string) {
		for _, iface := range netstatus.GetInterfaces() {
			interfaces = append(interfaces, iface.Name)
		}
		return
	}
	interfaces := getInterfaceNames()
	for _, iface := range interfaces {
		if iface == chk.name {
			return errutil.Success()
		}
	}
	return errutil.GenericError("Interface does not exist", chk.name, interfaces)
}
Пример #21
0
func (chk Temp) Status() (int, string, error) {
	// allCoreTemps returns the Temperature of each core
	allCoreTemps := func() (Temps []int) {
		cmd := exec.Command("sensors")
		out, err := cmd.CombinedOutput()
		outstr := string(out)
		errutil.ExecError(cmd, outstr, err)
		restr := `Core\s\d+:\s+[\+\-](?P<Temp>\d+)\.*\d*°C`
		re := regexp.MustCompile(restr)
		for _, line := range regexp.MustCompile(`\n+`).Split(outstr, -1) {
			if re.MatchString(line) {
				// submatch captures only the integer part of the Temperature
				matchDict := chkutil.SubmatchMap(re, line)
				if _, ok := matchDict["Temp"]; !ok {
					log.WithFields(log.Fields{
						"regexp":    re.String(),
						"matchDict": matchDict,
						"output":    outstr,
					}).Fatal("Couldn't find any Temperatures in `sensors` output")
				}
				TempInt64, err := strconv.ParseInt(matchDict["Temp"], 10, 64)
				if err != nil {
					log.WithFields(log.Fields{
						"regexp":    re.String(),
						"matchDict": matchDict,
						"output":    outstr,
						"error":     err.Error(),
					}).Fatal("Couldn't parse integer from `sensors` output")
				}
				Temps = append(Temps, int(TempInt64))
			}
		}
		return Temps
	}
	// getCoreTemp returns an integer Temperature for a certain core
	getCoreTemp := func(core int) (Temp int) {
		Temps := allCoreTemps()
		errutil.IndexError("No such core available", core, Temps)
		return Temps[core]
	}
	Temp := getCoreTemp(0)
	if Temp < int(chk.max) {
		return errutil.Success()
	}
	msg := "Core Temp exceeds defined maximum"
	return errutil.GenericError(msg, chk.max, []string{fmt.Sprint(Temp)})
}
Пример #22
0
func (chk PacmanIgnore) Status() (int, string, error) {
	path := "/etc/pacman.conf"
	data := chkutil.FileToString(path)
	re := regexp.MustCompile(`[^#]IgnorePkg\s+=\s+.+`)
	find := re.FindString(data)
	var packages []string
	if find != "" {
		spl := strings.Split(find, " ")
		errutil.IndexError("Not enough lines in "+path, 2, spl)
		packages = spl[2:] // first two are "IgnorePkg" and "="
		if tabular.StrIn(chk.pkg, packages) {
			return errutil.Success()
		}
	}
	msg := "Couldn't find package in IgnorePkg"
	return errutil.GenericError(msg, chk.pkg, packages)
}
Пример #23
0
func (chk Up) Status() (int, string, error) {
	// getUpInterfaces returns all the names of the interfaces that are up
	getUpInterfaces := func() (interfaceNames []string) {
		for _, iface := range netstatus.GetInterfaces() {
			if iface.Flags&net.FlagUp != 0 {
				interfaceNames = append(interfaceNames, iface.Name)
			}
		}
		return interfaceNames

	}
	upInterfaces := getUpInterfaces()
	if tabular.StrIn(chk.name, upInterfaces) {
		return errutil.Success()
	}
	return errutil.GenericError("Interface is not up", chk.name, upInterfaces)
}
Пример #24
0
func (chk Gateway) Status() (int, string, error) {
	// getGatewayAddress filters all Gateway IPs for a non-zero value
	getGatewayAddress := func() (addr string) {
		ips := RoutingTableColumn("Gateway")
		for _, ip := range ips {
			if ip != "0.0.0.0" {
				return ip
			}
		}
		return "0.0.0.0"
	}
	GatewayIP := getGatewayAddress()
	if chk.ip.String() == GatewayIP {
		return errutil.Success()
	}
	msg := "Gateway does not have address"
	return errutil.GenericError(msg, chk.ip.String(), []string{GatewayIP})
}
Пример #25
0
func (chk CPUUsage) Status() (int, string, error) {
	// TODO check that parameters are in range 0 < x < 100
	cpuPercentUsed := func(sampleTime time.Duration) float32 {
		idle0, total0 := getCPUSample()
		time.Sleep(sampleTime)
		idle1, total1 := getCPUSample()
		idleTicks := float32(idle1 - idle0)
		totalTicks := float32(total1 - total0)
		return (100 * (totalTicks - idleTicks) / totalTicks)
	}
	actualPercentUsed := cpuPercentUsed(3 * time.Second)
	if actualPercentUsed < float32(chk.maxPercentUsed) {
		return errutil.Success()
	}
	msg := "CPU usage above defined maximum"
	slc := []string{fmt.Sprint(actualPercentUsed)}
	return errutil.GenericError(msg, fmt.Sprint(chk.maxPercentUsed), slc)
}
Пример #26
0
func (chk Running) Status() (int, string, error) {
	// getRunningCommands returns the entries in the "Command" column of `ps aux`
	getRunningCommands := func() (Commands []string) {
		cmd := exec.Command("ps", "aux")
		return chkutil.CommandColumnNoHeader(10, cmd)
	}
	// remove this process from consideration
	Commands := getRunningCommands()
	var filtered []string
	for _, cmd := range Commands {
		if !strings.Contains(cmd, "distributive") {
			filtered = append(filtered, cmd)
		}
	}
	if tabular.StrIn(chk.name, filtered) {
		return errutil.Success()
	}
	return errutil.GenericError("Process not Running", chk.name, filtered)
}
Пример #27
0
func (chk Checksum) Status() (int, string, error) {
	// getFileChecksum is self-explanatory
	fileChecksum := func(algorithm string, path string) string {
		if path == "" {
			log.Fatal("getFileChecksum got a blank path")
		} else if _, err := os.Stat(chk.path); err != nil {
			log.WithFields(log.Fields{
				"path": chk.path,
			}).Fatal("fileChecksum got an invalid path")
		}
		// we already validated the aglorithm
		chksum, _ := fsstatus.Checksum(algorithm, chkutil.FileToBytes(path))
		return chksum
	}
	actualChksum := fileChecksum(chk.algorithm, chk.path)
	if actualChksum == chk.expectedChksum {
		return errutil.Success()
	}
	msg := "Checksums do not match for file: " + chk.path
	return errutil.GenericError(msg, chk.expectedChksum, []string{actualChksum})
}
Пример #28
0
// existsRepoWithProperty is an abstraction of YumRepoExists and YumRepoURL.
// It takes a struct field name to check, and an expected value. If the expected
// value is found in the field of a repo, it returns 0, "" else an error message.
// Valid choices for prop: "URL" | "Name" | "Name"
func existsRepoWithProperty(prop string, val *regexp.Regexp, manager string) (int, string, error) {
	var properties []string
	for _, repo := range getRepos(manager) {
		switch prop {
		case "URL":
			properties = append(properties, repo.URL)
		case "Name":
			properties = append(properties, repo.Name)
		case "Status":
			properties = append(properties, repo.Status)
		case "ID":
			properties = append(properties, repo.ID)
		default:
			log.Fatal("Repos don't have the requested property: " + prop)
		}
	}
	if tabular.ReIn(val, properties) {
		return errutil.Success()
	}
	msg := "Repo with given " + prop + " not found"
	return errutil.GenericError(msg, val.String(), properties)
}
Пример #29
0
func (chk GatewayInterface) Status() (int, string, error) {
	// getGatewayInterface returns the interface that the default Gateway is
	// operating on
	getGatewayInterface := func() (iface string) {
		ips := RoutingTableColumn("Gateway")
		names := RoutingTableColumn("Iface")
		for i, ip := range ips {
			if ip != "0.0.0.0" {
				msg := "Fewer names in kernel routing table than IPs"
				errutil.IndexError(msg, i, names)
				return names[i] // interface name
			}
		}
		return ""
	}
	iface := getGatewayInterface()
	if chk.name == iface {
		return errutil.Success()
	}
	msg := "Default Gateway does not operate on interface"
	return errutil.GenericError(msg, chk.name, []string{iface})
}
Пример #30
0
func (chk DiskUsage) Status() (int, string, error) {
	// percentFSUsed gets the percent of the filesystem that is occupied
	percentFSUsed := func(path string) int {
		// get FS info (*nix systems only!)
		var stat syscall.Statfs_t
		syscall.Statfs(path, &stat)

		// blocks * size of block = available size
		totalBytes := stat.Blocks * uint64(stat.Bsize)
		availableBytes := stat.Bavail * uint64(stat.Bsize)
		usedBytes := totalBytes - availableBytes
		percentUsed := int((float64(usedBytes) / float64(totalBytes)) * 100)
		return percentUsed

	}
	actualPercentUsed := percentFSUsed(chk.path)
	if actualPercentUsed < int(chk.maxPercentUsed) {
		return errutil.Success()
	}
	msg := "More disk space used than expected"
	slc := []string{fmt.Sprint(actualPercentUsed) + "%"}
	return errutil.GenericError(msg, fmt.Sprint(chk.maxPercentUsed)+"%", slc)
}