From 55cbfcf1f10b961c78ba260f0edaf39171b1d960 Mon Sep 17 00:00:00 2001 From: Fernando Giorgetti Date: Wed, 10 Jun 2026 17:00:44 -0300 Subject: [PATCH] Checkbox to expose a console on Deploy VAN Fixes #117 Signed-off-by: Fernando Giorgetti --- components/console/src/pages/VANs/VANs.jsx | 19 ++++++++- .../management-controller/src/mc-apiserver.js | 7 ++++ .../src/resource-templates.js | 39 ++++++++++++++++++- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/components/console/src/pages/VANs/VANs.jsx b/components/console/src/pages/VANs/VANs.jsx index 79ac6f7..41eb1d6 100644 --- a/components/console/src/pages/VANs/VANs.jsx +++ b/components/console/src/pages/VANs/VANs.jsx @@ -29,6 +29,7 @@ import { NumberInput, IconButton, Link, + Checkbox, } from '@carbon/react'; import { Add, TrashCan, Gui, Deploy } from '@carbon/icons-react'; import OwnerGroupSelect from '../../components/OwnerGroupSelect/OwnerGroupSelect'; @@ -61,6 +62,7 @@ const VANs = () => { const [deploymentTarget, setDeploymentTarget] = useState('standalone'); const [vanAccessPoints, setVanAccessPoints] = useState([]); const [loadingAccessPoints, setLoadingAccessPoints] = useState(false); + const [exposeNetworkObserver, setExposeNetworkObserver] = useState(false); useEffect(() => { fetchBackbones(); @@ -203,6 +205,7 @@ const VANs = () => { setVanToDeploy(van); setDeployModalOpen(true); setDeploymentTarget('standalone'); + setExposeNetworkObserver(false); // Fetch access points of type "van" from the VAN's backbone let backbone = (van.backbone) ? van.backbone : selectedBackbone; @@ -751,12 +754,14 @@ const VANs = () => { setVanToDeploy(null); setDeploymentTarget('standalone'); setVanAccessPoints([]); + setExposeNetworkObserver(false); }} onRequestSubmit={() => { setDeployModalOpen(false); setVanToDeploy(null); setDeploymentTarget('standalone'); setVanAccessPoints([]); + setExposeNetworkObserver(false); }} >

@@ -780,13 +785,23 @@ const VANs = () => { /> ))} - + {loadingAccessPoints && (

Loading access points...

)} + {deploymentTarget !== 'standalone' && ( + setExposeNetworkObserver(e.target.checked)} + style={{ marginTop: '1rem', marginBottom: '1rem' }} + /> + )} + {vanToDeploy && (
Download Configuration
@@ -794,7 +809,7 @@ const VANs = () => { href={ deploymentTarget === 'standalone' ? `/api/v1alpha1/vans/${vanToDeploy.id}/config/nonconnecting` - : `/api/v1alpha1/vans/${vanToDeploy.id}/config/connecting/${deploymentTarget}` + : `/api/v1alpha1/vans/${vanToDeploy.id}/config/connecting/${deploymentTarget}${exposeNetworkObserver ? '?expose-console=true' : ''}` } download={'onboard.yaml'} > diff --git a/components/management-controller/src/mc-apiserver.js b/components/management-controller/src/mc-apiserver.js index 63cd984..366861d 100644 --- a/components/management-controller/src/mc-apiserver.js +++ b/components/management-controller/src/mc-apiserver.js @@ -261,6 +261,7 @@ const fetchBackboneLinksOutgoingKube = async function (req, res) { const getVanConfigConnecting = async function (req, res) { const vid = req.params.vid const apid = req.params.apid + let exposeNetworkObserverConsole = req.query['expose-console'] === 'true'; let returnStatus = 200; const client = await ClientFromPool(); try { @@ -289,6 +290,12 @@ const getVanConfigConnecting = async function (req, res) { resourceTemplates.NetworkLinkCR(ap.hostname, ap.port, van.objectname), resourceTemplates.Secret(secret, van.objectname), ]; + if (exposeNetworkObserverConsole) { + output.push( + resourceTemplates.ConnectorCR('vms-console', 8443, 'vms-console', 'app.kubernetes.io/name=network-observer', 'skupper-network-observer-client'), + resourceTemplates.InterNetworkIngressCR('vms-console', 'vms-console', 'management-link') + ); + } res.status(returnStatus).send(util.ToYaml(output)); } } catch (err) { diff --git a/components/management-controller/src/resource-templates.js b/components/management-controller/src/resource-templates.js index 3139453..a6b159f 100644 --- a/components/management-controller/src/resource-templates.js +++ b/components/management-controller/src/resource-templates.js @@ -116,7 +116,7 @@ export function NetworkLinkCR(host, port, secret) { }, spec : { hostname : host, - port : port, + port : parseInt(port, 10), tlsCredentials : secret, }, }; @@ -239,6 +239,43 @@ const accessPointNetworkAccess = function(apId, data) { return networkAccess; } +export function ConnectorCR(name, port, routingKey, selector, tlsCredentials) { + let connector = { + apiVersion: "skupper.io/v2alpha1", + kind: "Connector", + metadata: { + name: name, + }, + spec: { + port: port, + routingKey: routingKey, + selector: selector, + type: "tcp", + tlsCredentials: tlsCredentials, + } + }; + return connector; +} + +export function InterNetworkIngressCR(name, routingKey, networkLink='', networkAccess='') { + let ingress = { + apiVersion: "skupper.io/v2alpha1", + kind: "InterNetworkIngress", + metadata: { + name: name, + }, + spec: { + routingKey: routingKey, + } + }; + if (!!networkLink) { + ingress.spec.networkLink = networkLink; + } else if (!!networkAccess) { + ingress.spec.networkAccess = networkAccess; + } + return ingress; +} + export function Secret(certificate, profile_name, inject, stateKey) { let secret = { apiVersion: 'v1',