reconfigured streamlit and tidied api routes

This commit is contained in:
2025-03-18 14:30:02 +10:30
parent abcc4f306c
commit 5eeaa90e1d
22 changed files with 771 additions and 360 deletions
+122 -19
View File
@@ -2,25 +2,31 @@ import json
import streamlit as st
from streamlit_server.utils.helpers import format_timestamp
def render():
def render_list():
"""
Renders a list of all container workloads.
"""
st.header("Container Workload Management")
# Initialize session state variables for delete all confirmation
if 'container_delete_all_confirmation_shown' not in st.session_state:
st.session_state.container_delete_all_confirmation_shown = False
if 'container_delete_all_confirmed' not in st.session_state:
st.session_state.container_delete_all_confirmed = False
# Initialize session state variables for delete confirmation
if 'container_delete_confirmation_shown' not in st.session_state:
st.session_state.container_delete_confirmation_shown = False
if 'container_delete_confirmed' not in st.session_state:
st.session_state.container_delete_confirmed = False
# Fetch all VDCs for the dropdown
vdcs = st.session_state.client.get_vdcs()
vdcs = st.session_state.client.get_virtual_data_centers()
vdc_options = {vdc['name']: vdc['id'] for vdc in vdcs} if vdcs else {}
# Add a dropdown to select VDC
selected_vdc_name = st.selectbox("Filter by Virtual Data Center", list(vdc_options.keys()))
# Fetch all Workloads_hosts for the dropdown
workload_hosts = st.session_state.client.get_workload_hosts()
workload_host_options = {workload_host['hostname']: workload_host['id'] for workload_host in workload_hosts} if workload_hosts else {}
@@ -48,11 +54,11 @@ def render():
})
if result:
st.success("Container workload created successfully!")
# List Container Workloads
st.subheader("Existing Container Workloads")
containers = st.session_state.client.get_containers()
if containers:
# Filter containers based on the selected VDC
if selected_vdc_name:
@@ -62,26 +68,26 @@ def render():
filtered_containers = containers
# Delete All functionality
if not st.session_state.container_delete_confirmation_shown:
if not st.session_state.container_delete_all_confirmation_shown:
if st.button("Delete All Containers", key="delete_all_containers", type="primary", help="This will delete all visible containers"):
st.session_state.container_delete_confirmation_shown = True
st.session_state.container_delete_all_confirmation_shown = True
st.rerun()
# Show confirmation if delete was clicked
if st.session_state.container_delete_confirmation_shown and not st.session_state.container_delete_confirmed:
if st.session_state.container_delete_all_confirmation_shown and not st.session_state.container_delete_all_confirmed:
st.warning("Are you sure you want to delete all containers? This action cannot be undone.")
confirm_col1, confirm_col2 = st.columns([1, 1])
with confirm_col1:
if st.button("Yes, Delete All", key="confirm_delete_all_containers"):
st.session_state.container_delete_confirmed = True
st.session_state.container_delete_all_confirmed = True
st.rerun()
with confirm_col2:
if st.button("Cancel", key="cancel_delete_all_containers"):
st.session_state.container_delete_confirmation_shown = False
st.session_state.container_delete_all_confirmation_shown = False
st.rerun()
# Perform deletion if confirmed
if st.session_state.container_delete_confirmed:
if st.session_state.container_delete_all_confirmed:
deletion_count = 0
for container in filtered_containers:
# Call the delete API for each container
@@ -91,8 +97,8 @@ def render():
st.success(f"Successfully deleted {deletion_count} containers.")
# Reset the confirmation flags
st.session_state.container_delete_confirmation_shown = False
st.session_state.container_delete_confirmed = False
st.session_state.container_delete_all_confirmation_shown = False
st.session_state.container_delete_all_confirmed = False
# Display the containers
for container in filtered_containers:
@@ -118,13 +124,110 @@ def render():
st.text(f"Image: {container_name}")
with col2:
st.text(f"ID: {container['id']}")
with col3:
with col3:
if st.button("View Details", key=f"view_{container['id']}"):
print("Button is pressed")
st.session_state.selected_resource = container
st.session_state.view_type = 'detail'
st.session_state.selected_resource_type = 'container'
st.rerun()
# st.switch_page("streamlit_server/views/containers.py&container_id=d", query_params={"team": "streamlit"})
else:
st.info("No container workloads found.")
st.info("No container workloads found.")
def render_detail():
"""
Renders the details of a specific container workload.
"""
container = st.session_state.client.get_container(st.session_state.selected_resource['id'])
if not container:
st.error("Container workload not found.")
st.session_state.selected_resource = None
st.session_state.view_type = 'list'
st.session_state.selected_resource_type = None
return
st.title(f"Container Workload: {container['container_id']}")
if st.button("Back to list view"):
st.session_state.view_type = 'list'
st.rerun()
st.header("Container Workload Details")
col1, col2 = st.columns(2)
with col1:
st.markdown(f"**ID:** `{container['id']}`")
st.markdown(f"**Created:** {format_timestamp(container.get('created_at', 'Unknown'))}")
st.markdown(f"**VDC ID:** {container['vdc_id']}")
st.markdown(f"**Workload Host ID:** {container.get('container_host_id', 'N/A')}")
with col2:
if container.get('updated_at'):
st.markdown(f"**Last Updated:** {format_timestamp(container['updated_at'])}")
st.markdown(f"**Status:** {container['status']}")
st.markdown(f"**Launch Parameters:** {container.get('launch_params', 'N/A')}")
# Edit Container Workload Form
with st.expander("Edit Container Workload"):
with st.form("edit_container"):
new_status = st.selectbox("Status", ["running", "stopped", "pending","failed-deleted","pending-deleted","pending-allocation","failed-allocation","pending-allocated"], index=["running", "stopped", "pending","failed-deleted","pending-deleted","pending-allocation","failed-allocation","pending-allocated"].index(container['status']))
new_launch_params = st.text_input("Launch Parameters", value=container.get('launch_params', ''))
submit = st.form_submit_button("Update Container Workload")
if submit:
result = st.session_state.client.edit_container(container['id'], {
"status": new_status,
"launch_params": new_launch_params
})
if result:
st.success("Container workload updated successfully!")
st.session_state.selected_resource = container
st.session_state.view_type = 'detail'
st.session_state.selected_resource_type = 'container'
st.rerun()
# Delete functionality
if not st.session_state.container_delete_confirmation_shown:
if st.button("Delete container", key="delete_container", type="primary", help="This will delete visible container"):
st.session_state.container_delete_confirmation_shown = True
st.rerun()
# Show confirmation if delete was clicked
if st.session_state.container_delete_confirmation_shown and not st.session_state.container_delete_confirmed:
st.warning("Are you sure you want to delete container? This action cannot be undone.")
confirm_col1, confirm_col2 = st.columns([1, 1])
with confirm_col1:
if st.button("Yes, Delete", key="confirm_delete_container"):
st.session_state.container_delete_confirmed = True
st.rerun()
with confirm_col2:
if st.button("Cancel", key="cancel_delete_container"):
st.session_state.container_delete_confirmation_shown = False
st.rerun()
# Perform deletion if confirmed
if st.session_state.container_delete_confirmed:
result = st.session_state.client.delete_container(container['id'])
st.session_state.container_delete_confirmation_shown = False
st.session_state.container_delete_confirmed = False
if result:
st.success("Container workload deleted successfully!")
st.session_state.selected_resource = None
st.session_state.view_type = 'list'
st.session_state.selected_resource_type = 'container'
st.rerun()
st.success(f"Successfully deleted container.")
# Reset the confirmation flags
st.session_state.container_delete_confirmation_shown = False
st.session_state.container_delete_confirmed = False
if st.session_state.view_type == 'detail' and st.session_state.selected_resource_type=='container':
render_detail()
else:
render_list()
+34
View File
@@ -0,0 +1,34 @@
import streamlit as st
import pandas as pd
from streamlit_server.utils.helpers import format_timestamp
# def render():
st.header("Dashboard")
workload_hosts = st.session_state.client.get_workload_hosts()
st.subheader("Workload Hosts")
if workload_hosts:
workload_hosts_df = pd.DataFrame(workload_hosts)
st.dataframe(workload_hosts_df)
else:
st.info("No workload hosts found.")
images = st.session_state.client.get_images()
st.subheader("Images")
if images:
images_df = pd.DataFrame(images)
st.dataframe(images_df)
else:
st.info("No workload hosts found.")
regions = st.session_state.client.get_regions()
st.subheader("regions")
if regions:
regions_df = pd.DataFrame(regions)
st.dataframe(regions_df)
else:
st.info("No workload hosts found.")
+1 -226
View File
@@ -1,6 +1,5 @@
import streamlit as st
import pandas as pd
from streamlit_server.utils.helpers import format_timestamp
def render():
resource = st.session_state.selected_resource
@@ -27,237 +26,13 @@ def render():
elif resource_type == 'VirtualMachine':
render_detail_view_virtual_machine(resource)
def render_detail_view_container(container):
"""
Renders the details of a specific container workload.
"""
container = st.session_state.client.get_container(container['id'])
if not container:
st.error("Container workload not found.")
return
st.title(f"Container Workload: {container['container_id']}")
st.header("Container Workload Details")
col1, col2 = st.columns(2)
with col1:
st.markdown(f"**ID:** `{container['id']}`")
st.markdown(f"**Created:** {format_timestamp(container.get('created_at', 'Unknown'))}")
st.markdown(f"**VDC ID:** {container['vdc_id']}")
st.markdown(f"**Workload Host ID:** {container.get('container_host_id', 'N/A')}")
with col2:
if container.get('updated_at'):
st.markdown(f"**Last Updated:** {format_timestamp(container['updated_at'])}")
st.markdown(f"**Status:** {container['status']}")
st.markdown(f"**Launch Parameters:** {container.get('launch_params', 'N/A')}")
# Edit Container Workload Form
with st.expander("Edit Container Workload"):
with st.form("edit_container"):
new_status = st.selectbox("Status", ["running", "stopped", "pending","failed-deleted","pending-deleted","pending-allocation","failed-allocation","pending-allocated"], index=["running", "stopped", "pending","failed-deleted","pending-deleted","pending-allocation","failed-allocation","pending-allocated"].index(container['status']))
new_launch_params = st.text_input("Launch Parameters", value=container.get('launch_params', ''))
submit = st.form_submit_button("Update Container Workload")
if submit:
result = st.session_state.client.edit_container(container['id'], {
"status": new_status,
"launch_params": new_launch_params
})
if result:
st.success("Container workload updated successfully!")
st.session_state.selected_resource = container
st.session_state.view_type = 'detail'
st.session_state.selected_resource_type = 'container'
st.rerun()
# Delete Container Workload Button
if st.button("Delete Container Workload"):
result = st.session_state.client.delete_container(container['id'])
if result:
st.success("Container workload deleted successfully!")
st.session_state.selected_resource = None
st.session_state.view_type = 'list'
st.session_state.selected_resource_type = 'container'
st.rerun()
def render_detail_view_universe(universe):
st.title(f"Universe: {universe['name']}")
st.header("Universe Details")
col1, col2 = st.columns(2)
with col1:
st.markdown(f"**ID:** `{universe['id']}`")
st.markdown(f"**Created:** {format_timestamp(universe['created_at'])}")
with col2:
if universe.get('updated_at'):
st.markdown(f"**Last Updated:** {format_timestamp(universe['updated_at'])}")
if universe.get('description'):
st.markdown(f"**Description:** {universe['description']}")
def render_detail_view_project(project):
st.title(f"Project: {project['name']}")
st.header("Project Details")
col1, col2 = st.columns(2)
with col1:
st.markdown(f"**ID:** `{project['id']}`")
st.markdown(f"**Created:** {format_timestamp(project['created_at'])}")
with col2:
st.markdown(f"**Universe ID:** `{project['universe_id']}`")
if project.get('updated_at'):
st.markdown(f"**Last Updated:** {format_timestamp(project['updated_at'])}")
def render_detail_view_vdc(vdc):
st.title(f"Virtual Data Center: {vdc['name']}")
st.header("VDC Details")
col1, col2 = st.columns(2)
with col1:
st.markdown(f"**ID:** `{vdc['id']}`")
st.markdown(f"**Created:** {format_timestamp(vdc['created_at'])}")
with col2:
st.markdown(f"**Project ID:** `{vdc['project_id']}`")
if vdc.get('updated_at'):
st.markdown(f"**Last Updated:** {format_timestamp(vdc['updated_at'])}")
def render_detail_view_network(network):
st.title(f"Network: {network['name']}")
st.header("Network Details")
col1, col2 = st.columns(2)
with col1:
st.markdown(f"**ID:** `{network['id']}`")
st.markdown(f"**VDC ID:** `{network['vdc_id']}`")
st.markdown(f"**Created:** {network.get('created_at', 'Unknown')}")
st.markdown(f"**IPv4 CIDR:** {network.get('ipv4_cidr', 'N/A')}")
st.markdown(f"**IPv4 Gateway:** {network.get('ipv4_gateway', 'N/A')}")
with col2:
if network.get('updated_at'):
st.markdown(f"**Last Updated:** {network['updated_at']}")
if network.get('description'):
st.markdown(f"**Description:** {network['description']}")
st.markdown(f"**IPv6 CIDR:** {network.get('ipv6_cidr', 'N/A')}")
st.markdown(f"**IPv6 Gateway:** {network.get('ipv6_gateway', 'N/A')}")
st.header("Network Ports")
network_ports = st.session_state.client.get_network_ports_by_network(network['id'])
if network_ports:
# Fetch workloads to map workload_id to workload name
# TODO Enable to fetching of workloads once htey exist
# workloads = st.session_state.client.get_workloads()
# workload_map = {workload['id']: workload['name'] for workload in workloads}
# Add workload names to each network port entry
for port in network_ports:
port['workload_name'] = "Unk" #workload_map.get(port['workload_id'], 'Unknown Workload')
# Create a DataFrame with the enriched data
df = pd.DataFrame(network_ports)
df = df[[
'id', 'workload_id', 'workload_name', 'ip_address', 'mac_address',
'port_type'
]]
st.dataframe(df, use_container_width=True)
else:
st.info("No network ports found for this network.")
def render_detail_view_region(region):
st.title(f"Region: {region['name']}")
st.header("Region Details")
col1, col2 = st.columns(2)
with col1:
st.code(f"{region['id']}")
st.markdown(f"**Created:** {region.get('created_at', 'Unknown')}")
with col2:
if region.get('updated_at'):
st.markdown(f"**Last Updated:** {region['updated_at']}")
if region.get('description'):
st.markdown(f"**Description:** {region['description']}")
st.header("Region Access Entries")
region_access = st.session_state.client.get_region_access(region['id'])
if region_access:
# Fetch all projects and regions
projects = st.session_state.client.get_projects()
regions = st.session_state.client.get_regions()
# Create dictionaries to map IDs to names
project_map = {project['id']: project['name'] for project in projects}
region_map = {region['id']: region['name'] for region in regions}
# Add project and region names to each entry
for entry in region_access:
entry['project_name'] = project_map.get(entry['project_id'], 'Unknown Project')
entry['region_name'] = region_map.get(entry['region_id'], 'Unknown Region')
# Create a DataFrame with the enriched data
df = pd.DataFrame(region_access)
df = df[['project_id', 'project_name', 'region_id', 'region_name']] # Include names in the table
st.dataframe(df, use_container_width=True)
else:
st.info("No access entries found for this region.")
import streamlit as st
def render_detail_view_virtual_machine(vm):
"""
Renders the details of a specific VM workload.
"""
VirtualMachine = st.session_state.client.get_virtual_machine(vm['id'])
if not vm:
st.error("VM workload not found.")
return
print(vm)
st.title(f"VM Workload: {VirtualMachine['name']}")
st.header("VM Workload Details")
col1, col2 = st.columns(2)
with col1:
st.markdown(f"**ID:** `{VirtualMachine['id']}`")
st.markdown(f"**Created:** {format_timestamp(VirtualMachine.get('created_at', 'Unknown'))}")
st.markdown(f"**VDC ID:** {VirtualMachine['vdc_id']}")
st.markdown(f"**Workload Host ID:** {VirtualMachine.get('workload_host_id', 'N/A')}")
with col2:
if VirtualMachine.get('updated_at'):
st.markdown(f"**Last Updated:** {format_timestamp(VirtualMachine['updated_at'])}")
st.markdown(f"**Status:** {VirtualMachine['status']}")
st.markdown(f"**Launch Parameters:** {VirtualMachine.get('launch_params', 'N/A')}")
# Edit VM Workload Form
with st.expander("Edit VM Workload"):
with st.form("edit_vm"):
new_status = st.selectbox("Status", ["running", "stopped", "pending", "failed-deleted", "pending-deleted", "pending-allocation", "failed-allocation", "pending-allocated"], index=["running", "stopped", "pending", "failed-deleted", "pending-deleted", "pending-allocation", "failed-allocation", "pending-allocated"].index(VirtualMachine['status']))
new_launch_params = st.text_input("Launch Parameters", value=VirtualMachine.get('launch_params', ''))
submit = st.form_submit_button("Update VM Workload")
if submit:
result = st.session_state.client.edit_virtual_machine(VirtualMachine['id'], {
"status": new_status,
"launch_params": new_launch_params
})
if result:
st.success("VM workload updated successfully!")
st.session_state.selected_resource = vm
st.session_state.view_type = 'detail'
st.session_state.selected_resource_type = 'VirtualMachine'
st.rerun()
# Delete VM Workload Button
if st.button("Delete VM Workload"):
result = st.session_state.client.delete_virtual_machine(VirtualMachine['id'])
if result:
st.success("VM workload deleted successfully!")
st.session_state.selected_resource = None
st.session_state.view_type = 'list'
st.session_state.selected_resource_type = 'VirtualMachine'
st.rerun()
+13 -13
View File
@@ -2,16 +2,16 @@ import streamlit as st
import pandas as pd
from streamlit_server.utils.helpers import format_timestamp
def render():
st.header("Worker & Host Management")
# Fetch Worker Agents & Workload Hosts
workload_hosts = st.session_state.client.get_workload_hosts()
# Display Workload Hosts
st.subheader("Workload Hosts")
if workload_hosts:
workload_hosts_df = pd.DataFrame(workload_hosts)
st.dataframe(workload_hosts_df)
else:
st.info("No workload hosts found.")
# def render():
st.header("Worker & Host Management")
# Fetch Worker Agents & Workload Hosts
workload_hosts = st.session_state.client.get_workload_hosts()
# Display Workload Hosts
st.subheader("Workload Hosts")
if workload_hosts:
workload_hosts_df = pd.DataFrame(workload_hosts)
st.dataframe(workload_hosts_df)
else:
st.info("No workload hosts found.")
+16 -17
View File
@@ -1,7 +1,7 @@
import streamlit as st
from streamlit_server.utils.helpers import format_timestamp
def render_image_list():
def render_list():
"""
Renders a list of all images.
"""
@@ -52,16 +52,23 @@ def render_image_list():
else:
st.info("No images found.")
def render_image_detail(image_id):
def render_detail():
"""
Renders the details of a specific image.
"""
image = st.session_state.client.get_image(image_id)
image = st.session_state.client.get_image(st.session_state.selected_resource['id'])
if not image:
st.error("Image not found.")
st.session_state.selected_resource = None
st.session_state.view_type = 'list'
st.session_state.selected_resource_type = None
return
st.title(f"Image: {image['location']}")
if st.button("Back to list view"):
st.session_state.view_type = 'list'
st.rerun()
st.header("Image Details")
col1, col2 = st.columns(2)
@@ -87,7 +94,7 @@ def render_image_detail(image_id):
submit = st.form_submit_button("Update Image")
if submit:
result = st.session_state.client.edit_image(image['id'], {
result = st.session_state.client.update_image(image['id'], {
"location": new_location,
"size": new_size,
"location_type": new_location_type,
@@ -108,22 +115,14 @@ def render_image_detail(image_id):
st.session_state.view_type = 'list'
st.session_state.selected_resource_type='image'
def render():
# def render():
"""
Main render function for the Images page.
"""
# Read query parameters for routing
if not st.session_state.get('api_key'):
st.warning("Please enter your API key in the sidebar to continue.")
return
if st.session_state.view_type == 'list':
print("Viewing list")
render_image_list()
elif st.session_state.view_type == 'detail' and st.session_state.selected_resource:
print("Viewing detail")
render_image_detail(st.session_state.selected_resource["id"])
else:
st.error("Invalid view type or resource ID.")
if st.session_state.view_type == 'detail' and st.session_state.selected_resource_type=='image':
render_detail()
else:
render_list()
+62 -2
View File
@@ -2,14 +2,14 @@ import streamlit as st
import pandas as pd
from streamlit_server.utils.helpers import format_timestamp
def render():
def render_list():
st.header("Network Management")
# Create Network Form
with st.expander("Create New Network"):
with st.form("create_network"):
name = st.text_input("Network Name")
vdcs = st.session_state.client.get_vdcs()
vdcs = st.session_state.client.get_virtual_data_centers()
vdc_choices = {v['name']: v['id'] for v in vdcs} if vdcs else {}
selected_vdc = st.selectbox("Select VDC", list(vdc_choices.keys()))
submit = st.form_submit_button("Create Network")
@@ -38,3 +38,63 @@ def render():
st.session_state.view_type = 'detail'
st.session_state.selected_resource_type='network'
st.rerun() # Force Streamlit to rerun the script
def render_detail():
network = st.session_state.client.get_network(st.session_state.selected_resource['id'])
if not network:
st.error("Network not found.")
st.session_state.selected_resource = None
st.session_state.view_type = 'list'
st.session_state.selected_resource_type = None
return
st.title(f"Network: {network['name']}")
if st.button("Back to list view"):
st.session_state.view_type = 'list'
st.rerun()
st.header("Network Details")
col1, col2 = st.columns(2)
with col1:
st.markdown(f"**ID:** `{network['id']}`")
st.markdown(f"**VDC ID:** `{network['vdc_id']}`")
st.markdown(f"**Created:** {network.get('created_at', 'Unknown')}")
st.markdown(f"**IPv4 CIDR:** {network.get('ipv4_cidr', 'N/A')}")
st.markdown(f"**IPv4 Gateway:** {network.get('ipv4_gateway', 'N/A')}")
with col2:
if network.get('updated_at'):
st.markdown(f"**Last Updated:** {network['updated_at']}")
if network.get('description'):
st.markdown(f"**Description:** {network['description']}")
st.markdown(f"**IPv6 CIDR:** {network.get('ipv6_cidr', 'N/A')}")
st.markdown(f"**IPv6 Gateway:** {network.get('ipv6_gateway', 'N/A')}")
st.header("Network Ports")
network_ports = st.session_state.client.get_network_ports_by_network(network['id'])
if network_ports:
# Fetch workloads to map workload_id to workload name
# TODO Enable to fetching of workloads once htey exist
# workloads = st.session_state.client.get_workloads()
# workload_map = {workload['id']: workload['name'] for workload in workloads}
# Add workload names to each network port entry
for port in network_ports:
port['workload_name'] = "Unk" #workload_map.get(port['workload_id'], 'Unknown Workload')
# Create a DataFrame with the enriched data
df = pd.DataFrame(network_ports)
df = df[[
'id', 'workload_id', 'workload_name', 'ip_address', 'mac_address',
'port_type'
]]
st.dataframe(df, use_container_width=True)
else:
st.info("No network ports found for this network.")
if st.session_state.view_type == 'detail' and st.session_state.selected_resource_type=='network':
render_detail()
else:
render_list()
+25 -1
View File
@@ -2,7 +2,7 @@ import streamlit as st
import pandas as pd
from streamlit_server.utils.helpers import format_timestamp
def render():
def render_list():
st.header("Project Management")
# Create Project Form
@@ -39,3 +39,27 @@ def render():
st.session_state.selected_resource_type='project'
st.rerun() # Force Streamlit to rerun the script
def render_detail():
project = st.session_state.client.get_project(st.session_state.selected_resource['id'])
st.title(f"Project: {project['name']}")
if st.button("Back to list view"):
st.session_state.view_type = 'list'
st.rerun()
st.header("Project Details")
col1, col2 = st.columns(2)
with col1:
st.markdown(f"**ID:** `{project['id']}`")
st.markdown(f"**Created:** {format_timestamp(project['created_at'])}")
with col2:
st.markdown(f"**Universe ID:** `{project['universe_id']}`")
if project.get('updated_at'):
st.markdown(f"**Last Updated:** {format_timestamp(project['updated_at'])}")
if st.session_state.view_type == 'detail' and st.session_state.selected_resource_type=='project':
render_detail()
else:
render_list()
+51 -1
View File
@@ -2,7 +2,7 @@ import streamlit as st
import pandas as pd
from streamlit_server.utils.helpers import format_timestamp
def render():
def render_list():
st.header("Region Management")
# Create Region Form
@@ -39,3 +39,53 @@ def render():
st.session_state.selected_resource_type='region'
st.rerun() # Force Streamlit to rerun the script
def render_detail():
region = st.session_state.client.get_region(st.session_state.selected_resource['id'])
st.title(f"Region: {region['name']}")
if st.button("Back to list view"):
st.session_state.view_type = 'list'
st.rerun()
st.header("Region Details")
col1, col2 = st.columns(2)
with col1:
st.code(f"{region['id']}")
st.markdown(f"**Created:** {region.get('created_at', 'Unknown')}")
with col2:
if region.get('updated_at'):
st.markdown(f"**Last Updated:** {region['updated_at']}")
if region.get('description'):
st.markdown(f"**Description:** {region['description']}")
st.header("Region Access Entries")
region_access = st.session_state.client.get_region_access(region['id'])
if region_access:
# Fetch all projects and regions
projects = st.session_state.client.get_projects()
regions = st.session_state.client.get_regions()
# Create dictionaries to map IDs to names
project_map = {project['id']: project['name'] for project in projects}
region_map = {region['id']: region['name'] for region in regions}
# Add project and region names to each entry
for entry in region_access:
entry['project_name'] = project_map.get(entry['project_id'], 'Unknown Project')
entry['region_name'] = region_map.get(entry['region_id'], 'Unknown Region')
# Create a DataFrame with the enriched data
df = pd.DataFrame(region_access)
df = df[['project_id', 'project_name', 'region_id', 'region_name']] # Include names in the table
st.dataframe(df, use_container_width=True)
else:
st.info("No access entries found for this region.")
if st.session_state.view_type == 'detail' and st.session_state.selected_resource_type=='region':
render_detail()
else:
render_list()
+61 -15
View File
@@ -7,31 +7,77 @@ def render():
if 'api_key' not in st.session_state or st.session_state.api_key == "":
st.session_state.api_key = "xxx"
print("Providing xxx as api key")
# Display the API key input with the default value
api_key = st.sidebar.text_input("API Key", type="password", value=st.session_state.get('api_key'))
if api_key:
st.session_state.api_key = api_key
# Define views with appropriate icons
views = {
"Universes": "🌌",
"Projects": "📂",
"Virtual Data Centers": "🏢",
"Networks": "🔌",
"Regions": "🌎",
"Hosts": "💻",
"Images": "🖼️",
"Containers": "📦",
"Websocket": "🔄",
"Virtual Machines": "⚙️"
}
# Style the sidebar navigation
st.sidebar.markdown("""
<style>
/* Reduce spacing between items */
div.row-widget.stSelectbox > div {
margin-bottom: 0;
}
/* Style for the navbar */
.streamlit-expanderHeader {
font-size: 1em;
padding: 0.5rem;
}
/* Make the select box more compact */
.stSelectbox div:first-child {
padding-bottom: 0;
}
</style>
""", unsafe_allow_html=True)
st.sidebar.header("Navigation")
views = ["Universes", "Projects", "Virtual Data Centers", "Networks", "Regions", "Hosts", "Images", "Containers", "Websocket","Virtual Machines"]
# Initialize current view in session state if not present
if 'current_view' not in st.session_state:
st.session_state.current_view = list(views.keys())[0]
# Format the options with icons
format_func = lambda x: f"{views[x]} {x}"
# Use selectbox for navigation
if st.session_state.view_type == 'list':
# if st.sidebar.radio("Select View", views):
# print(f"Radio buton pressed")
# st.session_state.current_view = "D"
for _viewType in views:
if st.sidebar.button(_viewType):
print(f"Processing sidebar button pres {_viewType}")
st.session_state.current_view=_viewType
st.session_state.selected_resource = None
st.session_state.view_type = 'list'
st.session_state.selected_resource_type = None
# st.rerun() # Force Streamlit to rerun the script
selected_view = st.sidebar.selectbox(
"Select Resource Type",
options=list(views.keys()),
format_func=format_func,
index=list(views.keys()).index(st.session_state.current_view),
label_visibility="collapsed"
)
# Handle navigation
if selected_view != st.session_state.current_view:
st.session_state.current_view = selected_view
st.session_state.selected_resource = None
st.session_state.view_type = 'list'
st.session_state.selected_resource_type = None
st.rerun()
if st.session_state.view_type == 'detail':
if st.sidebar.button("← Back to List View"):
st.session_state.view_type = 'list'
st.session_state.selected_resource = None
st.session_state.selected_resource_type = None
st.rerun() # Force Streamlit to rerun the script
st.rerun()
+31 -1
View File
@@ -2,7 +2,7 @@ import streamlit as st
import pandas as pd
from streamlit_server.utils.helpers import format_timestamp
def render():
def render_list():
st.header("Universe Management")
with st.expander("Create New Universe"):
@@ -37,3 +37,33 @@ def render():
st.rerun() # Force Streamlit to rerun the script
def render_detail():
universe = st.session_state.client.get_universe(st.session_state.selected_resource['id'])
if not universe:
st.error("Universe not found.")
st.session_state.selected_resource = None
st.session_state.view_type = 'list'
st.session_state.selected_resource_type = None
return
st.title(f"Universe: {universe['name']}")
if st.button("Back to list view"):
st.session_state.view_type = 'list'
st.rerun()
st.header("Universe Details")
col1, col2 = st.columns(2)
with col1:
st.markdown(f"**ID:** `{universe['id']}`")
st.markdown(f"**Created:** {format_timestamp(universe['created_at'])}")
with col2:
if universe.get('updated_at'):
st.markdown(f"**Last Updated:** {format_timestamp(universe['updated_at'])}")
if universe.get('description'):
st.markdown(f"**Description:** {universe['description']}")
if st.session_state.view_type == 'detail' and st.session_state.selected_resource_type=='universe':
render_detail()
else:
render_list()
@@ -2,13 +2,13 @@ import streamlit as st
import pandas as pd
from streamlit_server.utils.helpers import format_timestamp
def render():
st.header("Virtual Data Center (VDC) Management")
def render_list():
st.header("Virtual Data Center Management")
# Create VDC Form
with st.expander("Create New VDC"):
with st.expander("Create New Virtual Data Center"):
with st.form("create_vdc"):
name = st.text_input("VDC Name")
name = st.text_input("Virtual Data Center Name")
projects = st.session_state.client.get_projects()
project_choices = {p['name']: p['id'] for p in projects} if projects else {}
selected_project = st.selectbox("Select Project", list(project_choices.keys()))
@@ -17,11 +17,11 @@ def render():
if submit and name and selected_project:
result = st.session_state.client.create_vdc(name, project_choices[selected_project])
if result:
st.success(f"VDC '{name}' created successfully!")
st.success(f"Virtual Data Center '{name}' created successfully!")
# List VDCs
st.subheader("Existing VDCs")
vdcs = st.session_state.client.get_vdcs()
st.subheader("Existing Virtual Data Center")
vdcs = st.session_state.client.get_virtual_data_centers()
# projects = st.session_state.client.get_projects()
# regions = st.session_state.client.get_regions()
@@ -41,7 +41,31 @@ def render():
if st.button("View Details", key=f"view_{vdc['id']}"):
st.session_state.selected_resource = vdc
st.session_state.view_type = 'detail'
st.session_state.selected_resource_type='vdc'
st.session_state.selected_resource_type='virtual_data_center'
st.rerun() # Force Streamlit to rerun the script
def render_detail():
vdc = st.session_state.client.get_virtual_data_center(st.session_state.selected_resource['id'])
st.title(f"Virtual Data Center: {vdc['name']}")
if st.button("Back to list view"):
st.session_state.view_type = 'list'
st.rerun()
st.header("Virtual Data Center Details")
col1, col2 = st.columns(2)
with col1:
st.markdown(f"**ID:** `{vdc['id']}`")
st.markdown(f"**Created:** {format_timestamp(vdc['created_at'])}")
with col2:
st.markdown(f"**Project ID:** `{vdc['project_id']}`")
if vdc.get('updated_at'):
st.markdown(f"**Last Updated:** {format_timestamp(vdc['updated_at'])}")
if st.session_state.view_type == 'detail' and st.session_state.selected_resource_type=='virtual_data_center':
render_detail()
else:
render_list()
+83 -3
View File
@@ -1,7 +1,9 @@
import json
import streamlit as st
from streamlit_server.utils.helpers import format_timestamp
def render():
def render_list():
"""
Renders a list of all VM workloads.
"""
@@ -14,7 +16,7 @@ def render():
st.session_state.delete_confirmed = False
# Fetch all VDCs for the dropdown
vdcs = st.session_state.client.get_vdcs()
vdcs = st.session_state.client.get_virtual_data_centers()
vdc_options = {vdc['name']: vdc['id'] for vdc in vdcs} if vdcs else {}
# Add a dropdown to select VDC
@@ -184,4 +186,82 @@ def render():
st.rerun()
else:
st.info("No VirtualMachine workloads found.")
st.info("No VirtualMachine workloads found.")
def render_detail():
"""
Renders the details of a specific VM workload.
"""
VirtualMachine = st.session_state.client.get_virtual_machine(st.session_state.selected_resource['id'])
if not VirtualMachine:
st.error("VM workload not found.")
return
st.title(f"VM Workload: {VirtualMachine['name']}")
if st.button("Back to list view"):
st.session_state.view_type = 'list'
st.rerun()
st.header("VM Workload Details")
col1, col2 = st.columns(2)
with col1:
st.markdown(f"**ID:** `{VirtualMachine['id']}`")
st.markdown(f"**Created:** {format_timestamp(VirtualMachine.get('created_at', 'Unknown'))}")
st.markdown(f"**VDC ID:** {VirtualMachine['vdc_id']}")
st.markdown(f"**Workload Host ID:** {VirtualMachine.get('workload_host_id', 'N/A')}")
with col2:
if VirtualMachine.get('updated_at'):
st.markdown(f"**Last Updated:** {format_timestamp(VirtualMachine['updated_at'])}")
st.markdown(f"**Status:** {VirtualMachine['status']}")
st.markdown(f"**Launch Parameters:** {VirtualMachine.get('launch_params', 'N/A')}")
# Edit VM Workload Form
with st.expander("Edit VM Workload"):
with st.form("edit_vm"):
new_status = st.selectbox("Status", ["running", "stopped", "pending", "failed-deleted", "pending-deleted", "pending-allocation", "failed-allocation", "pending-allocated"], index=["running", "stopped", "pending", "failed-deleted", "pending-deleted", "pending-allocation", "failed-allocation", "pending-allocated"].index(VirtualMachine['status']))
new_launch_params = st.text_input("Launch Parameters", value=VirtualMachine.get('launch_params', ''))
submit = st.form_submit_button("Update VM Workload")
if submit:
result = st.session_state.client.edit_virtual_machine(VirtualMachine['id'], {
"status": new_status,
"launch_params": new_launch_params
})
if result:
st.success("VM workload updated successfully!")
st.session_state.selected_resource = vm
st.session_state.view_type = 'detail'
st.session_state.selected_resource_type = 'VirtualMachine'
st.rerun()
# Delete VM Workload Button
if st.button("Delete VM Workload"):
result = st.session_state.client.delete_virtual_machine(VirtualMachine['id'])
if result:
st.success("VM workload deleted successfully!")
st.session_state.selected_resource = None
st.session_state.view_type = 'list'
st.session_state.selected_resource_type = 'VirtualMachine'
st.rerun()
if st.session_state.view_type == 'detail' and st.session_state.selected_resource_type=='VirtualMachine':
render_detail()
else:
render_list()
+2
View File
@@ -35,3 +35,5 @@ def render():
st.error("Message cannot be empty!")
else:
st.warning("No connected clients found.")
render()