Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding checks for CUPS #22

Merged
merged 12 commits into from
Oct 14, 2024
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ You can tune the behavior with the following parameters:
triggering deletion (default 90 days).
- `--show-quotas BOOLEAN`: whether to show quotas for the VO or not (default:
`True`)
- `--check-ssh BOOLEAN`: Check SSH version on target VMs (default: `False`)
- `--check-cups BOOLEAN`: Check whether TCP/UDP port 631 is accessible
(default: `False`)

If you have access to
[Check-in LDAP](https://docs.egi.eu/users/aai/check-in/vos/#ldap) for VO
Expand Down
18 changes: 17 additions & 1 deletion fedcloud_vm_monitoring/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@
help="Show quotas for VO",
show_default=True,
)
@click.option(
"--check-ssh",
default=False,
help="Check SSH version on target VMs",
show_default=True,
)
@click.option(
"--check-cups",
default=False,
help="Check whether TCP/UDP port 631 is accessible",
show_default=True,
)
@click.option(
"--ldap-server",
default="ldaps://ldap.aai.egi.eu:636",
Expand Down Expand Up @@ -62,6 +74,8 @@ def main(
max_days,
delete,
show_quotas,
check_ssh,
check_cups,
ldap_server,
ldap_base_dn,
ldap_user,
Expand All @@ -85,7 +99,9 @@ def main(
sites = [site] if site else set(appdb_sites + fedcloudclient_sites)
for s in sites:
click.secho(f"[.] Checking VO {vo} at {s}", fg="blue", bold=True)
site_monitor = SiteMonitor(s, vo, access_token, max_days, ldap_config)
site_monitor = SiteMonitor(
s, vo, access_token, max_days, check_ssh, check_cups, ldap_config
)
try:
site_monitor.vm_monitor(delete)
except SiteMonitorException as e:
Expand Down
60 changes: 58 additions & 2 deletions fedcloud_vm_monitoring/site_monitor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Monitor VM instances running in the provider"""

import ipaddress
import subprocess
from collections import defaultdict
from datetime import datetime, timezone

Expand All @@ -27,11 +28,15 @@ class SiteMonitor:
min_secgroup_instance_ratio = 3
min_ip_instance_ratio = 1

def __init__(self, site, vo, token, max_days, ldap_config={}):
def __init__(
self, site, vo, token, max_days, check_ssh, check_cups, ldap_config={}
):
self.site = site
self.vo = vo
self.token = token
self.max_days = max_days
self.check_ssh = check_ssh
self.check_cups = check_cups
self.ldap_config = ldap_config
self.flavors = {}
self.users = defaultdict(lambda: {})
Expand Down Expand Up @@ -238,6 +243,52 @@ def get_sshd_version(self, ip_addresses):
else:
return "No public IP available to check SSH version."

def _run_shell_command(self, command):
completed = subprocess.run(
command,
shell=True,
capture_output=True,
text=True,
)
return completed.returncode, completed.stdout, completed.stderr

def check_open_port(self, ip, port, protocol):
if protocol == "tcp":
command = f"ncat --nodns -z {ip} {port}"
elif protocol == "udp":
command = f"ncat --udp --nodns --idle-timeout 3s {ip} {port}"
else:
raise SiteMonitorException(f"Protocol {protocol} not supported!")
returncode, stdout, stderr = self._run_shell_command(command)
return returncode, stdout, stderr

def check_CUPS(self, ip_addresses):
returncode_ncat, stdout_ncat, stderr_ncat = self._run_shell_command(
"which ncat"
)
if returncode_ncat != 0:
return "ncat ( https://nmap.org/ncat ) is not installed"
public_ip = self.get_public_ip(ip_addresses)
if len(public_ip) > 0:
returncode_tcp, stdout_tcp, stderr_tcp = self.check_open_port(
public_ip, 631, "tcp"
)
returncode_upd, stdout_upd, stderr_upd = self.check_open_port(
public_ip, 631, "udp"
)
if returncode_tcp == 0 or returncode_upd == 0:
return "WARNING: CUPS port is open"
elif returncode_tcp == 1 and returncode_upd == 1:
return "CUPS port is closed"
else:
return (
"Error checking CUPS port. "
"TCP return code: {returncode_tcp}, stdout: {stdout_tcp}, stderr: {stderr_tcp}. "
"UDP return code: {returncode_upd}, stdout: {stdout_upd}, stderr: {stderr_upd}."
)
else:
return "No public IP available to check CUPs version"

def process_vm(self, vm):
vm_info = self.get_vm(vm)
flv = self.get_flavor(vm["Flavor"])
Expand All @@ -252,8 +303,13 @@ def process_vm(self, vm):
("instance id", vm["ID"]),
("status", click.style(vm["Status"], fg=self.color_maps[vm["Status"]])),
("ip address", " ".join(vm_ips)),
("SSH version", sshd_version),
]
if self.check_ssh:
sshd_version = self.get_sshd_version(vm_ips)
output.append(("SSH version", sshd_version))
if self.check_cups:
CUPS_check = self.check_CUPS(vm_ips)
output.append(("CUPS", CUPS_check))
if flv:
output.append(
(
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "fedcloud-vm-monitoring"
version = "0.2.0"
version = "0.2.1"
description = "Monitoring fedcloud VMs and sites"
authors = ["Giuseppe La Rocca <giuseppe.larocca@egi.eu>",
"Enol Fernandez <enol.fernandez@egi.eu>"]
Expand Down