180 lines
7.9 KiB
Python
180 lines
7.9 KiB
Python
import streamlit as st
|
|
from streamlit_server.utils.helpers import format_timestamp
|
|
import uuid
|
|
|
|
def render_list():
|
|
st.header("Workload Host Management")
|
|
|
|
# List Workload Hosts
|
|
st.subheader("Existing Workload Hosts")
|
|
workload_hosts = st.session_state.client.get_workload_hosts()
|
|
|
|
if workload_hosts:
|
|
for host in workload_hosts:
|
|
with st.container():
|
|
col1, col2, col3 = st.columns([3, 1, 1])
|
|
with col1:
|
|
st.markdown(f"### {host['name']}")
|
|
|
|
# Status indicator
|
|
status = host.get('status', 'unknown').lower()
|
|
if status == 'online':
|
|
st.markdown("**🟢 Online**")
|
|
elif status == 'offline':
|
|
st.markdown("**🔴 Offline**")
|
|
else:
|
|
st.markdown("**⚪ Unknown**")
|
|
|
|
st.text(f"Hostname: {host['hostname']}")
|
|
st.text(f"Region ID: {host['region_id']}")
|
|
# TODO - this bit doesnt work, we arent pulling the labels when we pull the lists of hosts
|
|
# Display capability tags if available
|
|
if 'labels' in host and host['labels']:
|
|
capabilities = []
|
|
for label in host['labels']:
|
|
if label['label_key'] in ['libvirt-capable', 'docker-capable']:
|
|
status = "✅" if label['label_value'].lower() in ['true', 'yes', '1'] else "❌"
|
|
capabilities.append(f"{label['label_key']}:{status}")
|
|
if capabilities:
|
|
st.markdown("**Capabilities:** " + " | ".join(capabilities))
|
|
with col2:
|
|
st.text(f"ID: {host['id'][:8]}...")
|
|
with col3:
|
|
if st.button("View Details", key=f"view_{host['id']}"):
|
|
st.session_state.selected_resource = host
|
|
st.session_state.view_type = 'detail'
|
|
st.session_state.selected_resource_type = 'workload_host'
|
|
st.rerun()
|
|
|
|
def render_detail():
|
|
host_id = st.session_state.selected_resource['id']
|
|
workload_host = st.session_state.client.get_workload_host(host_id)
|
|
|
|
st.title(f"Workload Host: {workload_host['name']}")
|
|
if st.button("← Back to list view"):
|
|
st.session_state.view_type = 'list'
|
|
st.rerun()
|
|
|
|
# Get labels for this host
|
|
labels = st.session_state.client.get_labels_for_host(host_id) or []
|
|
libvirt_label = next((l for l in labels if l['label_key'] == 'libvirt-capable'), None)
|
|
docker_label = next((l for l in labels if l['label_key'] == 'docker-capable'), None)
|
|
|
|
# Capability management section
|
|
st.header("Capability Management")
|
|
cap_col1, cap_col2 = st.columns(2)
|
|
|
|
with cap_col1:
|
|
st.subheader("Libvirt Capability")
|
|
if libvirt_label:
|
|
st.success("✅ This host is libvirt-capable")
|
|
if st.button("Remove Libvirt Capability", key="remove_libvirt"):
|
|
result = st.session_state.client.remove_label(host_id, 'libvirt-capable')
|
|
if result and result.get('success'):
|
|
st.rerun()
|
|
else:
|
|
st.warning("❌ Libvirt capability not enabled")
|
|
if st.button("Add Libvirt Capability", key="add_libvirt"):
|
|
result = st.session_state.client.add_label(
|
|
host_id,
|
|
'libvirt-capable',
|
|
'true',
|
|
admin_only_view=False,
|
|
admin_only_set=False
|
|
)
|
|
if result and result.get('success'):
|
|
st.rerun()
|
|
|
|
with cap_col2:
|
|
st.subheader("Docker Capability")
|
|
if docker_label:
|
|
st.success("✅ This host is docker-capable")
|
|
if st.button("Remove Docker Capability", key="remove_docker"):
|
|
result = st.session_state.client.remove_label(host_id, 'docker-capable')
|
|
if result and result.get('success'):
|
|
st.rerun()
|
|
else:
|
|
st.warning("❌ Docker capability not enabled")
|
|
if st.button("Add Docker Capability", key="add_docker"):
|
|
result = st.session_state.client.add_label(
|
|
host_id,
|
|
'docker-capable',
|
|
'true',
|
|
admin_only_view=False,
|
|
admin_only_set=False
|
|
)
|
|
if result and result.get('success'):
|
|
st.rerun()
|
|
|
|
# Display all labels/tags in an expandable section
|
|
with st.expander("All Host Labels/Tags"):
|
|
if labels:
|
|
for label in labels:
|
|
cols = st.columns([2, 3, 1])
|
|
cols[0].markdown(f"**Key:** `{label['label_key']}`")
|
|
cols[1].markdown(f"**Value:** `{label['label_value']}`")
|
|
with cols[2]:
|
|
if st.button("Remove", key=f"remove_{label['label_key']}"):
|
|
result = st.session_state.client.remove_label(host_id, label['label_key'])
|
|
if result and result.get('success'):
|
|
st.rerun()
|
|
else:
|
|
st.info("No labels found for this host")
|
|
|
|
# Host details section
|
|
st.header("Host Details")
|
|
col1, col2 = st.columns(2)
|
|
with col1:
|
|
st.markdown(f"**ID:** `{workload_host['id']}`")
|
|
st.markdown(f"**Hostname:** `{workload_host['hostname']}`")
|
|
if st.button(f"**Region ID:** `{workload_host['region_id']}`"):
|
|
st.session_state.selected_resource = {"id": workload_host['region_id']}
|
|
st.session_state.view_type = 'detail'
|
|
st.session_state.selected_resource_type = 'region'
|
|
st.switch_page("streamlit_server/views/regions.py")
|
|
|
|
st.markdown(f"**System Manufacturer:** `{workload_host['system_manufacturer']}`")
|
|
st.markdown(f"**System Model:** `{workload_host['system_model']}`")
|
|
with col2:
|
|
st.markdown(f"**Physical Identifier:** `{workload_host['physical_identifier']}`")
|
|
st.markdown(f"**DCIM Identifier:** `{workload_host['dcim_identifier']}`")
|
|
st.markdown(f"**Installed Status:** `{workload_host['installed_status']}`")
|
|
st.markdown(f"**Available for Scheduling:** `{workload_host['available_for_scheduling']}`")
|
|
st.markdown(f"**Placement Priority:** `{workload_host['placement_priority']}`")
|
|
st.markdown(f"**Status:** `{workload_host['status']}`")
|
|
# Network configuration section
|
|
st.subheader("Network Configuration")
|
|
|
|
# Input fields for editing East-West and North-South IPs
|
|
current_ew_ip = workload_host.get('ip_address_eastwest') or ""
|
|
current_ns_ip = workload_host.get('ip_address_northsouth') or ""
|
|
|
|
new_ew_ip = st.text_input("East-West IP Address", value=current_ew_ip)
|
|
new_ns_ip = st.text_input("North-South IP Address", value=current_ns_ip)
|
|
|
|
if st.button("Save Network Configuration"):
|
|
update_payload = {
|
|
"ip_address_eastwest": new_ew_ip,
|
|
"ip_address_northsouth": new_ns_ip
|
|
}
|
|
update_result = st.session_state.client.update_workload_host(host_id, update_payload)
|
|
if update_result and update_result.get('success'):
|
|
st.success("Network configuration updated.")
|
|
st.rerun()
|
|
else:
|
|
st.error("Failed to update network configuration.")
|
|
|
|
# Display OVS Bridges
|
|
st.subheader("Attached OVS Bridges")
|
|
ovs_bridges = st.session_state.client.get_ovs_bridges_for_host(host_id)
|
|
if ovs_bridges:
|
|
for bridge in ovs_bridges:
|
|
st.markdown(f"- **{bridge['ovs_bridge_name']}**")
|
|
else:
|
|
st.info("No OVS bridges attached to this host.")
|
|
|
|
|
|
if st.session_state.view_type == 'detail' and st.session_state.selected_resource_type == 'workload_host':
|
|
render_detail()
|
|
else:
|
|
render_list() |