Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F3747164
D2809.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
15 KB
Referenced Files
None
Subscribers
None
D2809.diff
View Options
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -100,6 +100,36 @@
This check isn't intended to detect containers
run with other engines like `systemd-nspawn`.
+### check_software_version
+
+#### Run the check
+
+With argument, check if the specified software is up-to-date.
+
+Without argument, get a list of software from the configuration.
+
+If the software can't be found, an UNKNOWN exit code is returned.
+
+#### Available check types
+
+* check_software_version: a list of software to keep up-to-date
+
+#### Configuration example
+
+```yaml
+checks:
+ check_software_version:
+ - consul
+ - nomad
+ - terraform
+ - vagrant
+ - vault
+```
+
+#### Supported software
+
+* HashiCorp CLI products with a "version" subcommand, like Consul, Vault, Vagrant or TerraForm.
+
## Return values of checks
The checks use the standard Nagios/NRPE exit codes:
diff --git a/bin/check_software_version b/bin/check_software_version
new file mode 100755
--- /dev/null
+++ b/bin/check_software_version
@@ -0,0 +1,64 @@
+#!/usr/bin/env python3
+
+# -------------------------------------------------------------
+# Platform checks - Software version
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# Description: Check if softwareversions is up-to-date
+# License: BSD-2-Clause
+# -------------------------------------------------------------
+
+
+import sys
+
+from platformchecks import exitcode
+from platformchecks.checks import SoftwareVersionCheck
+from platformchecks.config import parse_config
+
+
+# -------------------------------------------------------------
+# Configuration
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+def get_software_list():
+ return parse_config().get("checks", {}).get("check_software_version", [])
+
+
+# -------------------------------------------------------------
+# Application entry point
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+def run_all(software_list):
+ success = True
+ messages = []
+
+ for software in software_list:
+ check = SoftwareVersionCheck(software)
+ check_success, message = check.perform()
+
+ success &= check_success
+ messages.append(f"{software} {message}")
+
+ print("\n".join(messages))
+ return exitcode.ok_or_critical(success)
+
+
+def run(software):
+ check = SoftwareVersionCheck(software)
+ success, message = check.perform()
+
+ print(message)
+ return exitcode.ok_or_critical(success)
+
+
+if __name__ == "__main__":
+ argc = len(sys.argv)
+
+ if argc < 2:
+ exitCode = run_all(get_software_list())
+ else:
+ exitCode = run(sys.argv[1])
+
+ sys.exit(exitCode)
diff --git a/setup.cfg b/setup.cfg
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
[metadata]
name = platform-checks
-version = 0.1.3
+version = 0.2.0
author = Sébastien Santoro
author_email = dereckson@espace-win.org
description = Platform checks NRPE / Nagios
@@ -26,6 +26,7 @@
scripts =
bin/check_container_present
bin/check_http_200
+ bin/check_software_version
python_requires = >=3.6
install_requires =
PyYAML>=3.12,<7.0
diff --git a/src/platformchecks/checks/__init__.py b/src/platformchecks/checks/__init__.py
--- a/src/platformchecks/checks/__init__.py
+++ b/src/platformchecks/checks/__init__.py
@@ -1,2 +1,3 @@
from .http import HttpCheck
from .docker import DockerContainerCheck
+from .software import SoftwareVersionCheck
diff --git a/src/platformchecks/checks/software.py b/src/platformchecks/checks/software.py
new file mode 100644
--- /dev/null
+++ b/src/platformchecks/checks/software.py
@@ -0,0 +1,255 @@
+# -------------------------------------------------------------
+# Platform checks
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# Description: Check if a softwareversions is up-to-date
+# License: BSD-2-Clause
+# -------------------------------------------------------------
+
+
+from .softwareversions import HashiCorpSoftwareVersionCheck
+
+
+class SoftwareVersionCheck:
+ def __init__(self, software):
+ self.software = software
+
+ def perform(self):
+ check = get_software_version_check(self.software)
+ return check.perform()
+
+
+def get_software_version_check(software):
+ group = get_software_group(software)
+ if group == "HashiCorp":
+ return HashiCorpSoftwareVersionCheck(software)
+
+ raise RuntimeError(f"Unknown software group for {software}")
+
+
+def get_software_group(software):
+ for group, candidates in SOFTWARE_GROUPS.items():
+ for candidate in candidates:
+ if candidate == software:
+ return group
+
+
+SOFTWARE_GROUPS = {
+ "HashiCorp": [
+ "atlas-upload-cli",
+ "boundary",
+ "boundary-desktop",
+ "boundary-worker",
+ "consul",
+ "consul-api-gateway",
+ "consul-aws",
+ "consul-cni",
+ "consul-dataplane",
+ "consul-ecs",
+ "consul-esm",
+ "consul-k8s",
+ "consul-k8s-control-plane",
+ "consul-lambda-extension",
+ "consul-lambda-registrator",
+ "consul-replicate",
+ "consul-template",
+ "consul-terraform-sync",
+ "docker-base",
+ "docker-basetool",
+ "envconsul",
+ "hc-install",
+ "hcdiag",
+ "hcs",
+ "levant",
+ "nomad",
+ "nomad-autoscaler",
+ "nomad-device-nvidia",
+ "nomad-driver-ecs",
+ "nomad-driver-lxc",
+ "nomad-driver-podman",
+ "nomad-pack",
+ "otto",
+ "packer",
+ "sentinel",
+ "serf",
+ "terraform",
+ "terraform-ls",
+ "terraform-provider-aci",
+ "terraform-provider-acme",
+ "terraform-provider-ad",
+ "terraform-provider-akamai",
+ "terraform-provider-alicloud",
+ "terraform-provider-archive",
+ "terraform-provider-arukas",
+ "terraform-provider-atlas",
+ "terraform-provider-auth0",
+ "terraform-provider-avi",
+ "terraform-provider-aviatrix",
+ "terraform-provider-aws",
+ "terraform-provider-awscc",
+ "terraform-provider-azure",
+ "terraform-provider-azuread",
+ "terraform-provider-azuredevops",
+ "terraform-provider-azurerm",
+ "terraform-provider-azurestack",
+ "terraform-provider-baiducloud",
+ "terraform-provider-bigip",
+ "terraform-provider-bitbucket",
+ "terraform-provider-boundary",
+ "terraform-provider-brightbox",
+ "terraform-provider-checkpoint",
+ "terraform-provider-chef",
+ "terraform-provider-cherryservers",
+ "terraform-provider-circonus",
+ "terraform-provider-ciscoasa",
+ "terraform-provider-clc",
+ "terraform-provider-cloudamqp",
+ "terraform-provider-cloudflare",
+ "terraform-provider-cloudinit",
+ "terraform-provider-cloudscale",
+ "terraform-provider-cloudstack",
+ "terraform-provider-cobbler",
+ "terraform-provider-cohesity",
+ "terraform-provider-constellix",
+ "terraform-provider-consul",
+ "terraform-provider-datadog",
+ "terraform-provider-digitalocean",
+ "terraform-provider-dme",
+ "terraform-provider-dns",
+ "terraform-provider-dnsimple",
+ "terraform-provider-docker",
+ "terraform-provider-dome9",
+ "terraform-provider-dyn",
+ "terraform-provider-ecl",
+ "terraform-provider-equinix",
+ "terraform-provider-exoscale",
+ "terraform-provider-external",
+ "terraform-provider-fakewebservices",
+ "terraform-provider-fastly",
+ "terraform-provider-flexibleengine",
+ "terraform-provider-fortios",
+ "terraform-provider-genymotion",
+ "terraform-provider-github",
+ "terraform-provider-gitlab",
+ "terraform-provider-google",
+ "terraform-provider-google-beta",
+ "terraform-provider-googleworkspace",
+ "terraform-provider-grafana",
+ "terraform-provider-gridscale",
+ "terraform-provider-hcloud",
+ "terraform-provider-hcp",
+ "terraform-provider-hcs",
+ "terraform-provider-hedvig",
+ "terraform-provider-helm",
+ "terraform-provider-heroku",
+ "terraform-provider-http",
+ "terraform-provider-icinga2",
+ "terraform-provider-ignition",
+ "terraform-provider-incapsula",
+ "terraform-provider-influxdb",
+ "terraform-provider-infoblox",
+ "terraform-provider-jdcloud",
+ "terraform-provider-ksyun",
+ "terraform-provider-kubernetes",
+ "terraform-provider-kubernetes-alpha",
+ "terraform-provider-lacework",
+ "terraform-provider-launchdarkly",
+ "terraform-provider-librato",
+ "terraform-provider-linode",
+ "terraform-provider-local",
+ "terraform-provider-logentries",
+ "terraform-provider-logicmonitor",
+ "terraform-provider-mailgun",
+ "terraform-provider-metalcloud",
+ "terraform-provider-mongodbatlas",
+ "terraform-provider-mso",
+ "terraform-provider-mysql",
+ "terraform-provider-ncloud",
+ "terraform-provider-netlify",
+ "terraform-provider-newrelic",
+ "terraform-provider-nomad",
+ "terraform-provider-ns1",
+ "terraform-provider-nsxt",
+ "terraform-provider-null",
+ "terraform-provider-nutanix",
+ "terraform-provider-oci",
+ "terraform-provider-okta",
+ "terraform-provider-oktaasa",
+ "terraform-provider-oneandone",
+ "terraform-provider-onelogin",
+ "terraform-provider-opc",
+ "terraform-provider-opennebula",
+ "terraform-provider-openstack",
+ "terraform-provider-opentelekomcloud",
+ "terraform-provider-opsgenie",
+ "terraform-provider-oraclepaas",
+ "terraform-provider-ovh",
+ "terraform-provider-packet",
+ "terraform-provider-pagerduty",
+ "terraform-provider-panos",
+ "terraform-provider-postgresql",
+ "terraform-provider-powerdns",
+ "terraform-provider-prismacloud",
+ "terraform-provider-profitbricks",
+ "terraform-provider-pureport",
+ "terraform-provider-rabbitmq",
+ "terraform-provider-rancher",
+ "terraform-provider-rancher2",
+ "terraform-provider-random",
+ "terraform-provider-rightscale",
+ "terraform-provider-rubrik",
+ "terraform-provider-rundeck",
+ "terraform-provider-runscope",
+ "terraform-provider-salesforce",
+ "terraform-provider-scaleway",
+ "terraform-provider-sdm",
+ "terraform-provider-selectel",
+ "terraform-provider-selvpc",
+ "terraform-provider-signalfx",
+ "terraform-provider-skytap",
+ "terraform-provider-softlayer",
+ "terraform-provider-spotinst",
+ "terraform-provider-stackpath",
+ "terraform-provider-statuscake",
+ "terraform-provider-sumologic",
+ "terraform-provider-telefonicaopencloud",
+ "terraform-provider-template",
+ "terraform-provider-tencentcloud",
+ "terraform-provider-terraform",
+ "terraform-provider-tfcoremock",
+ "terraform-provider-tfe",
+ "terraform-provider-thunder",
+ "terraform-provider-time",
+ "terraform-provider-tls",
+ "terraform-provider-triton",
+ "terraform-provider-turbot",
+ "terraform-provider-ucloud",
+ "terraform-provider-ultradns",
+ "terraform-provider-vault",
+ "terraform-provider-vcd",
+ "terraform-provider-venafi",
+ "terraform-provider-vmc",
+ "terraform-provider-vra",
+ "terraform-provider-vra7",
+ "terraform-provider-vsphere",
+ "terraform-provider-vthunder",
+ "terraform-provider-vultr",
+ "terraform-provider-wavefront",
+ "terraform-provider-yandex",
+ "tfc-agent",
+ "vagrant",
+ "vagrant-vmware-utility",
+ "vault",
+ "vault-auditor",
+ "vault-csi-provider",
+ "vault-k8s",
+ "vault-lambda-extension",
+ "vault-mssql-ekm-provider",
+ "vault-pkcs11-provider",
+ "vault-plugin-database-oracle",
+ "vault-servicenow-credential-resolver",
+ "vault-ssh-helper",
+ "waypoint",
+ "waypoint-entrypoint",
+ ]
+}
diff --git a/src/platformchecks/checks/softwareversions/__init__.py b/src/platformchecks/checks/softwareversions/__init__.py
new file mode 100644
--- /dev/null
+++ b/src/platformchecks/checks/softwareversions/__init__.py
@@ -0,0 +1 @@
+from .hashicorp import HashiCorpSoftwareVersionCheck
diff --git a/src/platformchecks/checks/softwareversions/hashicorp.py b/src/platformchecks/checks/softwareversions/hashicorp.py
new file mode 100644
--- /dev/null
+++ b/src/platformchecks/checks/softwareversions/hashicorp.py
@@ -0,0 +1,83 @@
+# -------------------------------------------------------------
+# Platform checks
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# Description: Check if a softwareversions is up-to-date
+# License: BSD-2-Clause
+# -------------------------------------------------------------
+
+
+import re
+import requests
+import subprocess
+
+from semver import VersionInfo as Version
+
+
+class HashiCorpSoftwareVersionCheck:
+ def __init__(self, software, executable_name=None):
+ self.software = software
+ if executable_name:
+ self.executable_name = executable_name
+ else:
+ self.executable_name = software
+
+ def perform(self):
+ _, last = self.get_last_version()
+ current = self.get_current_version()
+
+ last = Version.parse(last)
+ current = Version.parse(current)
+
+ if current < last:
+ return False, f"can be upgraded from {current} to {last}"
+
+ return True, "up-to-date"
+
+ def get_last_version(self, rc=False):
+ url = f"https://releases.hashicorp.com/{self.software}/"
+ response = requests.get(url)
+
+ if response.status_code != 200:
+ return False, None
+
+ lines = [
+ line.strip()
+ for line in response.text.split("\n")
+ if f"/{self.software}/" in line
+ ]
+
+ try:
+ for line in lines:
+ version = self.extract_published_version(line)
+
+ if "+" in version:
+ continue
+
+ if rc or not is_beta(version):
+ return True, version
+ except RuntimeError:
+ return False, None
+
+ def extract_published_version(self, expression):
+ result = re.findall(r"\/([a-z0-9\-]+)\/(.*?)\/", expression)
+ if len(result) != 1:
+ raise RuntimeError("Can't extract version")
+
+ software, version = result[0]
+ if software != self.software:
+ raise RuntimeError("Unexpected software name")
+
+ return version
+
+ def get_current_version(self):
+ p = subprocess.run([self.executable_name, "version"], capture_output=True)
+ if p.returncode != 0:
+ raise RuntimeError("Can't get executable version")
+
+ expression = p.stdout.decode("UTF-8").strip()
+ return expression.split()[1][1:]
+
+
+def is_beta(version):
+ return "rc" in version or "beta" in version
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 17, 00:51 (19 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2248336
Default Alt Text
D2809.diff (15 KB)
Attached To
Mode
D2809: Check Vault and other HashiCorp products version
Attached
Detach File
Event Timeline
Log In to Comment