def query_opennms(self): json_devices = http_get( self.opennms_devices, headers={ "Accept": "application/json" }, auth=(self.opennms_login, app.get_password(self.opennms_password)), ).json()["node"] devices = { device["id"]: { "name": device.get("label", device["id"]), "description": device["assetRecord"].get("description", ""), "location": device["assetRecord"].get("building", ""), "vendor": device["assetRecord"].get("manufacturer", ""), "model": device["assetRecord"].get("modelNumber", ""), "operating_system": device.get("operatingSystem", ""), "os_version": device["assetRecord"].get("sysDescription", ""), "longitude": device["assetRecord"].get("longitude", 0.0), "latitude": device["assetRecord"].get("latitude", 0.0), } for device in json_devices } for device in list(devices): link = http_get( f"{self.opennms_address}/nodes/{device}/ipinterfaces", headers={ "Accept": "application/json" }, auth=(self.opennms_login, app.get_password(self.opennms_password)), ).json() for interface in link["ipInterface"]: if interface["snmpPrimary"] == "P": devices[device]["ip_address"] = interface["ipAddress"] db.factory("device", **devices[device])
def job(self, run, payload, device=None): rest_url = run.sub(run.rest_url, locals()) run.log("info", f"Sending REST Call to {rest_url}", device) kwargs = { p: run.sub(getattr(self, p), locals()) for p in ("headers", "params", "timeout") } kwargs["verify"] = run.verify_ssl_certificate if self.username: kwargs["auth"] = HTTPBasicAuth(self.username, app.get_password(self.password)) if run.call_type in ("POST", "PUT", "PATCH"): kwargs["json"] = run.sub(run.payload, locals()) call = getattr(app.request_session, run.call_type.lower()) response = call(rest_url, **kwargs) if response.status_code not in range(200, 300): result = { "success": False, "response_code": response.status_code, "response": response.text, } if response.status_code == 401: result["result"] = "Wrong credentials supplied." return result return { "url": rest_url, "status_code": response.status_code, "headers": dict(response.headers), "result": response.text, }
def verify_password(username, password): if not username or not password: return False user = db.fetch("user", name=username) hash = app.settings["security"]["hash_user_passwords"] verify = argon2.verify if hash else str.__eq__ return verify(password, app.get_password(user.password))
def job(self, run, payload, device): ssh_client = SSHClient() if run.missing_host_key_policy: ssh_client.set_missing_host_key_policy(AutoAddPolicy()) if run.load_known_host_keys: ssh_client.load_system_host_keys() source = run.sub(run.source_file, locals()) destination = run.sub(run.destination_file, locals()) success, result = True, f"File {source} transferred successfully" ssh_client.connect( device.ip_address, username=device.username, password=app.get_password(device.password), look_for_keys=run.look_for_keys, ) if run.source_file_includes_globbing: glob_source_file_list = glob(source, recursive=False) if not glob_source_file_list: success = False result = f"Glob pattern {source} returned no matching files" else: pairs = [] for glob_source in glob_source_file_list: if Path(glob_source).is_dir(): run.log( "warn", (f"Skipping glob transfer of directory" f"{glob_source} to {destination}"), device, ) continue _, filename = split(glob_source) if destination[-1] != "/": destination = destination + "/" glob_destination = destination + filename pairs.append((glob_source, glob_destination)) run.log( "info", (f"Transferring glob file(s)" f"{glob_source_file_list} to {destination}"), device, ) run.transfer_file(ssh_client, pairs) elif not Path(source).is_file(): success = False result = (f"Source file {source} does not exist, is a directory," " or you forgot to enable globbing") else: run.log("info", f"Transferring file {source} to {destination}", device) run.transfer_file(ssh_client, [(source, destination)]) ssh_client.close() return {"success": success, "result": result}
def job(self, run, payload, device=None): arguments = run.sub(run.arguments, locals()).split() command, extra_args = ["ansible-playbook"], {} if run.pass_device_properties: extra_args = device.get_properties() extra_args["password"] = app.get_password(device.password) if run.options: extra_args.update(run.sub(run.options, locals())) if extra_args: command.extend(["-e", dumps(extra_args)]) if device: command.extend(["-i", device.ip_address + ","]) command.append(run.sub(run.playbook_path, locals())) password = extra_args.get("password") full_command = " ".join(command + arguments) if password: full_command = full_command.replace(password, "*" * 10) run.log( "info", f"Sending Ansible playbook: {full_command}", device, logger="security", ) try: result = check_output(command + arguments, cwd=app.path / "files" / "playbooks") except Exception: result = "\n".join(format_exc().splitlines()) if password: result = result.replace(password, "*" * 10) results = { "success": False, "result": result, "command": full_command } exit_code = search(r"exit status (\d+)", result) if exit_code: results["exit_code"] = self.exit_codes[exit_code.group(1)] return results try: result = result.decode("utf-8") except AttributeError: pass return {"command": full_command, "result": result}
def query_librenms(self): devices = http_get( f"{self.librenms_address}/api/v0/devices", headers={ "X-Auth-Token": app.get_password(self.librenms_token) }, ).json()["devices"] for device in devices: db.factory( "device", **{ "name": device["hostname"], "ip_address": device["ip"] or device["hostname"], "model": device["hardware"], "operating_system": device["os"], "os_version": device["version"], "location": device["location"], "longitude": device["lng"], "latitude": device["lat"], }, )
def query_netbox(self): nb = netbox_api(self.netbox_address, app.get_password(self.netbox_token)) for device in nb.dcim.devices.all(): device_ip = device.primary_ip4 or device.primary_ip6 db.factory( "device", **{ "name": device.name, "ip_address": str(device_ip).split("/")[0], "subtype": str(device.device_role), "model": str(device.device_type), "location": str(device.site), "vendor": str(device.device_type.manufacturer), "operating_system": str(device.platform), "longitude": str(nb.dcim.sites.get(name=device.site).longitude), "latitude": str(nb.dcim.sites.get(name=device.site).latitude), }, )
def job(self, run, payload, device): ssh_client = SSHClient() if run.missing_host_key_policy: ssh_client.set_missing_host_key_policy(AutoAddPolicy()) if run.load_known_host_keys: ssh_client.load_system_host_keys() source = run.sub(run.source_file, locals()) destination = run.sub(run.destination_file, locals()) ssh_client.connect( device.ip_address, username=device.username, password=app.get_password(device.password), look_for_keys=run.look_for_keys, ) if run.source_file_includes_globbing: glob_source_file_list = glob(source, recursive=False) if not glob_source_file_list: return { "success": False, "result": f"Glob pattern {source} returned no matching files", } else: files = [] for glob_source in glob_source_file_list: if Path(glob_source).is_dir(): continue _, filename = split(glob_source) if destination[-1] != "/": destination = destination + "/" glob_destination = destination + filename files.append((glob_source, glob_destination)) else: files = [(source, destination)] log = ", ".join("Transferring {} to {}".format(*pairs) for pairs in files) run.log("info", log, device) run.transfer_file(ssh_client, files) ssh_client.close() return {"success": True, "result": "Transfer successful"}