示例#1
0
class NapalmTracerouteService(ConnectionService):

    __tablename__ = "napalm_traceroute_service"
    pretty_name = "NAPALM Traceroute"
    parent_type = "connection_service"
    id = db.Column(Integer,
                   ForeignKey("connection_service.id"),
                   primary_key=True)
    driver = db.Column(db.SmallString)
    use_device_driver = db.Column(Boolean, default=True)
    timeout = db.Column(Integer, default=60)
    optional_args = db.Column(db.Dict)
    destination_ip = db.Column(db.SmallString)
    source_ip = db.Column(db.SmallString)
    timeout = db.Column(Integer, default=0)
    ttl = db.Column(Integer, default=0)
    vrf = db.Column(db.SmallString)

    __mapper_args__ = {"polymorphic_identity": "napalm_traceroute_service"}

    def job(self, run, payload, device):
        napalm_connection = run.napalm_connection(device)
        destination = run.sub(run.destination_ip, locals())
        source = run.sub(run.source_ip, locals())
        run.log("info", f"NAPALM TRACEROUTE : {source} -> {destination}",
                device)
        traceroute = napalm_connection.traceroute(
            destination=destination,
            source=run.source,
            vrf=run.vrf,
            ttl=run.ttl or 255,
            timeout=run.timeout or 2,
        )
        return {"success": "success" in traceroute, "result": traceroute}
示例#2
0
class Access(AbstractBase):

    __tablename__ = type = class_type = "access"
    id = db.Column(Integer, primary_key=True)
    name = db.Column(db.SmallString, unique=True)
    description = db.Column(db.LargeString)
    menu = db.Column(db.List)
    pages = db.Column(db.List)
    upper_menu = db.Column(db.List)
    get_requests = db.Column(db.List)
    post_requests = db.Column(db.List)
    delete_requests = db.Column(db.List)
    user_pools = relationship("Pool",
                              secondary=db.access_user_pools_table,
                              back_populates="access_users")
    access_pools = relationship("Pool",
                                secondary=db.access_model_pools_table,
                                back_populates="access")
    access_type = db.Column(db.SmallString)

    def get_users(self):
        return set(chain.from_iterable(pool.users for pool in self.user_pools))

    def update(self, **kwargs):
        old_users = self.get_users()
        super().update(**kwargs)
        for user in old_users | self.get_users():
            user.update_rbac()
示例#3
0
class Object(AbstractBase):

    __tablename__ = "object"
    pool_model = True
    type = db.Column(db.SmallString)
    __mapper_args__ = {
        "polymorphic_identity": "object",
        "polymorphic_on": type
    }
    id = db.Column(Integer, primary_key=True)
    creator = db.Column(db.SmallString)
    access_groups = db.Column(db.LargeString)
    last_modified = db.Column(db.TinyString, info={"log_change": False})
    subtype = db.Column(db.SmallString)
    description = db.Column(db.LargeString)
    model = db.Column(db.SmallString)
    location = db.Column(db.SmallString)
    vendor = db.Column(db.SmallString)

    def delete(self):
        number = f"{self.class_type}_number"
        for pool in self.pools:
            setattr(pool, number, getattr(pool, number) - 1)

    @classmethod
    def rbac_filter(cls, query, mode, user):
        pool_alias = aliased(models["pool"])
        return (query.join(cls.pools).join(
            models["access"], models["pool"].access).join(
                pool_alias, models["access"].user_pools).join(
                    models["user"], pool_alias.users).filter(
                        models["access"].access_type.contains(mode)).filter(
                            models["user"].name == user.name).group_by(cls.id))
示例#4
0
class MattermostNotificationService(Service):

    __tablename__ = "mattermost_notification_service"
    pretty_name = "Mattermost Notification"
    id = db.Column(Integer, ForeignKey("service.id"), primary_key=True)
    channel = db.Column(db.SmallString)
    body = db.Column(db.LargeString)

    __mapper_args__ = {
        "polymorphic_identity": "mattermost_notification_service"
    }

    def job(self, run, device=None):
        channel = run.sub(run.channel,
                          locals()) or vs.settings["mattermost"]["channel"]
        run.log("info", f"Sending MATTERMOST notification on {channel}",
                device)
        result = post(
            vs.settings["mattermost"]["url"],
            verify=vs.settings["mattermost"]["verify_certificate"],
            json={
                "channel": channel,
                "text": run.sub(run.body, locals())
            },
        )
        return {"success": True, "result": str(result)}
示例#5
0
class Link(Object):

    __tablename__ = class_type = "link"
    __mapper_args__ = {"polymorphic_identity": "link"}
    parent_type = "object"
    id = db.Column(Integer, ForeignKey("object.id"), primary_key=True)
    name = db.Column(db.SmallString)
    color = db.Column(db.TinyString, default="#000000")
    source_id = db.Column(Integer, ForeignKey("device.id"))
    destination_id = db.Column(Integer, ForeignKey("device.id"))
    source = relationship(
        Device,
        primaryjoin=source_id == Device.id,
        backref=backref("source", cascade="all, delete-orphan"),
    )
    source_name = association_proxy("source", "name")
    destination = relationship(
        Device,
        primaryjoin=destination_id == Device.id,
        backref=backref("destination", cascade="all, delete-orphan"),
    )
    destination_name = association_proxy("destination", "name")
    pools = relationship("Pool",
                         secondary=db.pool_link_table,
                         back_populates="links")
    __table_args__ = (UniqueConstraint(name, source_id, destination_id), )

    def __init__(self, **kwargs):
        self.update(**kwargs)

    @property
    def view_properties(self):
        node_properties = ("id", "longitude", "latitude")
        return {
            **{
                property: getattr(self, property)
                for property in ("id", "type", "name", "color")
            },
            **{
                f"source_{property}": getattr(self.source, property, None)
                for property in node_properties
            },
            **{
                f"destination_{property}": getattr(self.destination, property, None)
                for property in node_properties
            },
        }

    def update(self, **kwargs):
        if "source_name" in kwargs:
            kwargs["source"] = db.fetch("device",
                                        name=kwargs.pop("source_name")).id
            kwargs["destination"] = db.fetch(
                "device", name=kwargs.pop("destination_name")).id
        if "source" in kwargs and "destination" in kwargs:
            kwargs.update({
                "source_id": kwargs["source"],
                "destination_id": kwargs["destination"]
            })
        super().update(**kwargs)
示例#6
0
class Access(AbstractBase):

    __tablename__ = type = "access"
    id = db.Column(Integer, primary_key=True)
    name = db.Column(db.SmallString, unique=True)
    description = db.Column(db.SmallString)
    menu = db.Column(db.List)
    pages = db.Column(db.List)
    upper_menu = db.Column(db.List)
    get_requests = db.Column(db.List)
    post_requests = db.Column(db.List)
    users = relationship("User",
                         secondary=db.access_user_table,
                         back_populates="access")
    groups = relationship("Group",
                          secondary=db.access_group_table,
                          back_populates="access")
    pools = relationship("Pool",
                         secondary=db.access_pool_table,
                         back_populates="access")
    services = relationship("Service",
                            secondary=db.access_service_table,
                            back_populates="access")
    services_access = db.Column(db.SmallString)
    pools_access = db.Column(db.SmallString)

    def get_users(self):
        group_users = chain.from_iterable(group.users for group in self.groups)
        return set(self.users) | set(group_users)

    def update(self, **kwargs):
        old_users = self.get_users()
        super().update(**kwargs)
        for user in old_users | self.get_users():
            user.update_rbac()
示例#7
0
class Label(ViewObject):

    __tablename__ = class_type = "label"
    __mapper_args__ = {"polymorphic_identity": "label"}
    parent_type = "view_object"
    id = db.Column(Integer, ForeignKey(ViewObject.id), primary_key=True)
    text = db.Column(db.SmallString)
示例#8
0
文件: inventory.py 项目: bbrk364/eNMS
class Pool(AbstractBase):

    __tablename__ = type = "pool"
    id = db.Column(Integer, primary_key=True)
    name = db.Column(db.SmallString, unique=True)
    last_modified = db.Column(db.SmallString,
                              info={"dont_track_changes": True})
    description = db.Column(db.SmallString)
    operator = db.Column(db.SmallString, default="all")
    devices = relationship("Device",
                           secondary=db.pool_device_table,
                           back_populates="pools")
    device_number = db.Column(Integer, default=0)
    links = relationship("Link",
                         secondary=db.pool_link_table,
                         back_populates="pools")
    link_number = db.Column(Integer, default=0)
    latitude = db.Column(db.SmallString, default="0.0")
    longitude = db.Column(db.SmallString, default="0.0")
    services = relationship("Service",
                            secondary=db.service_pool_table,
                            back_populates="pools")
    runs = relationship("Run",
                        secondary=db.run_pool_table,
                        back_populates="pools")
    tasks = relationship("Task",
                         secondary=db.task_pool_table,
                         back_populates="pools")
    manually_defined = db.Column(Boolean, default=False)

    def update(self, **kwargs):
        super().update(**kwargs)
        self.compute_pool()

    def property_match(self, obj, property):
        pool_value = getattr(self, f"{obj.class_type}_{property}")
        object_value = str(getattr(obj, property))
        match = getattr(self, f"{obj.class_type}_{property}_match")
        if not pool_value:
            return True
        elif match == "inclusion":
            return pool_value in object_value
        elif match == "equality":
            return pool_value == object_value
        else:
            return bool(search(pool_value, object_value))

    def object_match(self, obj):
        operator = all if self.operator == "all" else any
        return operator(
            self.property_match(obj, property)
            for property in properties["filtering"][obj.class_type])

    def compute_pool(self):
        if self.manually_defined:
            return
        self.devices = list(filter(self.object_match, db.fetch_all("device")))
        self.device_number = len(self.devices)
        self.links = list(filter(self.object_match, db.fetch_all("link")))
        self.link_number = len(self.links)
示例#9
0
class View(ViewObject):

    __tablename__ = class_type = "view"
    __mapper_args__ = {"polymorphic_identity": "view"}
    parent_type = "view_object"
    id = db.Column(Integer, ForeignKey(ViewObject.id), primary_key=True)
    last_modified = db.Column(db.TinyString, info={"log_change": False})
    objects = relationship("ViewObject", foreign_keys="ViewObject.view_id")
示例#10
0
class PythonSnippetService(Service):

    __tablename__ = "python_snippet_service"
    pretty_name = "Python Snippet"

    id = db.Column(Integer, ForeignKey("service.id"), primary_key=True)
    source_code = db.Column(db.LargeString)

    __mapper_args__ = {"polymorphic_identity": "python_snippet_service"}

    def job(self, run, device=None):

        try:
            code_object = compile(run.source_code, "user_python_code", "exec")
        except Exception as exc:
            run.log("info", f"Compile error: {str(exc)}")
            return {"success": False, "result": {"step": "compile", "error": str(exc)}}
        results = {}

        def save_result(success, result, **kwargs):
            results.update({"success": success, "result": result, **kwargs})
            if kwargs.get("exit"):
                raise SystemExit()

        globals = {
            "results": results,
            "save_result": save_result,
            **run.global_variables(**locals()),
        }

        try:
            exec(code_object, globals)
        except SystemExit:
            pass
        except Exception as exc:
            line_number = extract_tb(exc.__traceback__)[-1][1]
            run.log("info", f"Execution error(line {line_number}): {str(exc)}")
            return {
                "success": False,
                "result": {
                    "step": "execute",
                    "error": str(exc),
                    "result": results,
                    "traceback": format_exc(),
                },
            }

        if not results:
            run.log("info", "Error: Result not set by user code on service instance")
            results = {
                "success": False,
                "result": {"error": "Result not set by user code on service instance"},
            }

        return results
示例#11
0
class DataValidationService(Service):

    __tablename__ = "data_validation_service"
    pretty_name = "Data Validation"
    id = db.Column(Integer, ForeignKey("service.id"), primary_key=True)
    query = db.Column(db.SmallString)

    __mapper_args__ = {"polymorphic_identity": "data_validation_service"}

    def job(self, run, payload, device=None):
        return {"query": run.query, "result": run.eval(run.query, **locals())[0]}
示例#12
0
class UnixCommandService(Service):

    __tablename__ = "unix_command_service"
    pretty_name = "Unix Command"
    id = db.Column(Integer, ForeignKey("service.id"), primary_key=True)
    command = db.Column(db.SmallString)

    __mapper_args__ = {"polymorphic_identity": "unix_command_service"}

    def job(self, run, device=None):
        command = run.sub(run.command, locals())
        run.log("info", f"Running UNIX command: {command}", device)
        return {"command": command, "result": check_output(command.split()).decode()}
示例#13
0
class ServiceLog(AbstractBase):

    __tablename__ = type = "service_log"
    private = True
    log_change = False
    id = db.Column(Integer, primary_key=True)
    content = db.Column(db.LargeString)
    runtime = db.Column(db.TinyString)
    service_id = db.Column(Integer, ForeignKey("service.id"))
    service = relationship("Service", foreign_keys="ServiceLog.service_id")

    def __repr__(self):
        return f"SERVICE '{self.service}' ({self.runtime})"
示例#14
0
class Line(ViewObject):

    __tablename__ = class_type = "line"
    __mapper_args__ = {"polymorphic_identity": "line"}
    parent_type = "view_object"
    id = db.Column(Integer, ForeignKey(ViewObject.id), primary_key=True)
    link_id = db.Column(Integer, ForeignKey("link.id"))
    link = relationship("Link", foreign_keys="Line.link_id")
    link_name = association_proxy("link", "name")

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        if not self.name:
            self.name = vs.get_time()
示例#15
0
class Object(AbstractBase):

    __tablename__ = "object"
    type = db.Column(db.SmallString)
    __mapper_args__ = {"polymorphic_identity": "object", "polymorphic_on": type}
    id = db.Column(Integer, primary_key=True)
    last_modified = db.Column(db.SmallString, info={"dont_track_changes": True})
    subtype = db.Column(db.SmallString)
    description = db.Column(db.SmallString)
    model = db.Column(db.SmallString)
    location = db.Column(db.SmallString)
    vendor = db.Column(db.SmallString)

    def update(self, **kwargs):
        super().update(**kwargs)
        if kwargs.get("dont_update_pools", False):
            return
        for pool in db.fetch_all("pool"):
            if pool.manually_defined:
                continue
            match = pool.object_match(self)
            relation, number = f"{self.class_type}s", f"{self.class_type}_number"
            if match and self not in getattr(pool, relation):
                getattr(pool, relation).append(self)
                setattr(pool, number, getattr(pool, number) + 1)
            if self in getattr(pool, relation) and not match:
                getattr(pool, relation).remove(self)
                setattr(pool, number, getattr(pool, number) - 1)

    def delete(self):
        number = f"{self.class_type}_number"
        for pool in self.pools:
            setattr(pool, number, getattr(pool, number) - 1)
示例#16
0
class Group(AbstractBase):

    __tablename__ = type = "group"
    id = db.Column(Integer, primary_key=True)
    name = db.Column(db.SmallString, unique=True)
    email = db.Column(db.SmallString)
    menu = db.Column(db.List)
    pages = db.Column(db.List)
    upper_menu = db.Column(db.List)
    get_requests = db.Column(db.List)
    post_requests = db.Column(db.List)
    users = relationship("User",
                         secondary=db.user_group_table,
                         back_populates="groups")
    pools = relationship("Pool",
                         secondary=db.pool_group_table,
                         back_populates="groups")
    services = relationship("Service",
                            secondary=db.service_group_table,
                            back_populates="groups")

    def update(self, **kwargs):
        super().update(**kwargs)
        self.update_rbac()

    def update_rbac(self):
        for user in self.users:
            user.update_rbac()
示例#17
0
class NapalmBackupService(ConnectionService):

    __tablename__ = "napalm_backup_service"
    pretty_name = "NAPALM Operational Data Backup"
    parent_type = "connection_service"
    id = db.Column(Integer,
                   ForeignKey("connection_service.id"),
                   primary_key=True)
    driver = db.Column(db.SmallString)
    use_device_driver = db.Column(Boolean, default=True)
    timeout = db.Column(Integer, default=60)
    optional_args = db.Column(db.Dict)
    configuration_getters = db.Column(db.List)
    operational_data_getters = db.Column(db.List)
    replacements = db.Column(db.List)

    __mapper_args__ = {"polymorphic_identity": "napalm_backup_service"}

    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_getters",
                              "operational_data_getters"):
                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 exc:
                        result[getter] = f"{getter} failed because of {exc}"
                if not result:
                    continue
                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 exc:
            device.last_status = "Failure"
            device.last_failure = str(device.last_runtime)
            run.generate_yaml_file(path, device)
            return {"success": False, "result": str(exc)}
        return {"success": True}
示例#18
0
文件: rest_call.py 项目: gnubyte/eNMS
class RestCallService(Service):

    __tablename__ = "rest_call_service"
    pretty_name = "REST Call"
    id = db.Column(Integer, ForeignKey("service.id"), primary_key=True)
    call_type = db.Column(db.SmallString)
    rest_url = db.Column(db.LargeString)
    payload = db.Column(JSON, default={})
    params = db.Column(JSON, default={})
    headers = db.Column(JSON, default={})
    verify_ssl_certificate = db.Column(Boolean, default=True)
    timeout = db.Column(Integer, default=15)
    username = db.Column(db.SmallString)
    password = db.Column(db.SmallString)

    __mapper_args__ = {"polymorphic_identity": "rest_call_service"}

    def job(self, run, payload, device=None):
        local_variables = locals()
        rest_url = run.sub(run.rest_url, local_variables)
        run.log("info", f"Sending REST Call to {rest_url}", device, logger="security")
        kwargs = {
            p: run.sub(getattr(self, p), local_variables)
            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, local_variables)
        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,
        }
示例#19
0
class Node(ViewObject):

    __tablename__ = class_type = "node"
    __mapper_args__ = {"polymorphic_identity": "node"}
    parent_type = "view_object"
    id = db.Column(Integer, ForeignKey(ViewObject.id), primary_key=True)
    model = db.Column(db.SmallString)
    device_id = db.Column(Integer, ForeignKey("device.id"))
    device = relationship("Device", foreign_keys="Node.device_id")
    device_name = association_proxy("device", "name")

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        if not self.name:
            self.name = vs.get_time()
示例#20
0
class Object(AbstractBase):

    __tablename__ = "object"
    type = db.Column(db.SmallString)
    __mapper_args__ = {
        "polymorphic_identity": "object",
        "polymorphic_on": type
    }
    id = db.Column(Integer, primary_key=True)
    public = db.Column(Boolean)
    last_modified = db.Column(db.TinyString, info={"log_change": False})
    subtype = db.Column(db.SmallString)
    description = db.Column(db.SmallString)
    model = db.Column(db.SmallString)
    location = db.Column(db.SmallString)
    vendor = db.Column(db.SmallString)

    def update(self, **kwargs):
        super().update(**kwargs)
        if kwargs.get("dont_update_pools", False):
            return
        for pool in db.fetch_all("pool"):
            if pool.manually_defined or not pool.compute(self.class_type):
                continue
            match = pool.object_match(self)
            relation, number = f"{self.class_type}s", f"{self.class_type}_number"
            if match and self not in getattr(pool, relation):
                getattr(pool, relation).append(self)
                setattr(pool, number, getattr(pool, number) + 1)
            if self in getattr(pool, relation) and not match:
                getattr(pool, relation).remove(self)
                setattr(pool, number, getattr(pool, number) - 1)

    def delete(self):
        number = f"{self.class_type}_number"
        for pool in self.pools:
            setattr(pool, number, getattr(pool, number) - 1)

    @classmethod
    def rbac_filter(cls, query, mode, user):
        public_objects = query.filter(cls.public == true())
        user_objects = (query.join(cls.pools).join(
            models["access"], models["pool"].access).join(
                models["user"], models["access"].users).filter(
                    models["access"].pools_access.contains(mode)).filter(
                        models["user"].name == user.name))
        user_group_objects = (query.join(cls.pools).join(
            models["access"], models["pool"].access).join(
                models["group"], models["access"].groups).join(
                    models["user"], models["group"].users).filter(
                        models["access"].pools_access.contains(mode)).filter(
                            models["user"].name == user.name))
        return public_objects.union(user_objects, user_group_objects)
示例#21
0
def set_pool_properties(Pool):
    for property in properties["filtering"]["device"]:
        setattr(Pool, f"device_{property}", db.Column(db.LargeString))
        setattr(
            Pool,
            f"device_{property}_match",
            db.Column(db.TinyString, default="inclusion"),
        )
    for property in properties["filtering"]["link"]:
        setattr(Pool, f"link_{property}", db.Column(db.LargeString))
        setattr(
            Pool,
            f"link_{property}_match",
            db.Column(db.TinyString, default="inclusion"),
        )
    return Pool
示例#22
0
class NapalmBackupService(ConnectionService):

    __tablename__ = "napalm_backup_service"
    pretty_name = "NAPALM Data Backup"
    parent_type = "connection_service"
    id = db.Column(Integer,
                   ForeignKey("connection_service.id"),
                   primary_key=True)
    driver = db.Column(db.SmallString)
    use_device_driver = db.Column(Boolean, default=True)
    timeout = db.Column(Integer, default=60)
    optional_args = db.Column(db.Dict)
    property = db.Column(db.SmallString)
    getters = db.Column(db.List)
    replacements = db.Column(db.List)

    __mapper_args__ = {"polymorphic_identity": "napalm_backup_service"}

    def job(self, run, device):
        path = Path.cwd() / "network_data" / device.name
        path.mkdir(parents=True, exist_ok=True)
        try:
            runtime = datetime.now()
            setattr(device, f"last_{self.property}_runtime", str(runtime))
            napalm_connection = run.napalm_connection(device)
            run.log("info", f"Fetching getters: {', '.join(run.getters)}",
                    device)
            result = {}
            for getter in run.getters:
                try:
                    output = vs.dict_to_string(
                        getattr(napalm_connection, getter)())
                    for replacement in self.replacements:
                        output = sub(
                            replacement["pattern"],
                            replacement["replace_with"],
                            output,
                            flags=M,
                        )
                    result[getter] = output
                except Exception as exc:
                    result[getter] = f"{getter} failed because of {exc}"
            result = vs.dict_to_string(result)
            setattr(device, self.property, result)
            with open(path / self.property, "w") as file:
                file.write(result)
            setattr(device, f"last_{self.property}_status", "Success")
            duration = f"{(datetime.now() - runtime).total_seconds()}s"
            setattr(device, f"last_{self.property}_duration", duration)
            setattr(device, f"last_{self.property}_update", str(runtime))
            run.update_configuration_properties(path, self.property, device)
        except Exception as exc:
            setattr(device, f"last_{self.property}_status", "Failure")
            setattr(device, f"last_{self.property}_failure", str(runtime))
            run.update_configuration_properties(path, self.property, device)
            return {"success": False, "result": str(exc)}
        return {"success": True}
示例#23
0
class User(AbstractBase, UserMixin):

    __tablename__ = type = "user"
    id = db.Column(Integer, primary_key=True)
    name = db.Column(db.SmallString, unique=True)
    email = db.Column(db.SmallString)
    permissions = db.Column(db.List)
    password = db.Column(db.SmallString)
    group = db.Column(db.SmallString)
    small_menu = db.Column(Boolean,
                           default=False,
                           info={"dont_track_changes": True})

    def update(self, **kwargs):
        if app.settings["security"][
                "hash_user_passwords"] and "password" in kwargs:
            kwargs["password"] = argon2.hash(kwargs["password"])
        super().update(**kwargs)

    @property
    def is_admin(self):
        return "Admin" in self.permissions

    def allowed(self, permission):
        return self.is_admin or permission in self.permissions
示例#24
0
class GitService(Service):

    __tablename__ = "git_service"
    pretty_name = "Git Action"
    id = db.Column(Integer, ForeignKey("service.id"), primary_key=True)
    git_repository = db.Column(db.SmallString)
    relative_path = db.Column(Boolean, default=False)
    pull = db.Column(Boolean, default=False)
    add_commit = db.Column(Boolean, default=False)
    commit_message = db.Column(db.LargeString)
    push = db.Column(Boolean, default=False)

    __mapper_args__ = {"polymorphic_identity": "git_service"}

    def job(self, run, payload, device=None):
        repo = Repo(
            Path.cwd() / self.git_repository
            if self.relative_path
            else self.git_repository
        )
        if self.add_commit:
            repo.git.add(A=True)
            repo.git.commit(m=self.commit_message)
        if self.pull:
            repo.remotes.origin.pull()
        if self.push:
            repo.remotes.origin.push()
        return {"success": True}
示例#25
0
class Event(AbstractBase):

    __tablename__ = type = "event"
    id = db.Column(Integer, primary_key=True)
    name = db.Column(db.SmallString, unique=True)
    log_source = db.Column(db.SmallString)
    log_source_regex = db.Column(Boolean, default=False)
    log_content = db.Column(db.SmallString)
    log_content_regex = db.Column(Boolean, default=False)
    service_id = db.Column(Integer, ForeignKey("service.id"))
    service = relationship("Service", back_populates="events")
    service_name = association_proxy("service", "name")

    def match_log(self, source, content):
        source_match = (
            search(self.log_source, source)
            if self.log_source_regex
            else self.log_source in source
        )
        content_match = (
            search(self.log_content, content)
            if self.log_content_regex
            else self.log_content in content
        )
        if source_match and content_match:
            self.service.run()
示例#26
0
class NapalmConfigurationService(ConnectionService):

    __tablename__ = "napalm_configuration_service"
    pretty_name = "NAPALM Configuration"
    parent_type = "connection_service"
    id = db.Column(Integer,
                   ForeignKey("connection_service.id"),
                   primary_key=True)
    action = db.Column(db.SmallString)
    content = db.Column(db.LargeString)
    driver = db.Column(db.SmallString)
    use_device_driver = db.Column(Boolean, default=True)
    timeout = db.Column(Integer, default=60)
    optional_args = db.Column(db.Dict)

    __mapper_args__ = {"polymorphic_identity": "napalm_configuration_service"}

    def job(self, run, payload, device):
        napalm_connection = run.napalm_connection(device)
        run.log(
            "info",
            "Pushing Configuration with NAPALM",
            device,
            logger="security",
        )
        config = "\n".join(run.sub(run.content, locals()).splitlines())
        getattr(napalm_connection, run.action)(config=config)
        napalm_connection.commit_config()
        return {"success": True, "result": f"Config push ({config})"}
示例#27
0
class Group(AbstractBase):

    __tablename__ = type = "group"
    id = db.Column(Integer, primary_key=True)
    name = db.Column(db.SmallString, unique=True)
    email = db.Column(db.SmallString)
    users = relationship("User",
                         secondary=db.user_group_table,
                         back_populates="groups")
    access = relationship("Access",
                          secondary=db.access_group_table,
                          back_populates="groups")

    def update(self, **kwargs):
        old_users = set(self.users)
        super().update(**kwargs)
        for user in old_users | set(self.users):
            user.update_rbac()
示例#28
0
 def database_init(cls):
     for property in app.configuration_properties:
         for timestamp in app.configuration_timestamps:
             setattr(
                 cls,
                 f"last_{property}_{timestamp}",
                 db.Column(db.SmallString, default="Never"),
             )
     return cls
示例#29
0
class SwissArmyKnifeService(Service):

    __tablename__ = "swiss_army_knife_service"
    pretty_name = "Swiss Army Knife"
    id = db.Column(Integer, ForeignKey("service.id"), primary_key=True)

    __mapper_args__ = {"polymorphic_identity": "swiss_army_knife_service"}

    def job(self, *args, **kwargs):
        return getattr(self, self.scoped_name)(*args, **kwargs)

    def Start(self, *args, **kwargs):  # noqa: N802
        return {"success": True}

    def End(self, *args, **kwargs):  # noqa: N802
        return {"success": True}

    def Placeholder(self, *args, **kwargs):  # noqa: N802
        return {"success": True}

    def cluster_monitoring(self, run, payload):
        protocol = app.settings["cluster"]["scan_protocol"]
        for instance in db.fetch_all("instance"):
            db.factory(
                "instance",
                **get(
                    f"{protocol}://{instance.ip_address}/rest/is_alive",
                    timeout=app.settings["cluster"]["scan_timeout"],
                ).json(),
            )
        return {"success": True}

    def git_push_configurations(self, run, payload, device=None):
        if not app.settings["app"]["git_repository"]:
            return
        repo = Repo(Path.cwd() / "network_data")
        try:
            repo.remotes.origin.pull()
            repo.git.add(A=True)
            repo.git.commit(m="Automatic commit (configurations)")
        except GitCommandError as exc:
            info(f"Git commit failed ({str(exc)}")
        repo.remotes.origin.push()
        return {"success": True}

    def process_payload1(self, run, payload, device):
        get_facts = run.get_result("NAPALM: Get Facts", device.name)
        get_interfaces = run.get_result("NAPALM: Get interfaces", device.name)
        uptime_less_than_50000 = get_facts["result"]["get_facts"][
            "uptime"] < 50000
        mgmg1_is_up = get_interfaces["result"]["get_interfaces"][
            "Management1"]["is_up"]
        return {
            "success": True,
            "uptime_less_5000": uptime_less_than_50000,
            "Management1 is UP": mgmg1_is_up,
        }
示例#30
0
文件: ping.py 项目: blackstrip/eNMS
class PingService(Service):

    __tablename__ = "ping_service"
    pretty_name = "ICMP / TCP Ping"
    id = db.Column(Integer, ForeignKey("service.id"), primary_key=True)
    protocol = db.Column(db.SmallString)
    ports = db.Column(db.SmallString)
    count = db.Column(Integer, default=5)
    timeout = db.Column(Integer, default=2)
    ttl = db.Column(Integer, default=60)
    packet_size = db.Column(Integer, default=56)

    __mapper_args__ = {"polymorphic_identity": "ping_service"}

    def job(self, run, device):
        if run.protocol == "ICMP":
            command = ["ping"]
            for variable, property in (
                ("c", "count"),
                ("W", "timeout"),
                ("t", "ttl"),
                ("s", "packet_size"),
            ):
                value = getattr(self, property)
                if value:
                    command.extend(f"-{variable} {value}".split())
            command.append(device.ip_address)
            run.log("info", f"Running PING ({command})", device)
            output = check_output(command).decode().strip().splitlines()
            total = output[-2].split(",")[3].split()[1]
            loss = output[-2].split(",")[2].split()[0]
            timing = output[-1].split()[3].split("/")
            return {
                "success": True,
                "result": {
                    "probes_sent": run.count,
                    "packet_loss": loss,
                    "rtt_min": timing[0],
                    "rtt_max": timing[2],
                    "rtt_avg": timing[1],
                    "rtt_stddev": timing[3],
                    "total rtt": total,
                },
            }
        else:
            result = {}
            for port in map(int, run.ports.split(",")):
                s = socket()
                s.settimeout(run.timeout)
                try:
                    connection = not s.connect_ex((device.ip_address, port))
                except (gaierror, timeout, error):
                    connection = False
                finally:
                    s.close()
                result[port] = connection
            return {"success": all(result.values()), "result": result}