def job(self, run, payload, device): path = Path.cwd() / "network_data" / device.name path.mkdir(parents=True, exist_ok=True) try: device.last_runtime = datetime.now() napalm_connection = run.napalm_connection(device) run.log("info", "Fetching Operational Data", device) for data_type in ("configuration", "operational_data"): result = {} for getter in getattr(run, data_type): try: output = app.str_dict(getattr(napalm_connection, getter)()) for r in self.replacements: output = sub( r["pattern"], r["replace_with"], output, flags=M, ) result[getter] = output except Exception as e: result[getter] = f"{getter} failed because of {e}" result = app.str_dict(result) setattr(device, data_type, result) with open(path / data_type, "w") as file: file.write(result) device.last_status = "Success" device.last_duration = ( f"{(datetime.now() - device.last_runtime).total_seconds()}s" ) device.last_update = str(device.last_runtime) run.generate_yaml_file(path, device) except Exception as e: device.last_status = "Failure" device.last_failure = str(device.last_runtime) run.generate_yaml_file(path, device) return {"success": False, "result": str(e)} return {"success": True}
def notify(self, results): self.log("info", f"Sending {self.send_notification_method} notification...") notification = self.build_notification(results) file_content = deepcopy(notification) if self.include_device_results: file_content["Device Results"] = {} for device in self.devices: device_result = fetch( "result", service_id=self.service_id, parent_runtime=self.parent_runtime, device_id=device.id, allow_none=True, ) if device_result: file_content["Device Results"][ device.name] = device_result.result try: if self.send_notification_method == "mail": filename = self.runtime.replace(".", "").replace(":", "") status = "PASS" if results["success"] else "FAILED" result = app.send_email( f"{status}: {self.service.name} run by {self.creator}", app.str_dict(notification), recipients=self.mail_recipient, filename=f"results-{filename}.txt", file_content=app.str_dict(file_content), ) elif self.send_notification_method == "slack": result = SlackClient(environ.get("SLACK_TOKEN")).api_call( "chat.postMessage", channel=app.settings["slack"]["channel"], text=notification, ) else: result = post( app.settings["mattermost"]["url"], verify=app.settings["mattermost"]["verify_certificate"], data=dumps({ "channel": app.settings["mattermost"]["channel"], "text": notification, }), ).text results["notification"] = {"success": True, "result": result} except Exception: results["notification"] = { "success": False, "error": "\n".join(format_exc().splitlines()), } return results
def notify(self, results): notification = self.build_notification(results) results["notification"] = {"content": notification} try: if self.send_notification_method == "mail": filename = self.runtime.replace(".", "").replace(":", "") result = app.send_email( f"{self.name} ({'PASS' if results['success'] else 'FAILED'})", notification, recipients=self.mail_recipient, filename=f"results-{filename}.txt", file_content=app.str_dict(results), ) elif self.send_notification_method == "slack": result = SlackClient(app.slack_token).api_call( "chat.postMessage", channel=app.slack_channel, text=notification) else: result = post( app.mattermost_url, verify=app.mattermost_verify_certificate, data=dumps({ "channel": app.mattermost_channel, "text": notification }), ) results["notification"].update({"success": True, "result": result}) except Exception as exc: results["notification"].update({ "success": False, "result": str(exc) }) return results
def slack_feedback_notification(self, run: "Run", payload: dict) -> dict: slack_client = SlackClient(app.slack_token) result = slack_client.api_call( "chat.postMessage", channel=app.slack_channel, text=app.str_dict(payload["content"]), ) return {"success": True, "result": str(result)}
def notify(self, results): notification = self.build_notification(results) file_content = deepcopy(notification) if self.include_device_results: file_content["Device Results"] = { device.name: fetch( "result", service_id=self.service_id, parent_runtime=self.parent_runtime, device_id=device.id, ).result for device in self.devices } try: if self.send_notification_method == "mail": filename = self.runtime.replace(".", "").replace(":", "") result = app.send_email( f"{self.name} ({'PASS' if results['success'] else 'FAILED'})", app.str_dict(notification), recipients=self.mail_recipient, filename=f"results-{filename}.txt", file_content=app.str_dict(file_content), ) elif self.send_notification_method == "slack": result = SlackClient(environ.get("SLACK_TOKEN")).api_call( "chat.postMessage", channel=app.config["slack"]["channel"], text=notification, ) else: result = post( app.config["mattermost"]["url"], verify=app.config["mattermost"]["verify_certificate"], data=dumps({ "channel": app.config["mattermost"]["channel"], "text": notification, }), ).text results["notification"] = {"success": True, "result": result} except Exception: results["notification"] = { "success": False, "error": "\n".join(format_exc().splitlines()), } return results
def start(name, devices, payload): devices_list = devices.split(",") if devices else [] devices_list = [fetch("device", name=name).id for name in devices_list] payload_dict = loads(payload) if payload else {} payload_dict["devices"] = devices_list service = fetch("service", name=name) results = app.run(service.id, **payload_dict) Session.commit() echo(app.str_dict(results))
def start(name: str, devices: str, payload: str) -> None: devices_list = devices.split(",") if devices else [] devices_list = [fetch("Device", name=name).id for name in devices_list] payload_dict = loads(payload) if payload else {} payload_dict["devices"] = devices_list job = fetch("Job", name=name) results = app.run(job.id, **payload_dict) Session.commit() echo(app.str_dict(results))
def mail_feedback_notification(self, run: "Run", payload: dict) -> dict: name = payload["job"]["name"] app.send_email( f"{name} ({'PASS' if payload['results']['success'] else 'FAILED'})", payload["content"], recipients=payload["job"]["mail_recipient"], filename=f"results-{run.runtime.replace('.', '').replace(':', '')}.txt", file_content=app.str_dict(payload["results"]), ) return {"success": True}
def git_push(self, results: dict) -> None: path_git_folder = Path.cwd() / "git" / "automation" with open(path_git_folder / self.name, "w") as file: file.write(app.str_dict(results)) repo = Repo(str(path_git_folder)) try: repo.git.add(A=True) repo.git.commit(m=f"Automatic commit ({self.name})") except GitCommandError: pass repo.remotes.origin.push()
def start(name, devices, payload): devices_list = devices.split(",") if devices else [] devices_list = [ db.fetch("device", name=name).id for name in devices_list ] payload_dict = loads(payload) if payload else {} payload_dict.update(devices=devices_list, trigger="CLI", creator=getuser()) service = db.fetch("service", name=name) results = app.run(service.id, **payload_dict) db.session.commit() echo(app.str_dict(results))
def job(self, run, payload, device): path = Path.cwd() / "network_data" / device.name path.mkdir(parents=True, exist_ok=True) try: device.last_runtime = datetime.now() napalm_connection = run.napalm_connection(device) run.log("info", f"Fetching getters: {', '.join(run.getters)}", device) result = {} for getter in run.getters: try: output = app.str_dict(getattr(napalm_connection, getter)()) for r in self.replacements: output = sub( r["pattern"], r["replace_with"], output, flags=M, ) result[getter] = output except Exception as exc: result[getter] = f"{getter} failed because of {exc}" result = app.str_dict(result) setattr(device, self.property, result) with open(path / self.property, "w") as file: file.write(result) device.last_status = "Success" device.last_duration = ( f"{(datetime.now() - device.last_runtime).total_seconds()}s") device.last_update = str(device.last_runtime) run.update_configuration_properties(path, self.property, device) except Exception as exc: device.last_status = "Failure" device.last_failure = str(device.last_runtime) run.update_configuration_properties(path, self.property, device) return {"success": False, "result": str(exc)} return {"success": True}
def job(self, run, payload, device): try: device.last_runtime = datetime.now() path_configurations = Path.cwd() / "git" / "configurations" path_device_config = path_configurations / device.name path_device_config.mkdir(parents=True, exist_ok=True) napalm_connection = run.napalm_connection(device) run.log("info", "Fetching NAPALM configuration", device) configuration = app.str_dict(napalm_connection.get_config()) device.last_status = "Success" device.last_duration = ( f"{(datetime.now() - device.last_runtime).total_seconds()}s") for i in range(1, 4): configuration = sub( getattr(self, f"regex_pattern_{i}"), getattr(self, f"regex_replace_{i}"), configuration, flags=M, ) if device.configuration == configuration: return {"success": True, "result": "no change"} device.last_update = str(device.last_runtime) factory( "configuration", device=device.id, runtime=device.last_runtime, duration=device.last_duration, configuration=configuration, ) device.configuration = configuration with open(path_device_config / device.name, "w") as file: file.write(configuration) run.generate_yaml_file(path_device_config, device) except Exception as e: device.last_status = "Failure" device.last_failure = str(device.last_runtime) run.generate_yaml_file(path_device_config, device) return {"success": False, "result": str(e)} return {"success": True, "result": "Get Config via Napalm"}
def cli_delete(table, name): device = delete(table, name=name) Session.commit() echo(app.str_dict(device))
def update(table, properties): result = factory( table, **loads(properties)).get_properties(exclude=["positions"]) Session.commit() echo(app.str_dict(result))
def cli_fetch(table, name): echo( app.str_dict( fetch(table, name=name).get_properties(exclude=["positions"])))