Port forwarding improvements inc multiple ports per container inc streamlit

This commit is contained in:
2025-05-20 16:53:35 +09:30
parent 41773f64ee
commit bb8bd7e80a
2 changed files with 196 additions and 54 deletions
+103 -14
View File
@@ -26,6 +26,7 @@ def render_list():
# Create Container Workload Form
with st.expander("Create New Container Workload"):
# The form only contains form-specific widgets
with st.form("create_container"):
# Dropdown for VDC selection
selected_vdc_name_create = st.selectbox("VDC", list(vdc_options.keys()))
@@ -40,18 +41,65 @@ def render_list():
index=0
)
# If 'Custom...' selected, let user input their own image
# If 'Custom...' is selected, let the user input their own image
if docker_image == "Custom...":
docker_image = st.text_input("Custom Docker Image", value="")
# Port mapping (single)
st.markdown("**Optional: Port Mapping**")
internal_port = st.number_input("Internal Port", min_value=1, max_value=65535, step=1)
external_port = st.number_input("External Port", min_value=1, max_value=65535, step=1)
# Port mappings (multiple)
st.markdown("**Port Mappings**")
# Initialize port mappings in session state if not exists
if 'port_mappings' not in st.session_state:
st.session_state.port_mappings = [{
'internal': None,
'external': None,
'use_dns': True,
'protocol': 'tcp'
}]
# New: Use DNS (Cloudflare) Checkbox
use_dns = st.checkbox("Use DNS (Cloudflare)", value=True)
# Display each port mapping
for i, mapping in enumerate(st.session_state.port_mappings):
with st.container():
cols = st.columns([2, 2, 2, 1, 1])
with cols[0]:
internal_port = st.number_input(
"Internal Port",
min_value=1,
max_value=65535,
step=1,
value=mapping['internal'],
key=f"internal_{i}"
)
with cols[1]:
external_port = st.number_input(
"External Port",
min_value=1,
max_value=65535,
step=1,
value=mapping['external'],
key=f"external_{i}"
)
with cols[2]:
protocol = st.selectbox(
"Protocol",
["tcp", "udp"],
index=0 if mapping['protocol'] == 'tcp' else 1,
key=f"protocol_{i}"
)
with cols[3]:
use_dns = st.checkbox(
"Use DNS",
value=mapping['use_dns'],
key=f"use_dns_{i}"
)
# with cols[4]:
# # Only show remove button for additional port mappings
# if i > 0:
# if st.button("❌", key=f"remove_{i}"):
# st.session_state.port_mappings.pop(i)
# st.rerun()
# Form submit button for creating the container
submit = st.form_submit_button("Create Container Workload")
if submit and selected_vdc_name_create and container_name:
@@ -63,20 +111,51 @@ def render_list():
"networks": "bridge", # Default network
}
# Only add ports if both fields are non-zero
if internal_port and external_port:
container_payload["ports"] = [{"internal": int(internal_port), "external": int(external_port)}]
# Prepare port mappings from session state
port_mappings = []
for i in range(len(st.session_state.port_mappings)):
internal = st.session_state.get(f"internal_{i}")
external = st.session_state.get(f"external_{i}")
protocol = st.session_state.get(f"protocol_{i}")
use_dns = st.session_state.get(f"use_dns_{i}")
if internal and external: # Only add if both ports are specified
port_mappings.append({
"internal": int(internal),
"external": int(external),
"protocol": protocol,
"use_dns": use_dns
})
if port_mappings:
container_payload["ports"] = port_mappings
payload = {
"vdc": vdc_id,
"use_dns": use_dns,
"containers": [container_payload]
}
result = st.session_state.client.create_container(payload)
if result:
st.success("Container workload created successfully!")
# Clear port mappings after successful creation
st.session_state.port_mappings = [{
'internal': None,
'external': None,
'use_dns': True,
'protocol': 'tcp'
}]
st.rerun()
# The button to add a new port mapping is now placed outside the form
if st.button("➕ Add Another Port Mapping"):
st.session_state.port_mappings.append({
'internal': None,
'external': None,
'use_dns': True,
'protocol': 'tcp'
})
st.rerun()
# List Container Pods
st.subheader("Existing Container Pods")
@@ -128,11 +207,21 @@ def render_list():
st.markdown("🔁 **Port Forwarding:**")
for pf in pod['port_forwardings']:
print (pf)
st.text(f" {pf['protocol'].upper()} → {pf['external_port']} ↦ {pf['internal_port']}")
dns_status = "🌐 DNS" if pf.get('dns_record_id') else "🚫 No DNS"
cols = st.columns([1, 3, 2])
with cols[0]:
st.markdown(f"**{pf['protocol'].upper()}**")
with cols[1]:
st.text(f"{pf['external_port']} → {pf['internal_port']}")
with cols[2]:
st.text(dns_status)
st.page_link(f"http://{pf['ip_address']}:{pf['external_port']}",label=f"http://{pf['ip_address']}:{pf['external_port']}")
if pf.get('dns_hostname'):
st.page_link(f"http://{pf['dns_hostname']}", label=f"http://{pf['dns_hostname']}")
else:
st.page_link(f"http://{pf['ip_address']}:{pf['external_port']}", label=f"http://{pf['ip_address']}:{pf['external_port']}")
st.markdown("---")
else:
st.text("No port forwardings")