feat(ansible): host edit page Ansible target link/create/unlink section

This commit is contained in:
2026-06-05 18:51:33 -04:00
parent 37d9ca8a8a
commit dd0acaf623
2 changed files with 126 additions and 4 deletions
+79 -4
View File
@@ -147,14 +147,38 @@ async def create_host():
@hosts_bp.get("/<host_id>/edit")
@require_role(UserRole.operator)
async def edit_host(host_id: str):
from steward.models.ansible_inventory import AnsibleTarget
from sqlalchemy.orm import selectinload
async with current_app.db_sessionmaker() as db:
result = await db.execute(select(Host).where(Host.id == host_id))
host = result.scalar_one_or_none()
if host is None:
return "Not found", 404
if host is None:
return "Not found", 404
linked_result = await db.execute(
select(AnsibleTarget)
.where(AnsibleTarget.host_id == host_id)
.options(selectinload(AnsibleTarget.groups))
)
linked_target = linked_result.scalar_one_or_none()
# Only show targets not yet linked to any host (plus the currently linked one)
linkable_result = await db.execute(
select(AnsibleTarget)
.where(AnsibleTarget.host_id.is_(None))
.order_by(AnsibleTarget.name)
)
linkable_targets = linkable_result.scalars().all()
return await render_template(
"hosts/form.html", host=host, probe_types=list(ProbeType),
ansible_sources=_ansible_source_names())
"hosts/form.html",
host=host,
probe_types=list(ProbeType),
ansible_sources=_ansible_source_names(),
linked_target=linked_target,
linkable_targets=linkable_targets,
)
@hosts_bp.post("/<host_id>")
@@ -178,6 +202,57 @@ async def update_host(host_id: str):
return redirect(url_for("hosts.list_hosts"))
@hosts_bp.post("/<host_id>/ansible-link")
@require_role(UserRole.operator)
async def ansible_link(host_id: str):
"""Link, unlink, or create an AnsibleTarget from this host."""
from steward.models.ansible_inventory import AnsibleTarget
form = await request.form
action = form.get("action", "")
async with current_app.db_sessionmaker() as db:
async with db.begin():
if action == "unlink":
linked_result = await db.execute(
select(AnsibleTarget).where(AnsibleTarget.host_id == host_id)
)
linked = linked_result.scalar_one_or_none()
if linked:
linked.host_id = None
elif action == "link":
target_id = form.get("target_id", "").strip()
if target_id:
result = await db.execute(
select(AnsibleTarget).where(AnsibleTarget.id == target_id)
)
target = result.scalar_one_or_none()
if target:
# Clear any previous link for this host first
old_result = await db.execute(
select(AnsibleTarget).where(AnsibleTarget.host_id == host_id)
)
old = old_result.scalar_one_or_none()
if old and old.id != target_id:
old.host_id = None
target.host_id = host_id
elif action == "create":
host_result = await db.execute(select(Host).where(Host.id == host_id))
host = host_result.scalar_one_or_none()
if host:
new_target = AnsibleTarget(
id=str(uuid.uuid4()),
name=host.name,
address=host.address,
host_id=host_id,
)
db.add(new_target)
return redirect(f"/hosts/{host_id}/edit")
@hosts_bp.post("/<host_id>/run-playbook")
@require_role(UserRole.operator)
async def run_playbook(host_id: str):