core

package
v0.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 5, 2026 License: Apache-2.0 Imports: 0 Imported by: 0

Documentation

Overview

Package cli contains shared CLI infrastructure used by command packages.

Command-specific behavior belongs in internal/cli/<command>; this package is limited to config, constants, errors, runtime composition, process execution, kubectl clients, terminal output, and test doubles.

Index

Constants

View Source
const (

	// Exported aliases for tests and subpackages (same values as above).
	DefaultRegistryEndpoint    = defaultRegistryEndpoint
	DefaultRegistryIngressHost = defaultRegistryIngressHost
)

Default values

View Source
const (
	// NamespaceMCPRuntime is the namespace for the MCP runtime operator.
	NamespaceMCPRuntime = "github.com/mcp-runtime/mcp-runtime"

	// NamespaceRegistry is the namespace for the container registry.
	NamespaceRegistry = "registry"

	// NamespaceMCPServers is the default namespace for MCP server deployments.
	NamespaceMCPServers = mcpdefaults.MCPServersNamespace

	// PlatformNamespace holds control-plane services.
	PlatformNamespace = platforminventory.PlatformNamespace

	// ObservabilityNamespace holds the event pipeline and telemetry stack.
	ObservabilityNamespace = platforminventory.ObservabilityNamespace

	// LogCollectorNamespace isolates the node log collector and its hostPath access.
	LogCollectorNamespace = mcpdefaults.LogCollectorNamespace
)

This file defines constants used across the CLI, including:

  • Kubernetes namespace names
  • Deployment and resource names
  • Label selectors
  • Default values
View Source
const (
	// OperatorDeploymentName is the name of the operator deployment.
	OperatorDeploymentName = "mcp-runtime-operator-controller-manager"

	// OperatorManagerContainerName is the main manager container in the operator deployment.
	OperatorManagerContainerName = "manager"

	// RegistryDeploymentName is the name of the registry deployment.
	RegistryDeploymentName = "registry"

	// RegistryServiceName is the name of the registry service.
	RegistryServiceName = "registry"

	// RegistryPVCName is the name of the registry persistent volume claim.
	RegistryPVCName = "registry-storage"
)

Deployment and resource names.

View Source
const (
	// MCPServerCRDName is the full name of the MCPServer CRD.
	MCPServerCRDName = "mcpservers.mcpruntime.org"

	// CertManagerCRDName is the full name of the cert-manager Certificate CRD.
	CertManagerCRDName = "certificates.cert-manager.io"
)

CRD identifiers.

View Source
const (
	// LabelApp is the standard app label key.
	LabelApp = "app"

	// LabelManagedBy is the label indicating the managing controller.
	LabelManagedBy = "app.kubernetes.io/managed-by"

	// LabelManagedByValue is the value for the managed-by label.
	LabelManagedByValue = "github.com/mcp-runtime/mcp-runtime"
)

Labels used for resource identification.

View Source
const (
	// SelectorRegistry is the label selector for registry pods.
	SelectorRegistry = "app=registry"

	// SelectorOperator is the label selector for operator pods.
	SelectorOperator = "control-plane=controller-manager"

	// SelectorManagedBy is the label selector for MCP-managed resources.
	SelectorManagedBy = "app.kubernetes.io/managed-by=mcp-runtime"
)

Selector strings for kubectl queries.

Variables

View Source
var (
	// CLI errors.
	ErrImageRequired             = newSentinelError("image is required", errx.CodeCLI, errx.DescCLI)
	ErrInvalidServerName         = newSentinelError("invalid server name", errx.CodeCLI, errx.DescCLI)
	ErrGetWorkingDirectoryFailed = newSentinelError("get working directory", errx.CodeCLI, errx.DescCLI)
	ErrControlCharsNotAllowed    = newSentinelError("value must not contain control characters", errx.CodeCLI, errx.DescCLI)
	ErrFieldRequired             = newSentinelError("field is required", errx.CodeCLI, errx.DescCLI)
	ErrGetHomeDirectoryFailed    = newSentinelError("failed to get home directory", errx.CodeCLI, errx.DescCLI)
	ErrUnknownRegistryMode       = newSentinelError("unknown registry mode", errx.CodeCLI, errx.DescCLI)

	// Auth package errors.
	ErrAuthAPIURLRequired                  = newSentinelError("api URL is required", errx.CodeAuth, errx.DescAuth)
	ErrAuthAPIURLInvalid                   = newSentinelError("api URL must include scheme and host", errx.CodeAuth, errx.DescAuth)
	ErrAuthEmailPasswordRequired           = newSentinelError("email and password are both required for password login", errx.CodeAuth, errx.DescAuth)
	ErrAuthPlatformLoginFailed             = newSentinelError("platform login failed", errx.CodeAuth, errx.DescAuth)
	ErrAuthReadStdinFailed                 = newSentinelError("read stdin", errx.CodeAuth, errx.DescAuth)
	ErrAuthTTYRequired                     = newSentinelError("not a TTY: pass --token, --token-stdin, or run in an interactive terminal", errx.CodeAuth, errx.DescAuth)
	ErrAuthReadTokenFailed                 = newSentinelError("read token", errx.CodeAuth, errx.DescAuth)
	ErrAuthTokenRequired                   = newSentinelError("token is required", errx.CodeAuth, errx.DescAuth)
	ErrAuthTokenVerificationFailed         = newSentinelError("API token could not be verified", errx.CodeAuth, errx.DescAuth)
	ErrAuthLoginHTTPStatus                 = newSentinelError("login HTTP status failed", errx.CodeAuth, errx.DescAuth)
	ErrAuthLoginResponseMissingAccessToken = newSentinelError("login response did not include access_token", errx.CodeAuth, errx.DescAuth)
	ErrAuthServerRejectedToken             = newSentinelError("server rejected the token", errx.CodeAuth, errx.DescAuth)
	ErrAuthAPIURLMayBeWrong                = newSentinelError("API URL may be wrong", errx.CodeAuth, errx.DescAuth)
	ErrAuthVerifyRequestFailed             = newSentinelError("verify request failed", errx.CodeAuth, errx.DescAuth)
	ErrAuthFileDescriptorOutOfRange        = newSentinelError("file descriptor out of range", errx.CodeAuth, errx.DescAuth)

	// Pipeline errors.
	ErrLoadMetadataFailed      = newSentinelError("failed to load metadata", errx.CodePipeline, errx.DescPipeline)
	ErrNoServersInMetadata     = newSentinelError("no servers found in metadata", errx.CodePipeline, errx.DescPipeline)
	ErrGenerateCRDsFailed      = newSentinelError("failed to generate CRDs", errx.CodePipeline, errx.DescPipeline)
	ErrListManifestFilesFailed = newSentinelError("failed to list manifest files", errx.CodePipeline, errx.DescPipeline)
	ErrNoManifestFilesFound    = newSentinelError("no manifest files found", errx.CodePipeline, errx.DescPipeline)
	ErrApplyManifestFailed     = newSentinelError("failed to apply manifest", errx.CodePipeline, errx.DescPipeline)

	// Operator errors.
	ErrOperatorNotFound = newSentinelError("operator not found", errx.CodeOperator, errx.DescOperator)
	ErrOperatorNotReady = newSentinelError("operator not ready", errx.CodeOperator, errx.DescOperator)

	// Setup errors.
	ErrClusterInitFailed                   = newSentinelError("failed to initialize cluster", errx.CodeSetup, errx.DescSetup)
	ErrClusterConfigFailed                 = newSentinelError("cluster configuration failed", errx.CodeSetup, errx.DescSetup)
	ErrTLSSetupFailed                      = newSentinelError("TLS setup failed", errx.CodeSetup, errx.DescSetup)
	ErrDeployRegistryFailed                = newSentinelError("failed to deploy registry", errx.CodeSetup, errx.DescSetup)
	ErrOperatorImageBuildFailed            = newSentinelError("operator image build failed", errx.CodeSetup, errx.DescSetup)
	ErrGatewayProxyImageBuildFailed        = newSentinelError("gateway proxy image build failed", errx.CodeSetup, errx.DescSetup)
	ErrEnsureRegistryNamespaceFailed       = newSentinelError("failed to ensure registry namespace", errx.CodeSetup, errx.DescSetup)
	ErrPushOperatorImageInternalFailed     = newSentinelError("failed to push operator image to internal registry", errx.CodeSetup, errx.DescSetup)
	ErrPushGatewayProxyImageInternalFailed = newSentinelError("failed to push gateway proxy image to internal registry", errx.CodeSetup, errx.DescSetup)
	ErrOperatorDeploymentFailed            = newSentinelError("operator deployment failed", errx.CodeSetup, errx.DescSetup)
	ErrConfigureExternalRegistryEnvFailed  = newSentinelError("failed to configure external registry env on operator", errx.CodeSetup, errx.DescSetup)
	ErrRestartOperatorDeploymentFailed     = newSentinelError("failed to restart operator deployment after registry env update", errx.CodeSetup, errx.DescSetup)
	ErrCRDCheckFailed                      = newSentinelError("CRD check failed", errx.CodeSetup, errx.DescSetup)
	ErrRenderSecretManifestFailed          = newSentinelError("render secret manifest", errx.CodeSetup, errx.DescSetup)
	ErrApplySecretManifestFailed           = newSentinelError("apply secret manifest", errx.CodeSetup, errx.DescSetup)
	ErrMarshalDockerConfigFailed           = newSentinelError("marshal docker config", errx.CodeSetup, errx.DescSetup)
	ErrApplyImagePullSecretFailed          = newSentinelError("apply imagePullSecret", errx.CodeSetup, errx.DescSetup)
	ErrPushImageInClusterFailed            = newSentinelError("failed to push image in-cluster", errx.CodeSetup, errx.DescSetup)
	ErrSetupStepFailed                     = newSentinelError("setup step failed", errx.CodeSetup, errx.DescSetup)
	ErrApplyCRDFailed                      = newSentinelError("failed to apply CRD", errx.CodeSetup, errx.DescSetup)
	ErrEnsureOperatorNamespaceFailed       = newSentinelError("failed to ensure operator namespace", errx.CodeSetup, errx.DescSetup)
	ErrApplyRBACFailed                     = newSentinelError("failed to apply RBAC", errx.CodeSetup, errx.DescSetup)
	ErrReadManagerYAMLFailed               = newSentinelError("failed to read manager.yaml", errx.CodeSetup, errx.DescSetup)
	ErrReadIngressManifestFailed           = newSentinelError("failed to read ingress manifest", errx.CodeSetup, errx.DescSetup)
	ErrParseManagerYAMLFailed              = newSentinelError("failed to parse manager.yaml", errx.CodeSetup, errx.DescSetup)
	ErrSetOperatorImageFailed              = newSentinelError("failed to set operator image", errx.CodeSetup, errx.DescSetup)
	ErrMutateManagerYAMLFailed             = newSentinelError("failed to mutate manager.yaml", errx.CodeSetup, errx.DescSetup)
	ErrRenderManagerYAMLFailed             = newSentinelError("failed to render mutated manager.yaml", errx.CodeSetup, errx.DescSetup)
	ErrCreateTempFileFailed                = newSentinelError("failed to create temp file", errx.CodeSetup, errx.DescSetup)
	ErrCloseTempFileFailed                 = newSentinelError("failed to close temp file", errx.CodeSetup, errx.DescSetup)
	ErrWriteTempFileFailed                 = newSentinelError("failed to write temp file", errx.CodeSetup, errx.DescSetup)
	ErrApplyManagerDeploymentFailed        = newSentinelError("failed to apply manager deployment", errx.CodeSetup, errx.DescSetup)
	ErrClusterIssuerApplyFailed            = newSentinelError("failed to apply ClusterIssuer", errx.CodeSetup, errx.DescSetup)
	ErrCreateRegistryNamespaceFailed       = newSentinelError("failed to create registry namespace", errx.CodeSetup, errx.DescSetup)
	ErrApplyCertificateFailed              = newSentinelError("failed to apply Certificate", errx.CodeSetup, errx.DescSetup)

	// Setup platform package errors.
	ErrSetupImagePlatformNoNodeArchitectures       = newSentinelError("could not resolve setup image platform: no Kubernetes node architectures were reported", errx.CodeSetup, errx.DescSetup)
	ErrSetupImagePlatformMixedNodeArchitectures    = newSentinelError("mixed Kubernetes node architectures detected", errx.CodeSetup, errx.DescSetup)
	ErrSetupImagePlatformMismatch                  = newSentinelError("MCP_IMAGE_PLATFORM does not match Kubernetes node architecture", errx.CodeSetup, errx.DescSetup)
	ErrSetupImagePlatformInvalid                   = newSentinelError("invalid MCP_IMAGE_PLATFORM", errx.CodeSetup, errx.DescSetup)
	ErrSetupImagePlatformUnsupported               = newSentinelError("unsupported MCP_IMAGE_PLATFORM", errx.CodeSetup, errx.DescSetup)
	ErrSetupImagePlatformKubectlNil                = newSentinelError("could not resolve setup image platform: kubectl runner is nil", errx.CodeSetup, errx.DescSetup)
	ErrSetupInspectNodeArchitecturesFailed         = newSentinelError("could not inspect Kubernetes node architectures", errx.CodeSetup, errx.DescSetup)
	ErrSetupInvalidStorageMode                     = newSentinelError("invalid storage mode", errx.CodeSetup, errx.DescSetup)
	ErrSetupInvalidPlatformMode                    = newSentinelError("invalid platform mode", errx.CodeSetup, errx.DescSetup)
	ErrSetupInvalidRegistryMode                    = newSentinelError("invalid registry mode", errx.CodeSetup, errx.DescSetup)
	ErrSetupSetRuntimeTestModeFailed               = newSentinelError("set MCP_RUNTIME_TEST_MODE", errx.CodeSetup, errx.DescSetup)
	ErrSetupUnsetRuntimeTestModeFailed             = newSentinelError("unset MCP_RUNTIME_TEST_MODE", errx.CodeSetup, errx.DescSetup)
	ErrSetupSetPlatformModeFailed                  = newSentinelError("set MCP_PLATFORM_MODE", errx.CodeSetup, errx.DescSetup)
	ErrSetupListTraefikDeploymentsFailed           = newSentinelError("list traefik deployments", errx.CodeSetup, errx.DescSetup)
	ErrSetupMarshalTraefikDeploymentPatchFailed    = newSentinelError("marshal traefik deployment patch", errx.CodeSetup, errx.DescSetup)
	ErrSetupReadTraefikDeploymentFailed            = newSentinelError("read traefik deployment", errx.CodeSetup, errx.DescSetup)
	ErrSetupDecodeTraefikDeploymentFailed          = newSentinelError("decode traefik deployment", errx.CodeSetup, errx.DescSetup)
	ErrSetupDeploymentReadinessDeadlineExceeded    = newSentinelError("deployment readiness deadline exceeded", errx.CodeSetup, errx.DescSetup)
	ErrSetupTLSKubectlRunnerNil                    = newSentinelError("kubectl runner is nil", errx.CodeSetup, errx.DescSetup)
	ErrSetupInspectClusterIssuerFailed             = newSentinelError("inspect ClusterIssuer", errx.CodeSetup, errx.DescSetup)
	ErrSetupTLSCertificateSANsEmpty                = newSentinelError("no DNS names or IP addresses resolved for the Certificate", errx.CodeSetup, errx.DescSetup)
	ErrSetupDeleteClickHouseInitJobFailed          = newSentinelError("delete existing clickhouse init job", errx.CodeSetup, errx.DescSetup)
	ErrSetupAnalyticsRolloutFailed                 = newSentinelError("analytics components failed to roll out", errx.CodeSetup, errx.DescSetup)
	ErrSetupRenderManifestFailed                   = newSentinelError("render manifest", errx.CodeSetup, errx.DescSetup)
	ErrSetupApplyPlatformUIIngressFailed           = newSentinelError("apply platform UI ingress", errx.CodeSetup, errx.DescSetup)
	ErrSetupRemovePathBasedSentinelIngressesFailed = newSentinelError("remove path-based sentinel ingresses for public platform host", errx.CodeSetup, errx.DescSetup)
	ErrSetupDecodeAnalyticsConfigManifestFailed    = newSentinelError("decode analytics config manifest", errx.CodeSetup, errx.DescSetup)
	ErrSetupEncodeAnalyticsConfigManifestFailed    = newSentinelError("encode analytics config manifest", errx.CodeSetup, errx.DescSetup)
	ErrSetupReadConfigMapFailed                    = newSentinelError("read configmap", errx.CodeSetup, errx.DescSetup)
	ErrSetupDecodeConfigMapFailed                  = newSentinelError("decode configmap", errx.CodeSetup, errx.DescSetup)
	ErrSetupReadSecretKeyFailed                    = newSentinelError("read secret key", errx.CodeSetup, errx.DescSetup)
	ErrSetupDecodeSecretKeyFailed                  = newSentinelError("decode secret key", errx.CodeSetup, errx.DescSetup)

	// Platform update errors.
	ErrUpdateTargetRequired      = newSentinelError("update target required", errx.CodeSetup, errx.DescSetup)
	ErrUpdateManifestInvalid     = newSentinelError("release manifest invalid", errx.CodeSetup, errx.DescSetup)
	ErrUpdateTargetMismatch      = newSentinelError("release manifest version does not match --to", errx.CodeSetup, errx.DescSetup)
	ErrUpdateInvalidFlag         = newSentinelError("invalid update flag", errx.CodeSetup, errx.DescSetup)
	ErrUpdateKubeClientFailed    = newSentinelError("create Kubernetes client for update", errx.CodeSetup, errx.DescSetup)
	ErrUpdateNotInstalled        = newSentinelError("cluster is not an MCP Runtime install", errx.CodeSetup, errx.DescSetup)
	ErrUpdateInventoryFailed     = newSentinelError("read installed platform inventory", errx.CodeSetup, errx.DescSetup)
	ErrUpdateCRDChange           = newSentinelError("release changes CRDs", errx.CodeSetup, errx.DescSetup)
	ErrUpdateBlocked             = newSentinelError("update plan has blocked components", errx.CodeSetup, errx.DescSetup)
	ErrUpdateConfirmationMissing = newSentinelError("update confirmation required", errx.CodeSetup, errx.DescSetup)
	ErrUpdateAborted             = newSentinelError("update aborted", errx.CodeSetup, errx.DescSetup)
	ErrUpdateRolloutFailed       = newSentinelError("platform update rollout failed", errx.CodeSetup, errx.DescSetup)
	ErrUpdateBuildFailed         = newSentinelError("platform update image build failed", errx.CodeSetup, errx.DescSetup)

	// Cert errors.
	ErrCertManagerNotInstalled     = newSentinelError("cert-manager not installed", errx.CodeCert, errx.DescCert)
	ErrCertManagerInstallFailed    = newSentinelError("cert-manager install failed", errx.CodeCert, errx.DescCert)
	ErrCASecretNotFound            = newSentinelError("CA secret not found", errx.CodeCert, errx.DescCert)
	ErrCASecretInvalid             = newSentinelError("CA secret invalid", errx.CodeCert, errx.DescCert)
	ErrCAExpired                   = newSentinelError("CA certificate expired", errx.CodeCert, errx.DescCert)
	ErrCANearExpiry                = newSentinelError("CA certificate near expiry", errx.CodeCert, errx.DescCert)
	ErrCertificateNotReady         = newSentinelError("certificate not ready", errx.CodeCert, errx.DescCert)
	ErrClusterIssuerNotFound       = newSentinelError("ClusterIssuer not found", errx.CodeCert, errx.DescCert)
	ErrRegistryCertificateNotFound = newSentinelError("registry Certificate not found", errx.CodeCert, errx.DescCert)

	// Certmanager package errors.
	ErrCertEncodeGeneratedCAFailed         = newSentinelError("failed to encode generated internal CA", errx.CodeCert, errx.DescCert)
	ErrCertLookupRegistryIngressFailed     = newSentinelError("failed to look up registry ingress", errx.CodeCert, errx.DescCert)
	ErrCertRemoveRegistryIngressAnnotation = newSentinelError("failed to remove cert-manager.io/cluster-issuer from registry ingress", errx.CodeCert, errx.DescCert)
	ErrCertRegistryTLSSecretConflict       = newSentinelError("registry TLS secret is already referenced by Certificate(s)", errx.CodeCert, errx.DescCert)
	ErrCertListCertificatesFailed          = newSentinelError("failed to list cert-manager Certificates", errx.CodeCert, errx.DescCert)
	ErrCertParseCertificatesFailed         = newSentinelError("failed to parse cert-manager Certificates", errx.CodeCert, errx.DescCert)
	ErrCertACMEPublicDNSNameRequired       = newSentinelError("ACME public CA requires a public DNS name", errx.CodeCert, errx.DescCert)
	ErrCertACMEPublicDNSNameInvalid        = newSentinelError("ACME public CA requires a public DNS name; invalid host", errx.CodeCert, errx.DescCert)
	ErrCertACMEIngressManifestInvalid      = newSentinelError("http-01 ingress manifest is not valid for Let's Encrypt", errx.CodeCert, errx.DescCert)
	ErrCertTraefikNotReady                 = newSentinelError("traefik not ready", errx.CodeCert, errx.DescCert)
	ErrCertACMEEmailRequired               = newSentinelError("ACME email is required", errx.CodeCert, errx.DescCert)
	ErrCertCertificateSANsEmpty            = newSentinelError("TLS has no DNS names or IP addresses to request", errx.CodeCert, errx.DescCert)

	// Cluster errors.
	ErrCRDNotInstalled                = newSentinelError("MCPServer CRD not installed", errx.CodeCluster, errx.DescCluster)
	ErrClusterNotAccessible           = newSentinelError("cluster not accessible", errx.CodeCluster, errx.DescCluster)
	ErrNamespaceNotFound              = newSentinelError("namespace not found", errx.CodeCluster, errx.DescCluster)
	ErrDeploymentTimeout              = newSentinelError("deployment timed out waiting for readiness", errx.CodeCluster, errx.DescCluster)
	ErrInstallCRDFailed               = newSentinelError("failed to install CRD", errx.CodeCluster, errx.DescCluster)
	ErrEnsureRuntimeNamespaceFailed   = newSentinelError("failed to ensure mcp-runtime namespace", errx.CodeCluster, errx.DescCluster)
	ErrEnsureServersNamespaceFailed   = newSentinelError("failed to ensure mcp-servers namespace", errx.CodeCluster, errx.DescCluster)
	ErrKubeconfigNotReadable          = newSentinelError("kubeconfig not found or not readable", errx.CodeCluster, errx.DescCluster)
	ErrSetKubeconfigFailed            = newSentinelError("failed to set KUBECONFIG", errx.CodeCluster, errx.DescCluster)
	ErrSetContextFailed               = newSentinelError("failed to set context", errx.CodeCluster, errx.DescCluster)
	ErrAKSKubeconfigNotImplemented    = newSentinelError("AKS kubeconfig not yet implemented", errx.CodeCluster, errx.DescCluster)
	ErrGKEKubeconfigNotImplemented    = newSentinelError("GKE kubeconfig not yet implemented", errx.CodeCluster, errx.DescCluster)
	ErrUnsupportedProvider            = newSentinelError("unsupported provider", errx.CodeCluster, errx.DescCluster)
	ErrInvalidClusterName             = newSentinelError("invalid cluster name", errx.CodeCluster, errx.DescCluster)
	ErrInvalidNodeCount               = newSentinelError("invalid node count", errx.CodeCluster, errx.DescCluster)
	ErrUnsupportedIngressController   = newSentinelError("unsupported ingress controller", errx.CodeCluster, errx.DescCluster)
	ErrInstallIngressControllerFailed = newSentinelError("failed to install ingress controller", errx.CodeCluster, errx.DescCluster)
	ErrCreateKindConfigFailed         = newSentinelError("failed to create temp kind config", errx.CodeCluster, errx.DescCluster)
	ErrCloseKindConfigFailed          = newSentinelError("failed to close kind config", errx.CodeCluster, errx.DescCluster)
	ErrWriteKindConfigFailed          = newSentinelError("failed to write kind config", errx.CodeCluster, errx.DescCluster)
	ErrCreateKindClusterFailed        = newSentinelError("failed to create kind cluster", errx.CodeCluster, errx.DescCluster)
	ErrDockerDaemonNotReachable       = newSentinelError("docker daemon not reachable", errx.CodeCluster, errx.DescCluster)
	ErrKindClusterAlreadyExists       = newSentinelError("kind cluster already exists", errx.CodeCluster, errx.DescCluster)
	ErrGKEProvisioningNotImplemented  = newSentinelError("GKE provisioning not yet implemented", errx.CodeCluster, errx.DescCluster)
	ErrProvisionEKSFailed             = newSentinelError("failed to provision EKS cluster", errx.CodeCluster, errx.DescCluster)
	ErrAKSProvisioningNotImplemented  = newSentinelError("AKS provisioning not yet implemented", errx.CodeCluster, errx.DescCluster)

	// Cluster doctor package errors.
	ErrDoctorResourceNotFoundBeforeTimeout = newSentinelError("resource not found before timeout", errx.CodeCluster, errx.DescCluster)
	ErrDoctorDeploymentRolloutFailed       = newSentinelError("deployment rollout failed", errx.CodeCluster, errx.DescCluster)
	ErrDoctorPodsNotScheduledBeforeTimeout = newSentinelError("no scheduled pod found before timeout", errx.CodeCluster, errx.DescCluster)
	ErrDoctorDecodeBase64Failed            = newSentinelError("decode base64 value", errx.CodeCluster, errx.DescCluster)
	ErrDoctorImagePullStatusFailed         = newSentinelError("pod image pull status failed", errx.CodeCluster, errx.DescCluster)
	ErrDoctorPodPhaseFailed                = newSentinelError("pod phase Failed", errx.CodeCluster, errx.DescCluster)
	ErrDoctorKubectlError                  = newSentinelError("kubectl error", errx.CodeCluster, errx.DescCluster)
	ErrDoctorTraefikServiceNotFound        = newSentinelError("traefik service not found", errx.CodeCluster, errx.DescCluster)
	ErrDoctorDeploymentNotFound            = newSentinelError("deployment not found", errx.CodeCluster, errx.DescCluster)
	ErrDoctorUnexpectedReplicaStatus       = newSentinelError("unexpected replica status", errx.CodeCluster, errx.DescCluster)

	// Registry errors.
	ErrRegistryNotReady             = newSentinelError("registry not ready", errx.CodeRegistry, errx.DescRegistry)
	ErrRegistryNotFound             = newSentinelError("registry not found", errx.CodeRegistry, errx.DescRegistry)
	ErrBuildOperatorImageFailed     = newSentinelError("failed to build operator image", errx.CodeRegistry, errx.DescRegistry)
	ErrPushOperatorImageFailed      = newSentinelError("failed to push operator image", errx.CodeRegistry, errx.DescRegistry)
	ErrBuildGatewayProxyImageFailed = newSentinelError("failed to build gateway proxy image", errx.CodeRegistry, errx.DescRegistry)
	ErrPushGatewayProxyImageFailed  = newSentinelError("failed to push gateway proxy image", errx.CodeRegistry, errx.DescRegistry)
	ErrUnsupportedRegistryType      = newSentinelError("unsupported registry type", errx.CodeRegistry, errx.DescRegistry)
	ErrEnsureNamespaceFailed        = newSentinelError("failed to ensure namespace", errx.CodeRegistry, errx.DescRegistry)
	ErrReadRegistryStorageFailed    = newSentinelError("failed to read current registry storage size", errx.CodeRegistry, errx.DescRegistry)
	ErrUpdateRegistryStorageFailed  = newSentinelError("failed to update registry storage size", errx.CodeRegistry, errx.DescRegistry)
	ErrRegistryLoginFailed          = newSentinelError("failed to login to registry", errx.CodeRegistry, errx.DescRegistry)
	ErrTagImageFailed               = newSentinelError("failed to tag image", errx.CodeRegistry, errx.DescRegistry)
	ErrPushImageFailed              = newSentinelError("failed to push image", errx.CodeRegistry, errx.DescRegistry)
	ErrHelperNamespaceNotFound      = newSentinelError("helper namespace not found", errx.CodeRegistry, errx.DescRegistry)
	ErrSaveImageFailed              = newSentinelError("failed to save image", errx.CodeRegistry, errx.DescRegistry)
	ErrStartHelperPodFailed         = newSentinelError("failed to start helper pod", errx.CodeRegistry, errx.DescRegistry)
	ErrHelperPodNotReady            = newSentinelError("helper pod not ready", errx.CodeRegistry, errx.DescRegistry)
	ErrCopyImageToHelperFailed      = newSentinelError("failed to copy image tar to helper pod", errx.CodeRegistry, errx.DescRegistry)
	ErrPushImageFromHelperFailed    = newSentinelError("failed to push image from helper pod", errx.CodeRegistry, errx.DescRegistry)

	// Config errors.
	ErrRegistryURLRequired           = newSentinelError("registry url is required", errx.CodeConfig, errx.DescConfig)
	ErrRegistryURLMissingInConfig    = newSentinelError("registry url missing in config", errx.CodeConfig, errx.DescConfig)
	ErrSaveRegistryConfigFailed      = newSentinelError("failed to save registry config", errx.CodeConfig, errx.DescConfig)
	ErrReadRegistryConfigFailed      = newSentinelError("failed to read registry config", errx.CodeConfig, errx.DescConfig)
	ErrUnmarshalRegistryConfigFailed = newSentinelError("failed to unmarshal registry config", errx.CodeConfig, errx.DescConfig)

	// Build errors.
	ErrBuildImageFailed         = newSentinelError("failed to build image", errx.CodeBuild, errx.DescBuild)
	ErrMetadataFileNotFound     = newSentinelError("metadata file not found", errx.CodeBuild, errx.DescBuild)
	ErrServerNotFoundInMetadata = newSentinelError("server not found in metadata", errx.CodeBuild, errx.DescBuild)
	ErrMarshalMetadataFailed    = newSentinelError("failed to marshal metadata", errx.CodeBuild, errx.DescBuild)
	ErrWriteMetadataFailed      = newSentinelError("failed to write metadata", errx.CodeBuild, errx.DescBuild)

	// Server errors.
	ErrMarshalManifestFailed = newSentinelError("failed to marshal manifest", errx.CodeServer, errx.DescServer)
	ErrWriteManifestFailed   = newSentinelError("failed to write manifest", errx.CodeServer, errx.DescServer)
	ErrInvalidFilePath       = newSentinelError("invalid file path", errx.CodeServer, errx.DescServer)
	ErrFileNotAccessible     = newSentinelError("cannot access file", errx.CodeServer, errx.DescServer)
	ErrFileIsDirectory       = newSentinelError("path is a directory, not a file", errx.CodeServer, errx.DescServer)
	ErrGetMCPServerFailed    = newSentinelError("kubectl get mcpserver failed", errx.CodeServer, errx.DescServer)
	ErrListServersFailed     = newSentinelError("failed to list servers", errx.CodeServer, errx.DescServer)
	ErrCreateServerFailed    = newSentinelError("failed to create server", errx.CodeServer, errx.DescServer)
	ErrDeleteServerFailed    = newSentinelError("failed to delete server", errx.CodeServer, errx.DescServer)
	ErrViewServerLogsFailed  = newSentinelError("failed to view server logs", errx.CodeServer, errx.DescServer)
)

Sentinel errors for CLI operations. Errors are defined and registered in one step using newSentinelError to eliminate redundancy.

View Source
var DefaultCLIConfig = LoadCLIConfig()

DefaultCLIConfig is the global CLI configuration loaded at startup.

View Source
var DefaultPrinter = &Printer{}

DefaultPrinter is the default printer instance used by package-level functions.

View Source
var ValidK8sName = regexp.MustCompile(`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`)

ValidK8sName matches Kubernetes resource name requirements (RFC 1123 subdomain).

Functions

func ComponentNamespace

func ComponentNamespace(key string) string

ComponentNamespace returns the install namespace for a catalog component.

func Cyan

func Cyan(msg string) string

Cyan returns cyan text.

func Error

func Error(msg string)

Error prints an error message.

func GetAnalyticsIngestURLOverride

func GetAnalyticsIngestURLOverride() string

GetAnalyticsIngestURLOverride returns the analytics ingest URL override, empty if not set.

func GetCertTimeout

func GetCertTimeout() time.Duration

GetCertTimeout returns the certificate issuance timeout.

func GetClusterName

func GetClusterName() string

GetClusterName returns the cluster label attached to analytics/audit events.

func GetDefaultServerPort

func GetDefaultServerPort() int

GetDefaultServerPort returns the default MCP server port.

func GetDeploymentTimeout

func GetDeploymentTimeout() time.Duration

GetDeploymentTimeout returns the deployment wait timeout.

func GetGatewayOTLPEndpointOverride

func GetGatewayOTLPEndpointOverride() string

GetGatewayOTLPEndpointOverride returns the gateway OTLP endpoint override, empty if not set.

func GetGatewayProxyImageOverride

func GetGatewayProxyImageOverride() string

GetGatewayProxyImageOverride returns the gateway proxy image override, empty if not set.

func GetHelperPodTimeout

func GetHelperPodTimeout() time.Duration

GetHelperPodTimeout returns the helper pod ready timeout (e.g. registry pusher pod).

func GetMcpIngressHost

func GetMcpIngressHost() string

GetMcpIngressHost returns the public MCP / gateway host (mcp.<domain> when MCP_PLATFORM_DOMAIN is set), or empty if not configured.

func GetOperatorImageOverride

func GetOperatorImageOverride() string

GetOperatorImageOverride returns the operator image override, empty if not set.

func GetPlatformIngressHost

func GetPlatformIngressHost() string

GetPlatformIngressHost returns the public dashboard UI host (platform.<domain> when MCP_PLATFORM_DOMAIN is set), or empty if not configured. When empty the dev path-based routing on the gateway ingress is used.

func GetProvidedTLSSecrets

func GetProvidedTLSSecrets() bool

GetProvidedTLSSecrets reports whether setup references operator-provided TLS Secrets rather than cert-manager-issued Certificates.

func GetRegistryClusterIssuerName

func GetRegistryClusterIssuerName() string

GetRegistryClusterIssuerName returns the setup-selected cert-manager ClusterIssuer name (empty if unset).

func GetRegistryEndpoint

func GetRegistryEndpoint() string

GetRegistryEndpoint returns the configured registry endpoint for image refs and pushes.

func GetRegistryIngressHost

func GetRegistryIngressHost() string

GetRegistryIngressHost returns the configured registry ingress host.

func GetRegistryPort

func GetRegistryPort() int

GetRegistryPort returns the registry port.

func GetSkopeoImage

func GetSkopeoImage() string

GetSkopeoImage returns the skopeo image for in-cluster operations.

func Green

func Green(msg string) string

Green returns green text.

func Header(title string)

Header prints a header banner.

func Info

func Info(msg string)

Info prints an info message.

func IsDebugMode

func IsDebugMode() bool

IsDebugMode returns whether debug mode is enabled.

func LogStructuredError

func LogStructuredError(logger *zap.Logger, err error, msg string)

func NewSetupStepFailedError

func NewSetupStepFailedError() error

func NewWithSentinel

func NewWithSentinel(base error, msg string) error

func Red

func Red(msg string) string

Red returns red text.

func ResolveEmailAlias

func ResolveEmailAlias(email, username string) (string, error)

ResolveEmailAlias returns the single account email represented by --email and the deprecated/alias --username flag.

func Section

func Section(title string)

Section prints a section header.

func SetDebugMode

func SetDebugMode(enabled bool)

SetDebugMode sets the global debug mode flag. When enabled, logStructuredError will output structured error logs to terminal.

func SpinnerStart

func SpinnerStart(msg string) func(success bool, finalMsg string)

SpinnerStart starts a spinner.

func Step

func Step(title string)

Step prints a step header.

func Success

func Success(msg string)

Success prints a success message.

func SwapDefaultKubectlClient

func SwapDefaultKubectlClient(c *KubectlClient) (restore func())

SwapDefaultKubectlClient replaces the shared kubectl client (tests only).

func SwapExecExecutor

func SwapExecExecutor(e Executor) (restore func())

SwapExecExecutor replaces the global process executor (tests only).

func Table

func Table(data [][]string)

Table prints a table.

func TableBoxed

func TableBoxed(data [][]string)

TableBoxed prints a boxed table.

func ValidateK8sNameAndNamespace

func ValidateK8sNameAndNamespace(nameLabel string, nameSentinel error, name, namespace string) (string, string, error)

ValidateK8sNameAndNamespace validates a name+namespace pair against RFC-1123 subdomain rules plus ValidateManifestField. nameLabel customizes the invalid-name error message ("server name", "resource name"); nameSentinel (may be nil) selects the sentinel error category.

func ValidateManifestField

func ValidateManifestField(field, value string) (string, error)

ValidateManifestField rejects control characters, requires non-empty after trimming, and returns the trimmed value.

func Warn

func Warn(msg string)

Warn prints a warning message.

func WrapWithSentinel

func WrapWithSentinel(base, cause error, msg string) error

func WrapWithSentinelAndContext

func WrapWithSentinelAndContext(base, cause error, msg string, context map[string]any) error

func Yellow

func Yellow(msg string) string

Yellow returns yellow text.

Types

type CLIConfig

type CLIConfig struct {
	// Timeouts
	DeploymentTimeout time.Duration
	CertTimeout       time.Duration
	HelperPodTimeout  time.Duration

	// Registry settings
	RegistryPort int
	// KubernetesAPIPort is the host-facing Kubernetes API port used by the
	// runtime API NetworkPolicy on distributions such as k3s.
	KubernetesAPIPort   int
	RegistryEndpoint    string
	RegistryIngressHost string
	// McpIngressHost is the public gateway / MCP host (e.g. mcp.mcpruntime.com), from
	// MCP_MCP_INGRESS_HOST or mcp.<MCP_PLATFORM_DOMAIN>. Empty if unset.
	McpIngressHost string
	// PlatformIngressHost is the public dashboard UI host (e.g. platform.mcpruntime.com), from
	// MCP_PLATFORM_INGRESS_HOST or platform.<MCP_PLATFORM_DOMAIN>. Empty falls back to path-based dev routing.
	PlatformIngressHost string
	// RegistryClusterIssuerName is the cert-manager ClusterIssuer selected by
	// setup --with-tls for TLS-rendered resources (e.g. platform UI ingress).
	// The registry Secret itself is owned by an explicit registry-cert Certificate.
	RegistryClusterIssuerName string
	// ProvidedTLSSecrets selects operator-managed TLS Secrets in place of
	// cert-manager-issued Certificates.
	ProvidedTLSSecrets   bool
	SkopeoImage          string
	OperatorImage        string // Override for operator image
	GatewayProxyImage    string // Optional default image for the MCP gateway sidecar
	ImagePlatform        string // Optional Docker image platform for setup-built images, e.g. linux/amd64
	GatewayOTLPEndpoint  string // Optional OTLP/HTTP endpoint for MCP gateway sidecar tracing
	AnalyticsIngestURL   string // Optional analytics ingest URL override for the MCP gateway sidecar
	IngressReadinessMode string // Optional operator ingress readiness mode: strict or permissive
	ClusterName          string // Optional cluster label attached to analytics/audit events

	// Server defaults
	DefaultServerPort int

	// External/Provisioned registry credentials
	ProvisionedRegistryURL      string
	ProvisionedRegistryUsername string
	ProvisionedRegistryPassword string
}

CLIConfig holds all CLI configuration loaded from environment variables. Use LoadCLIConfig() to create an instance with values from the environment.

func LoadCLIConfig

func LoadCLIConfig() *CLIConfig

LoadCLIConfig loads CLI configuration from environment variables.

type Command

type Command interface {
	Output() ([]byte, error)
	CombinedOutput() ([]byte, error)
	Run() error
	SetStdout(w io.Writer)
	SetStderr(w io.Writer)
	SetStdin(r io.Reader)
}

Command represents a command that can be executed.

func ExecCommandWithValidators

func ExecCommandWithValidators(name string, args []string, validators ...ExecValidator) (Command, error)

ExecCommandWithValidators runs the named binary with args after validators pass.

type ExecSpec

type ExecSpec struct {
	Name string
	Args []string
}

type ExecValidator

type ExecValidator func(ExecSpec) error

func AllowlistBins

func AllowlistBins(allowed ...string) ExecValidator

func NoControlChars

func NoControlChars() ExecValidator

func NoShellMeta

func NoShellMeta() ExecValidator

func PathUnder

func PathUnder(root string) ExecValidator

type Executor

type Executor interface {
	Command(name string, args []string, validators ...ExecValidator) (Command, error)
}

Executor creates commands for execution.

func DefaultExecutor

func DefaultExecutor() Executor

DefaultExecutor returns the shared process executor used by CLI commands.

type KubectlClient

type KubectlClient struct {
	// contains filtered or unexported fields
}

KubectlClient wraps kubectl command execution with validation.

func DefaultKubectlClient

func DefaultKubectlClient() *KubectlClient

DefaultKubectlClient returns the shared kubectl client used by CLI commands.

func NewKubectlClient

func NewKubectlClient(exec Executor) (*KubectlClient, error)

NewKubectlClient creates a KubectlClient with default validators.

func NewTestKubectlClient

func NewTestKubectlClient(exec Executor) *KubectlClient

NewTestKubectlClient returns a KubectlClient for tests (no path validators).

func NewTestKubectlClientWithValidators

func NewTestKubectlClientWithValidators(exec Executor, validators []ExecValidator) *KubectlClient

NewTestKubectlClientWithValidators returns a KubectlClient for tests using the given validator list (or nil for none).

func (*KubectlClient) CombinedOutput

func (c *KubectlClient) CombinedOutput(args []string) ([]byte, error)

CombinedOutput runs kubectl with the given arguments and returns combined stdout/stderr.

func (*KubectlClient) CommandArgs

func (c *KubectlClient) CommandArgs(args []string) (Command, error)

CommandArgs builds a kubectl command with the given arguments. Validates arguments against configured validators before building.

func (*KubectlClient) Output

func (c *KubectlClient) Output(args []string) ([]byte, error)

Output runs kubectl with the given arguments and returns stdout.

func (*KubectlClient) Run

func (c *KubectlClient) Run(args []string) error

Run runs kubectl with the given arguments.

func (*KubectlClient) RunWithOutput

func (c *KubectlClient) RunWithOutput(args []string, stdout, stderr io.Writer) error

RunWithOutput runs kubectl with the given arguments, piping to the provided writers.

type KubectlRunner

type KubectlRunner interface {
	CommandArgs(args []string) (Command, error)
	Run(args []string) error
	RunWithOutput(args []string, stdout, stderr io.Writer) error
}

KubectlRunner captures the kubectl methods used by setup helpers.

func DefaultKubectlRunner

func DefaultKubectlRunner() KubectlRunner

DefaultKubectlRunner returns the shared kubectl runner used by CLI commands.

type MockCommand

type MockCommand struct {
	Args       []string
	OutputData []byte
	OutputErr  error
	RunErr     error
	StdoutW    io.Writer
	StderrW    io.Writer
	StdinR     io.Reader
	RunFunc    func() error
}

MockCommand is a test double for Command interface.

func (*MockCommand) CombinedOutput

func (m *MockCommand) CombinedOutput() ([]byte, error)

func (*MockCommand) Output

func (m *MockCommand) Output() ([]byte, error)

func (*MockCommand) Run

func (m *MockCommand) Run() error

func (*MockCommand) SetStderr

func (m *MockCommand) SetStderr(w io.Writer)

func (*MockCommand) SetStdin

func (m *MockCommand) SetStdin(r io.Reader)

func (*MockCommand) SetStdout

func (m *MockCommand) SetStdout(w io.Writer)

type MockExecutor

type MockExecutor struct {
	// Commands records all commands that were created.
	Commands []ExecSpec
	// DefaultOutput is returned by commands when CommandFunc is nil.
	DefaultOutput []byte
	// DefaultErr is the error returned by Output/CombinedOutput.
	DefaultErr error
	// DefaultRunErr is the error returned by Run.
	DefaultRunErr error
	// CommandFunc allows custom behavior per command.
	CommandFunc func(spec ExecSpec) *MockCommand
}

MockExecutor is a test double for Executor interface.

func (*MockExecutor) Command

func (m *MockExecutor) Command(name string, args []string, validators ...ExecValidator) (Command, error)

func (*MockExecutor) HasCommand

func (m *MockExecutor) HasCommand(name string) bool

HasCommand checks if a command with the given name was executed.

func (*MockExecutor) LastCommand

func (m *MockExecutor) LastCommand() ExecSpec

LastCommand returns the most recent command spec.

func (*MockExecutor) Reset

func (m *MockExecutor) Reset()

Reset clears recorded commands.

type Printer

type Printer struct {
	// Quiet suppresses non-essential output
	Quiet bool
	// Writer overrides the output destination when set.
	Writer io.Writer
}

Printer provides formatted terminal output methods. Use the default instance via package-level functions.

func (*Printer) Cyan

func (p *Printer) Cyan(msg string) string

Cyan returns cyan-colored text.

func (*Printer) Error

func (p *Printer) Error(msg string)

Error prints an error message. Note: Errors are intentionally not suppressed in quiet mode to ensure critical issues are always visible, even when non-essential output is disabled.

func (*Printer) Green

func (p *Printer) Green(msg string) string

Green returns green-colored text.

func (*Printer) Header

func (p *Printer) Header(title string)

Header prints a full-width header banner.

func (*Printer) Info

func (p *Printer) Info(msg string)

Info prints an informational message.

func (*Printer) Printf

func (p *Printer) Printf(format string, a ...interface{})

Printf prints formatted text.

func (*Printer) Println

func (p *Printer) Println(a ...interface{})

Println prints a plain line.

func (*Printer) Red

func (p *Printer) Red(msg string) string

Red returns red-colored text.

func (*Printer) Section

func (p *Printer) Section(title string)

Section prints a prominent section header.

func (*Printer) SpinnerStart

func (p *Printer) SpinnerStart(msg string) func(success bool, finalMsg string)

SpinnerStart starts a spinner with the given message. Returns a stop function.

func (*Printer) Step

func (p *Printer) Step(title string)

Step prints a step indicator (e.g., "Step 1: Initialize").

func (*Printer) Success

func (p *Printer) Success(msg string)

Success prints a success message.

func (*Printer) Table

func (p *Printer) Table(data [][]string)

Table prints a formatted table. First row is treated as header.

func (*Printer) TableBoxed

func (p *Printer) TableBoxed(data [][]string)

TableBoxed prints a formatted table with box borders.

func (*Printer) Warn

func (p *Printer) Warn(msg string)

Warn prints a warning message. Note: Warnings are intentionally not suppressed in quiet mode to ensure important notices are visible even when non-essential output is disabled.

func (*Printer) Yellow

func (p *Printer) Yellow(msg string) string

Yellow returns yellow-colored text.

type Runtime

type Runtime struct {
	// contains filtered or unexported fields
}

Runtime is the shared CLI facade for wiring common dependencies once and handing typed managers to the foldered command packages.

func NewRuntime

func NewRuntime(logger *zap.Logger) *Runtime

NewRuntime builds the shared CLI runtime facade.

func (*Runtime) Config

func (r *Runtime) Config() *CLIConfig

Config returns the loaded CLI configuration.

func (*Runtime) Executor

func (r *Runtime) Executor() Executor

Executor returns the shared process executor.

func (*Runtime) KubectlClient

func (r *Runtime) KubectlClient() *KubectlClient

KubectlClient returns the shared kubectl client.

func (*Runtime) KubectlRunner

func (r *Runtime) KubectlRunner() KubectlRunner

KubectlRunner returns the shared kubectl runner.

func (*Runtime) Logger

func (r *Runtime) Logger() *zap.Logger

Logger returns the shared logger.

func (*Runtime) Printer

func (r *Runtime) Printer() *Printer

Printer returns the shared terminal printer.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL