import { useState } from 'react'; import { useAgentDetails } from '@/react/portainer/environments/queries/useAgentDetails'; import { Code } from '@@/Code'; import { CopyButton } from '@@/buttons/CopyButton'; import { Modal } from '@@/modals/Modal'; import { Button } from '@@/buttons'; import { NavTabs } from '@@/NavTabs'; import { NavContainer } from '@@/NavTabs/NavContainer'; import { SwitchField } from '@@/form-components/SwitchField'; export type ConnectivityEnvironment = 'docker' | 'podman' | 'kubernetes'; const ALL_ENVIRONMENTS: ConnectivityEnvironment[] = [ 'docker', 'podman', 'kubernetes', ]; const ENVIRONMENT_LABELS: Record = { docker: 'Docker', podman: 'Podman', kubernetes: 'Kubernetes', }; interface Props { onDismiss: () => void; portainerUrl: string; tunnelServerAddr?: string; /** When provided, show only this environment. When omitted, show tabs for all environments. */ environment?: ConnectivityEnvironment; } export function ConnectivityTestModal({ onDismiss, portainerUrl, tunnelServerAddr, environment, }: Props) { const environments = environment ? [environment] : ALL_ENVIRONMENTS; const [selectedTab, setSelectedTab] = useState( environments[0] ); const [insecurePoll, setInsecurePoll] = useState(true); const agentDetails = useAgentDetails(); const agentVersion = agentDetails?.agentVersion ?? 'latest'; const options = environments.map((env) => { const command = buildCommand( env, portainerUrl, tunnelServerAddr, insecurePoll, agentVersion ); const label = ENVIRONMENT_LABELS[env]; return { id: env, label, children: ( <> {command}
Copy command
), }; }); return (

Run the command in the environment where the Edge Agent will be deployed to verify it can reach the Portainer server.

setSelectedTab(id)} />
); } function buildCommand( environment: ConnectivityEnvironment, portainerUrl: string, tunnelServerAddr?: string, allowInsecurePoll?: boolean, agentVersion = 'latest' ): string { const envVars = [ 'EDGE_CONNECTIVITY_CHECK=1', `EDGE_CONNECTIVITY_CHECK_URL=${portainerUrl}`, `EDGE_INSECURE_POLL=${allowInsecurePoll ? '1' : '0'}`, ...(tunnelServerAddr ? [`EDGE_CONNECTIVITY_CHECK_TUNNEL_ADDR=${tunnelServerAddr}`] : []), ]; const image = `portainer/agent:${agentVersion}`; switch (environment) { case 'kubernetes': return [ `kubectl run portainer-connectivity-check \\`, ` --rm --attach --restart=Never \\`, ` --image=${image} \\`, ...envVars.map((v, i) => i < envVars.length - 1 ? ` --env="${v}" \\` : ` --env="${v}"` ), ].join('\n'); case 'podman': return [ `sudo podman run --rm \\`, ...envVars.map((v) => ` -e ${v} \\`), ` docker.io/${image}`, ].join('\n'); case 'docker': default: return [ `docker run --rm \\`, ...envVars.map((v) => ` -e ${v} \\`), ` ${image}`, ].join('\n'); } }