Skip to content
Snippets Groups Projects
models.py 77.7 KiB
Newer Older
Benjamin Bertrand's avatar
Benjamin Bertrand committed
            "created_at": utils.format_field(self.created_at),
            "ended_at": utils.format_field(self.ended_at),
            "status": self.status.name,
            "awx_resource": self.awx_resource,
Benjamin Bertrand's avatar
Benjamin Bertrand committed
            "awx_job_id": self.awx_job_id,
            "awx_job_url": self.awx_job_url,
            "depends_on": self.depends_on_id,
Benjamin Bertrand's avatar
Benjamin Bertrand committed
            "command": self.command,
            "exception": self.exception,
            "user": str(self.user),
def trigger_core_services_update(session):
    """Trigger core services update on any Interface or Host modification.
    Called by before flush hook
    # In session.dirty, we need to check session.is_modified(instance) because the instance
    # could have been added to the session without being modified
    # In session.deleted, session.is_modified(instance) is usually False (we shouldn't check it).
    # In session.new, it will always be True and we don't need to check it.
    for kind in ("new", "dirty", "deleted"):
        for instance in getattr(session, kind):
            if isinstance(instance, (Host, Interface)) and (
                (kind == "dirty" and session.is_modified(instance))
                or (kind in ("new", "deleted"))
            ):
                utils.trigger_core_services_update()
                return True
    return False


def trigger_inventory_update(session):
    """Trigger an inventory update in AWX

    Update on any AnsibleGroup/Cname/Domain/Host/Interface/Network/NetworkScope
    modification.

    Called by before flush hook
    """
    # In session.dirty, we need to check session.is_modified(instance) because the instance
    # could have been added to the session without being modified
    # In session.deleted, session.is_modified(instance) is usually False (we shouldn't check it).
    # In session.new, it will always be True and we don't need to check it.
    for kind in ("new", "dirty", "deleted"):
        for instance in getattr(session, kind):
            if isinstance(
                instance,
                (AnsibleGroup, Cname, Domain, Host, Interface, Network, NetworkScope),
            ) and (
                (kind == "dirty" and session.is_modified(instance))
                or (kind in ("new", "deleted"))
            ):
                utils.trigger_inventory_update()
                return True
    return False


def trigger_ansible_groups_reindex(session):
    """Trigger a reindex of Ansible groups

    Update on any Host or Interface modification.
    This is required for all dynamic groups.

    Called by before flush hook
    """
    # In session.dirty, we need to check session.is_modified(instance) because the instance
    # could have been added to the session without being modified
    # In session.deleted, session.is_modified(instance) is usually False (we shouldn't check it).
    # In session.new, it will always be True and we don't need to check it.
    for kind in ("new", "dirty", "deleted"):
        for instance in getattr(session, kind):
            if isinstance(instance, (Host, Interface),) and (
                (kind == "dirty" and session.is_modified(instance))
                or (kind in ("new", "deleted"))
            ):
                utils.trigger_ansible_groups_reindex()
                return True
    return False


@sa.event.listens_for(db.session, "before_flush")
def before_flush(session, flush_context, instances):
    """Before flush hook

    Used to trigger core services and inventory update, as well
    as the Ansible groups reindex.

    See http://docs.sqlalchemy.org/en/latest/orm/session_events.html#before-flush
    """
    trigger_inventory_update(session)
    trigger_core_services_update(session)
    trigger_ansible_groups_reindex(session)
@sa.event.listens_for(Network.sensitive, "set")
def update_host_sensitive_field(target, value, oldvalue, initiator):
    """Update the host sensitive field in elasticsearch based on the Network value

    Updating the network won't trigger any update of the hosts as sensitive is just
    a property (based on host.main_interface.network).
    We have to force the update in elasticsearch index.
    """
    if value != oldvalue:
        current_app.logger.debug(f"Network {target} sensitive value changed to {value}")
        index = "host" + current_app.config["ELASTICSEARCH_INDEX_SUFFIX"]
        for interface in target.interfaces:
            current_app.logger.debug(
                f"Update sensitive to {value} for {interface.host}"
            )
            # We can't use interface.host.to_dict() because the property host.sensitive
            # doesn't have the new value yet at this time
            search.update_document(index, interface.host.id, {"sensitive": value})


# call configure_mappers after defining all the models
# required by sqlalchemy_continuum
sa.orm.configure_mappers()
ItemVersion = version_class(Item)
# Set SQLAlchemy event listeners
db.event.listen(db.session, "before_flush", SearchableMixin.before_flush)
db.event.listen(
    db.session, "after_flush_postexec", SearchableMixin.after_flush_postexec
)
db.event.listen(db.session, "after_commit", SearchableMixin.after_commit)