Workflow Engine
Workflow Execution Pipeline
Section titled “Workflow Execution Pipeline”When a workflow is “run”, the executor processes each node:
- Load workflow from MongoDB with all nodes and edges
- Validate status —
ExecuteWorkflow()rejects any workflow not inpublishedstatus before creating a run record - Resolve execution order —
getExecutionOrder()performs a topological sort of nodes using the edge graph so that dependencies are applied before dependents - Build connection graph —
buildConnectionGraph()analyzes edges to extract wiring relationships.getConnectedSourceData()resolves concrete cross-node dependencies: Service-to-Deployment port mappings, Ingress-to-Service backend references, and HPA-to-Deployment scaling targets. These resolved values are injected into the template rendering context so that dependent resources are automatically configured to reference their actual counterparts by name - Execute each node via its type-specific handler:
executeDeploymentNodeexecuteServiceNodeWithConnectionsexecuteIngressNodeWithConnectionsexecuteConfigMapNodeexecuteSecretNodeexecutePersistentVolumeClaimNodeexecuteStatefulSetNodeWithConnectionsexecuteJobNodeexecuteCronJobNodeexecuteDaemonSetNodeexecuteHPANodeWithConnectionsexecuteNetworkPolicyNodeWithConnectionsexecutePluginNode
- Per-node execution — each handler merges node
Datawith templateDefaultValues, renders the YAML manifest throughTemplateEngine, applies the manifest to the target cluster viaManifestApplier, then callsupdateNodeStatusandbroadcastNodeUpdateto stream the result to connected clients in real time - Start resource watchers for all deployed resources
- Stream status updates via SSE as each resource becomes ready in the cluster
The executor also provides two maintenance operations:
CleanupWorkflowResources()— called when a workflow is archived; deletes all Kubernetes resources that were created by any run of that workflowCleanupDeletedNodes()— called when a workflow canvas is saved; compares the current node set against the previous version and deletes Kubernetes resources for any nodes that were removed from the canvas
A background reconciliation function SyncWorkflowStatuses() periodically queries actual Kubernetes state and updates the MongoDB run status to match, handling cases where the API server state diverges from what the executor last recorded.
Template System
Section titled “Template System”Resource templates are stored as YAML files in templates/core/. Each resource type has:
metadata.yaml— Display name, description, category, default parameterstemplate.yaml— Go template that renders to a Kubernetes manifest
The TemplateRegistry (pkg/template/registry.go) loads all templates at startup and the TemplateEngine (pkg/template/engine.go) renders them with user-provided parameters.
The TemplateMetadata struct defines the full shape of a template’s metadata:
type TemplateMetadata struct { ID string Name string Description string Category string Tags []string Parameters []TemplateParameter DefaultValues map[string]interface{}}
type TemplateParameter struct { Name string Type string Required bool Default interface{} Description string Options []string // For enum-type parameters}The registry is initialized once at startup via InitializeGlobalRegistry() and exposes filter methods GetTemplatesByCategory and GetTemplatesByTag for discovery endpoints.
When rendering, RenderTemplate(templateID, values) resolves the template file through three candidate paths in order:
templateID/template.yaml— standard layouttemplateID/deployment.yaml— legacy layout for older templatestemplateID + ".yaml"— flat file layout
The template engine processes the resolved file using Go’s text/template package with a custom FuncMap containing three functions:
default— returns a fallback value if the primary value is empty, enabling optional parameters with sensible defaults in templatesquote— wraps a string in double quotes, useful for YAML values that must be explicitly typed as stringsbase64encode— base64-encodes a string value, used in Secret templates where Kubernetes expects base64-encoded data fields
Credential Security
Section titled “Credential Security”All cluster credentials are encrypted before storage:
User Input → AES-256-GCM Encrypt → MongoDBMongoDB → AES-256-GCM Decrypt → client-go ConfigCredentials are never returned in API responses after creation.