diff --git a/.gitignore b/.gitignore index 85015c11..fee6ade4 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,4 @@ current-bench.txt benchmark-results.txt benchstat-output.txt .worktrees +cmd/wfctl/.wfctl.yaml diff --git a/cmd/wfctl/type_registry.go b/cmd/wfctl/type_registry.go index 4472c516..e611c620 100644 --- a/cmd/wfctl/type_registry.go +++ b/cmd/wfctl/type_registry.go @@ -187,6 +187,18 @@ func KnownModuleTypes() map[string]ModuleTypeInfo { Stateful: false, ConfigKeys: []string{"secret", "algorithm", "privateKey", "tokenExpiry", "issuer", "clients"}, }, + "auth.token-blacklist": { + Type: "auth.token-blacklist", + Plugin: "auth", + Stateful: false, + ConfigKeys: []string{"ttl"}, + }, + "security.field-protection": { + Type: "security.field-protection", + Plugin: "auth", + Stateful: false, + ConfigKeys: []string{"fields", "algorithm", "keyRef"}, + }, // messaging plugin "messaging.broker": { @@ -513,6 +525,94 @@ func KnownModuleTypes() map[string]ModuleTypeInfo { Stateful: false, ConfigKeys: []string{"account", "provider", "name", "region", "image", "instances", "http_port", "envs"}, }, + "platform.do_database": { + Type: "platform.do_database", + Plugin: "platform", + Stateful: false, + ConfigKeys: []string{"account", "provider", "engine", "size", "region", "nodes"}, + }, + "platform.kubernetes": { + Type: "platform.kubernetes", + Plugin: "platform", + Stateful: false, + ConfigKeys: []string{"account", "cluster", "namespace", "kubeconfig"}, + }, + "platform.ecs": { + Type: "platform.ecs", + Plugin: "platform", + Stateful: false, + ConfigKeys: []string{"account", "cluster", "region"}, + }, + "platform.dns": { + Type: "platform.dns", + Plugin: "platform", + Stateful: false, + ConfigKeys: []string{"account", "provider", "domain"}, + }, + "platform.networking": { + Type: "platform.networking", + Plugin: "platform", + Stateful: false, + ConfigKeys: []string{"account", "provider", "vpc"}, + }, + "platform.apigateway": { + Type: "platform.apigateway", + Plugin: "platform", + Stateful: false, + ConfigKeys: []string{"account", "provider", "name", "region"}, + }, + "platform.autoscaling": { + Type: "platform.autoscaling", + Plugin: "platform", + Stateful: false, + ConfigKeys: []string{"account", "provider", "resource"}, + }, + "platform.region": { + Type: "platform.region", + Plugin: "platform", + Stateful: false, + ConfigKeys: []string{"provider", "region", "primary"}, + }, + "iac.state": { + Type: "iac.state", + Plugin: "platform", + Stateful: true, + ConfigKeys: []string{"backend", "path"}, + }, + "app.container": { + Type: "app.container", + Plugin: "platform", + Stateful: false, + ConfigKeys: []string{"image", "registry", "port", "envs"}, + }, + "argo.workflows": { + Type: "argo.workflows", + Plugin: "platform", + Stateful: false, + ConfigKeys: []string{"namespace", "kubeconfig", "server_addr"}, + }, + + // actors plugin + "actor.system": { + Type: "actor.system", + Plugin: "actors", + Stateful: false, + ConfigKeys: []string{"maxWorkers", "mailboxSize"}, + }, + "actor.pool": { + Type: "actor.pool", + Plugin: "actors", + Stateful: false, + ConfigKeys: []string{"system", "workers", "handler"}, + }, + + // scanner plugin + "security.scanner": { + Type: "security.scanner", + Plugin: "scanner", + Stateful: false, + ConfigKeys: []string{"trivy", "semgrep", "snyk"}, + }, } // Include any types registered dynamically (e.g. from external plugins loaded via LoadPluginTypesFromDir). for _, t := range schema.KnownModuleTypes() { diff --git a/cmd/wfctl/type_registry_test.go b/cmd/wfctl/type_registry_test.go index c9cad621..3a1aa658 100644 --- a/cmd/wfctl/type_registry_test.go +++ b/cmd/wfctl/type_registry_test.go @@ -223,3 +223,28 @@ func TestKnownStepTypesCoverAllPlugins(t *testing.T) { } } } + +// TestKnownModuleTypesCoverAllPlugins ensures KnownModuleTypes() is in sync with all module +// types registered by the built-in plugins. Any module type registered by a DefaultPlugin +// that is not listed in KnownModuleTypes() will cause this test to fail, preventing silent +// omissions from being introduced in the future (e.g. the auth.m2m missing-type regression). +func TestKnownModuleTypesCoverAllPlugins(t *testing.T) { + // Collect all module types registered by DefaultPlugins via the PluginLoader. + capReg := capability.NewRegistry() + schemaReg := schema.NewModuleSchemaRegistry() + loader := plugin.NewPluginLoader(capReg, schemaReg) + for _, p := range all.DefaultPlugins() { + if err := loader.LoadPlugin(p); err != nil { + t.Fatalf("LoadPlugin(%q) error: %v", p.Name(), err) + } + } + + pluginModules := loader.ModuleFactories() + known := KnownModuleTypes() + + for modType := range pluginModules { + if _, ok := known[modType]; !ok { + t.Errorf("module type %q is registered by a built-in plugin but missing from KnownModuleTypes()", modType) + } + } +} diff --git a/consistency_test.go b/consistency_test.go index e044ae20..195b7d1c 100644 --- a/consistency_test.go +++ b/consistency_test.go @@ -3,7 +3,9 @@ package workflow import ( "testing" + "github.com/GoCodeAlone/workflow/capability" "github.com/GoCodeAlone/workflow/module" + "github.com/GoCodeAlone/workflow/plugin" "github.com/GoCodeAlone/workflow/plugins/all" "github.com/GoCodeAlone/workflow/schema" ) @@ -59,4 +61,34 @@ func TestRegistryConsistency(t *testing.T) { t.Errorf("expected at least 40 engine step types, got %d", len(engineTypes)) } }) + + t.Run("schema KnownModuleTypes covers all built-in plugin module types", func(t *testing.T) { + // This is the contract test: every module type registered by a DefaultPlugin + // must appear in schema.KnownModuleTypes() so that wfctl validate does not + // report false "unknown module type" errors. + capReg := capability.NewRegistry() + schemaReg := schema.NewModuleSchemaRegistry() + loader := plugin.NewPluginLoader(capReg, schemaReg) + for _, p := range all.DefaultPlugins() { + if err := loader.LoadPlugin(p); err != nil { + t.Fatalf("LoadPlugin(%q) error: %v", p.Name(), err) + } + } + + known := make(map[string]bool) + for _, mt := range schema.KnownModuleTypes() { + known[mt] = true + } + + for modType := range loader.ModuleFactories() { + if !known[modType] { + t.Errorf("module type %q is registered by a built-in plugin but missing from schema.KnownModuleTypes() — add it to coreModuleTypes in schema/schema.go", modType) + } + } + for stepType := range loader.StepFactories() { + if !known[stepType] { + t.Errorf("step type %q is registered by a built-in plugin but missing from schema.KnownModuleTypes() — add it to coreModuleTypes in schema/schema.go", stepType) + } + } + }) } diff --git a/schema/module_schema.go b/schema/module_schema.go index 94230de6..72d8312e 100644 --- a/schema/module_schema.go +++ b/schema/module_schema.go @@ -2309,4 +2309,639 @@ func (r *ModuleSchemaRegistry) registerBuiltins() { {Key: "token_source", Label: "Token Source", Type: FieldTypeString, Required: true, Description: "Dot-path to Bearer token"}, }, }) + + // ---- Actor System ---- + + r.Register(&ModuleSchema{ + Type: "actor.system", + Label: "Actor System", + Category: "infrastructure", + Description: "Actor runtime for stateful, message-driven services. " + + "Actors are lightweight, isolated units of computation that communicate through messages.", + ConfigFields: []ConfigFieldDef{ + {Key: "shutdownTimeout", Label: "Shutdown Timeout", Type: FieldTypeDuration, Description: "How long to wait for in-flight messages to drain before forcing shutdown", DefaultValue: "30s"}, + {Key: "defaultRecovery", Label: "Default Recovery Policy", Type: FieldTypeJSON, Description: "What happens when any actor in this system crashes"}, + }, + }) + + // ---- Actor Pool ---- + + r.Register(&ModuleSchema{ + Type: "actor.pool", + Label: "Actor Pool", + Category: "infrastructure", + Description: "Defines a group of actors that handle the same type of work with configurable lifecycle and routing.", + ConfigFields: []ConfigFieldDef{ + {Key: "system", Label: "Actor Cluster", Type: FieldTypeString, Required: true, Description: "Name of the actor.system module this pool belongs to"}, + {Key: "mode", Label: "Lifecycle Mode", Type: FieldTypeSelect, Options: []string{"auto-managed", "permanent"}, DefaultValue: "auto-managed", Description: "'auto-managed': actors activate on first message; 'permanent': fixed pool"}, + {Key: "idleTimeout", Label: "Idle Timeout", Type: FieldTypeDuration, DefaultValue: "10m", Description: "How long an auto-managed actor stays idle before deactivating"}, + {Key: "poolSize", Label: "Pool Size", Type: FieldTypeNumber, DefaultValue: 10, Description: "Number of actors in a permanent pool"}, + {Key: "routing", Label: "Load Balancing", Type: FieldTypeSelect, Options: []string{"round-robin", "random", "broadcast", "sticky"}, DefaultValue: "round-robin", Description: "How messages are distributed among actors"}, + {Key: "routingKey", Label: "Sticky Routing Key", Type: FieldTypeString, Description: "Message field used for sticky routing"}, + {Key: "recovery", Label: "Recovery Policy", Type: FieldTypeJSON, Description: "What happens when an actor crashes"}, + }, + }) + + // ---- App Container ---- + + r.Register(&ModuleSchema{ + Type: "app.container", + Label: "App Container", + Category: "infrastructure", + Description: "Application deployment abstraction that translates high-level config into platform-specific resources (Kubernetes Deployment+Service or ECS task definition)", + ConfigFields: []ConfigFieldDef{ + {Key: "environment", Label: "Environment", Type: FieldTypeString, Required: true, Description: "Name of the platform.kubernetes or platform.ecs module to deploy to"}, + {Key: "image", Label: "Container Image", Type: FieldTypeString, Required: true, Description: "Container image reference (e.g. registry.example.com/my-api:v1.0.0)"}, + {Key: "replicas", Label: "Replicas", Type: FieldTypeNumber, Description: "Desired replica count"}, + {Key: "ports", Label: "Ports", Type: FieldTypeArray, Description: "List of container port numbers"}, + {Key: "cpu", Label: "CPU", Type: FieldTypeString, Description: "CPU request/limit (e.g. 500m)"}, + {Key: "memory", Label: "Memory", Type: FieldTypeString, Description: "Memory request/limit (e.g. 512Mi)"}, + {Key: "env", Label: "Environment Variables", Type: FieldTypeMap, Description: "Environment variables injected into the container"}, + {Key: "health_path", Label: "Health Path", Type: FieldTypeString, Description: "HTTP health check path"}, + {Key: "health_port", Label: "Health Port", Type: FieldTypeNumber, Description: "HTTP health check port"}, + }, + }) + + // ---- Argo Workflows ---- + + r.Register(&ModuleSchema{ + Type: "argo.workflows", + Label: "Argo Workflows", + Category: "cicd", + Description: "Manages Argo Workflows submissions and status on a Kubernetes cluster", + ConfigFields: []ConfigFieldDef{ + {Key: "namespace", Label: "Namespace", Type: FieldTypeString, Description: "Kubernetes namespace for Argo Workflows"}, + {Key: "server", Label: "Argo Server", Type: FieldTypeString, Description: "Argo Workflows server URL"}, + {Key: "token", Label: "Auth Token", Type: FieldTypeString, Description: "Bearer token for Argo server authentication", Sensitive: true}, + }, + }) + + // ---- Auth Token Blacklist ---- + + r.Register(&ModuleSchema{ + Type: "auth.token-blacklist", + Label: "Token Blacklist", + Category: "security", + Description: "JWT token blacklist for revocation support (memory or Redis backend)", + ConfigFields: []ConfigFieldDef{ + {Key: "backend", Label: "Backend", Type: FieldTypeSelect, Options: []string{"memory", "redis"}, DefaultValue: "memory", Description: "Storage backend for the blacklist"}, + {Key: "redis_url", Label: "Redis URL", Type: FieldTypeString, Description: "Redis connection URL (redis backend only)", Placeholder: "redis://localhost:6379"}, + {Key: "cleanup_interval", Label: "Cleanup Interval", Type: FieldTypeDuration, DefaultValue: "5m", Description: "How often to purge expired tokens"}, + }, + }) + + // ---- AWS CodeBuild ---- + + r.Register(&ModuleSchema{ + Type: "aws.codebuild", + Label: "AWS CodeBuild", + Category: "cicd", + Description: "AWS CodeBuild integration for running build projects in the cloud", + ConfigFields: []ConfigFieldDef{ + {Key: "region", Label: "AWS Region", Type: FieldTypeString, Description: "AWS region (e.g. us-east-1)"}, + {Key: "account", Label: "Cloud Account", Type: FieldTypeString, Description: "Name of the cloud.account module"}, + {Key: "role_arn", Label: "IAM Role ARN", Type: FieldTypeString, Description: "IAM role ARN for CodeBuild service role"}, + }, + }) + + // ---- Cache Redis ---- + + r.Register(&ModuleSchema{ + Type: "cache.redis", + Label: "Redis Cache", + Category: "infrastructure", + Description: "Redis-backed key/value cache for pipeline step data", + ConfigFields: []ConfigFieldDef{ + {Key: "address", Label: "Address", Type: FieldTypeString, DefaultValue: "localhost:6379", Description: "Redis server address (host:port)"}, + {Key: "password", Label: "Password", Type: FieldTypeString, Description: "Redis password (optional)", Sensitive: true}, + {Key: "db", Label: "Database", Type: FieldTypeNumber, DefaultValue: 0, Description: "Redis database number"}, + {Key: "prefix", Label: "Key Prefix", Type: FieldTypeString, DefaultValue: "wf:", Description: "Prefix applied to all cache keys"}, + {Key: "defaultTTL", Label: "Default TTL", Type: FieldTypeString, DefaultValue: "1h", Description: "Default time-to-live for cached values"}, + }, + }) + + // ---- Cloud Account ---- + + r.Register(&ModuleSchema{ + Type: "cloud.account", + Label: "Cloud Account", + Category: "infrastructure", + Description: "Cloud provider credentials (AWS, GCP, Azure, DigitalOcean, Kubernetes, or mock)", + ConfigFields: []ConfigFieldDef{ + {Key: "provider", Label: "Provider", Type: FieldTypeString, Required: true, Description: "Cloud provider: aws, gcp, azure, digitalocean, kubernetes, mock"}, + {Key: "region", Label: "Region", Type: FieldTypeString, Description: "Primary region (e.g. us-east-1, us-central1, eastus, nyc3)"}, + {Key: "credentials", Label: "Credentials", Type: FieldTypeJSON, Description: "Credential configuration (type, keys, paths)"}, + {Key: "project_id", Label: "GCP Project ID", Type: FieldTypeString, Description: "GCP project ID"}, + {Key: "subscription_id", Label: "Azure Subscription ID", Type: FieldTypeString, Description: "Azure subscription ID"}, + }, + }) + + // ---- GitLab Client ---- + + r.Register(&ModuleSchema{ + Type: "gitlab.client", + Label: "GitLab Client", + Category: "integration", + Description: "GitLab API client for triggering pipelines, managing MRs, and querying pipeline status", + ConfigFields: []ConfigFieldDef{ + {Key: "url", Label: "GitLab URL", Type: FieldTypeString, DefaultValue: "https://gitlab.com", Description: "GitLab instance URL"}, + {Key: "token", Label: "Access Token", Type: FieldTypeString, Required: true, Description: "GitLab personal or project access token", Sensitive: true}, + }, + }) + + // ---- GitLab Webhook ---- + + r.Register(&ModuleSchema{ + Type: "gitlab.webhook", + Label: "GitLab Webhook", + Category: "integration", + Description: "GitLab webhook receiver that parses and validates incoming GitLab events", + ConfigFields: []ConfigFieldDef{ + {Key: "secret", Label: "Webhook Secret", Type: FieldTypeString, Description: "GitLab webhook secret token for request validation", Sensitive: true}, + }, + }) + + // ---- HTTP Middleware OTEL ---- + + r.Register(&ModuleSchema{ + Type: "http.middleware.otel", + Label: "OTEL HTTP Middleware", + Category: "observability", + Description: "Instruments HTTP requests with OpenTelemetry tracing spans", + ConfigFields: []ConfigFieldDef{ + {Key: "serverName", Label: "Server Name", Type: FieldTypeString, DefaultValue: "workflow-http", Description: "Server name used as the span operation name"}, + }, + }) + + // ---- IaC State ---- + + r.Register(&ModuleSchema{ + Type: "iac.state", + Label: "IaC State Store", + Category: "infrastructure", + Description: "Tracks infrastructure provisioning state (memory or filesystem backend)", + ConfigFields: []ConfigFieldDef{ + {Key: "backend", Label: "Backend", Type: FieldTypeString, Description: "memory or filesystem"}, + {Key: "directory", Label: "Directory", Type: FieldTypeString, Description: "State directory (filesystem backend only)"}, + }, + }) + + // ---- NoSQL DynamoDB ---- + + r.Register(&ModuleSchema{ + Type: "nosql.dynamodb", + Label: "DynamoDB", + Category: "database", + Description: "AWS DynamoDB NoSQL store", + ConfigFields: []ConfigFieldDef{ + {Key: "region", Label: "Region", Type: FieldTypeString, Description: "AWS region"}, + {Key: "table", Label: "Table", Type: FieldTypeString, Required: true, Description: "DynamoDB table name"}, + {Key: "endpoint", Label: "Endpoint", Type: FieldTypeString, Description: "Custom endpoint (for local DynamoDB)"}, + }, + }) + + // ---- NoSQL Memory ---- + + r.Register(&ModuleSchema{ + Type: "nosql.memory", + Label: "In-Memory NoSQL", + Category: "database", + Description: "In-memory NoSQL store for testing and development", + ConfigFields: []ConfigFieldDef{}, + }) + + // ---- NoSQL MongoDB ---- + + r.Register(&ModuleSchema{ + Type: "nosql.mongodb", + Label: "MongoDB", + Category: "database", + Description: "MongoDB NoSQL document store", + ConfigFields: []ConfigFieldDef{ + {Key: "uri", Label: "Connection URI", Type: FieldTypeString, Required: true, Description: "MongoDB connection URI", Placeholder: "mongodb://localhost:27017"}, + {Key: "database", Label: "Database", Type: FieldTypeString, Required: true, Description: "MongoDB database name"}, + {Key: "collection", Label: "Collection", Type: FieldTypeString, Description: "Default collection name"}, + }, + }) + + // ---- NoSQL Redis ---- + + r.Register(&ModuleSchema{ + Type: "nosql.redis", + Label: "Redis NoSQL", + Category: "database", + Description: "Redis as a NoSQL key/value store", + ConfigFields: []ConfigFieldDef{ + {Key: "address", Label: "Address", Type: FieldTypeString, DefaultValue: "localhost:6379", Description: "Redis server address"}, + {Key: "password", Label: "Password", Type: FieldTypeString, Description: "Redis password", Sensitive: true}, + {Key: "db", Label: "Database", Type: FieldTypeNumber, DefaultValue: 0, Description: "Redis database number"}, + }, + }) + + // ---- Platform API Gateway ---- + + r.Register(&ModuleSchema{ + Type: "platform.apigateway", + Label: "API Gateway", + Category: "infrastructure", + Description: "Manages API gateway provisioning with routes, stages, and rate limiting (mock or AWS API Gateway v2)", + ConfigFields: []ConfigFieldDef{ + {Key: "account", Label: "Cloud Account", Type: FieldTypeString, Description: "Name of the cloud.account module"}, + {Key: "provider", Label: "Provider", Type: FieldTypeString, Description: "mock | aws"}, + {Key: "name", Label: "Gateway Name", Type: FieldTypeString, Required: true, Description: "API gateway name"}, + {Key: "stage", Label: "Stage", Type: FieldTypeString, Description: "Deployment stage (dev, staging, prod)"}, + {Key: "cors", Label: "CORS Config", Type: FieldTypeJSON, Description: "CORS configuration"}, + {Key: "routes", Label: "Routes", Type: FieldTypeJSON, Description: "Route definitions"}, + }, + }) + + // ---- Platform Autoscaling ---- + + r.Register(&ModuleSchema{ + Type: "platform.autoscaling", + Label: "Autoscaling Policies", + Category: "infrastructure", + Description: "Manages autoscaling policies (target tracking, step, scheduled) for AWS or mock resources", + ConfigFields: []ConfigFieldDef{ + {Key: "account", Label: "Cloud Account", Type: FieldTypeString, Description: "Name of the cloud.account module"}, + {Key: "provider", Label: "Provider", Type: FieldTypeString, Description: "mock | aws"}, + {Key: "policies", Label: "Policies", Type: FieldTypeJSON, Required: true, Description: "Scaling policy definitions"}, + }, + }) + + // ---- Platform DNS ---- + + r.Register(&ModuleSchema{ + Type: "platform.dns", + Label: "DNS Zone Manager", + Category: "infrastructure", + Description: "Manages DNS zones and records (mock or Route53/aws backend)", + ConfigFields: []ConfigFieldDef{ + {Key: "account", Label: "Cloud Account", Type: FieldTypeString, Description: "Name of the cloud.account module"}, + {Key: "provider", Label: "Provider", Type: FieldTypeString, Description: "mock | aws"}, + {Key: "zone", Label: "Zone Config", Type: FieldTypeJSON, Required: true, Description: "Zone configuration (name, comment, private, vpcId)"}, + {Key: "records", Label: "DNS Records", Type: FieldTypeJSON, Description: "List of DNS record definitions"}, + }, + }) + + // ---- Platform DigitalOcean App ---- + + r.Register(&ModuleSchema{ + Type: "platform.do_app", + Label: "DigitalOcean App Platform", + Category: "infrastructure", + Description: "Deploys containerized apps to DigitalOcean App Platform (mock or real DO backend)", + ConfigFields: []ConfigFieldDef{ + {Key: "account", Label: "Cloud Account", Type: FieldTypeString, Description: "Name of the cloud.account module"}, + {Key: "provider", Label: "Provider", Type: FieldTypeString, Description: "mock | digitalocean"}, + {Key: "name", Label: "App Name", Type: FieldTypeString, Description: "App Platform application name"}, + {Key: "region", Label: "Region", Type: FieldTypeString, Description: "DO region slug (e.g. nyc)"}, + {Key: "image", Label: "Container Image", Type: FieldTypeString, Description: "Container image reference"}, + {Key: "instances", Label: "Instances", Type: FieldTypeNumber, Description: "Number of instances"}, + {Key: "http_port", Label: "HTTP Port", Type: FieldTypeNumber, Description: "Container HTTP port"}, + {Key: "envs", Label: "Environment Variables", Type: FieldTypeMap, Description: "Environment variables for the app"}, + }, + }) + + // ---- Platform DigitalOcean Database ---- + + r.Register(&ModuleSchema{ + Type: "platform.do_database", + Label: "DigitalOcean Managed Database", + Category: "infrastructure", + Description: "Manages DigitalOcean Managed Databases (PostgreSQL, MySQL, Redis, MongoDB, Kafka)", + ConfigFields: []ConfigFieldDef{ + {Key: "account", Label: "Cloud Account", Type: FieldTypeString, Description: "Name of the cloud.account module"}, + {Key: "provider", Label: "Provider", Type: FieldTypeString, Description: "mock | digitalocean"}, + {Key: "engine", Label: "Engine", Type: FieldTypeString, Description: "Database engine: pg | mysql | redis | mongodb | kafka"}, + {Key: "version", Label: "Version", Type: FieldTypeString, Description: "Engine version"}, + {Key: "size", Label: "Size", Type: FieldTypeString, Description: "Droplet size slug"}, + {Key: "region", Label: "Region", Type: FieldTypeString, Description: "DO region slug"}, + {Key: "num_nodes", Label: "Node Count", Type: FieldTypeNumber, Description: "Number of nodes"}, + {Key: "name", Label: "Cluster Name", Type: FieldTypeString, Description: "Database cluster name"}, + }, + }) + + // ---- Platform DigitalOcean DNS ---- + + r.Register(&ModuleSchema{ + Type: "platform.do_dns", + Label: "DigitalOcean DNS", + Category: "infrastructure", + Description: "Manages DigitalOcean domains and DNS records (mock or real DO backend)", + ConfigFields: []ConfigFieldDef{ + {Key: "account", Label: "Cloud Account", Type: FieldTypeString, Description: "Name of the cloud.account module"}, + {Key: "provider", Label: "Provider", Type: FieldTypeString, Description: "mock | digitalocean"}, + {Key: "domain", Label: "Domain", Type: FieldTypeString, Required: true, Description: "Domain name (e.g. example.com)"}, + {Key: "records", Label: "Records", Type: FieldTypeJSON, Description: "List of DNS record definitions"}, + }, + }) + + // ---- Platform DigitalOcean Networking ---- + + r.Register(&ModuleSchema{ + Type: "platform.do_networking", + Label: "DigitalOcean VPC & Firewalls", + Category: "infrastructure", + Description: "Manages DigitalOcean VPCs, firewalls, and load balancers (mock or real DO backend)", + ConfigFields: []ConfigFieldDef{ + {Key: "account", Label: "Cloud Account", Type: FieldTypeString, Description: "Name of the cloud.account module"}, + {Key: "provider", Label: "Provider", Type: FieldTypeString, Description: "mock | digitalocean"}, + {Key: "vpc", Label: "VPC Config", Type: FieldTypeJSON, Required: true, Description: "VPC configuration (name, region, ip_range)"}, + {Key: "firewalls", Label: "Firewalls", Type: FieldTypeJSON, Description: "List of firewall definitions"}, + }, + }) + + // ---- Platform DOKS ---- + + r.Register(&ModuleSchema{ + Type: "platform.doks", + Label: "DigitalOcean Kubernetes (DOKS)", + Category: "infrastructure", + Description: "Manages DigitalOcean Kubernetes Service clusters (mock or real DO backend)", + ConfigFields: []ConfigFieldDef{ + {Key: "account", Label: "Cloud Account", Type: FieldTypeString, Description: "Name of the cloud.account module"}, + {Key: "cluster_name", Label: "Cluster Name", Type: FieldTypeString, Description: "DOKS cluster name"}, + {Key: "region", Label: "Region", Type: FieldTypeString, Description: "DO region slug (e.g. nyc3)"}, + {Key: "version", Label: "Kubernetes Version", Type: FieldTypeString, Description: "Kubernetes version slug"}, + {Key: "node_pool", Label: "Node Pool", Type: FieldTypeJSON, Description: "Node pool config"}, + }, + }) + + // ---- Platform ECS ---- + + r.Register(&ModuleSchema{ + Type: "platform.ecs", + Label: "ECS Fargate Service", + Category: "infrastructure", + Description: "AWS ECS/Fargate service with task definitions and ALB target group config", + ConfigFields: []ConfigFieldDef{ + {Key: "account", Label: "Cloud Account", Type: FieldTypeString, Description: "Name of the cloud.account module"}, + {Key: "cluster", Label: "ECS Cluster", Type: FieldTypeString, Required: true, Description: "ECS cluster name"}, + {Key: "region", Label: "AWS Region", Type: FieldTypeString, Description: "AWS region (e.g. us-east-1)"}, + {Key: "launch_type", Label: "Launch Type", Type: FieldTypeString, Description: "FARGATE or EC2"}, + {Key: "desired_count", Label: "Desired Count", Type: FieldTypeString, Description: "Number of tasks to run"}, + {Key: "vpc_subnets", Label: "VPC Subnets", Type: FieldTypeJSON, Description: "List of subnet IDs"}, + {Key: "security_groups", Label: "Security Groups", Type: FieldTypeJSON, Description: "List of security group IDs"}, + }, + }) + + // ---- Platform Kubernetes ---- + + r.Register(&ModuleSchema{ + Type: "platform.kubernetes", + Label: "Kubernetes Cluster", + Category: "infrastructure", + Description: "Managed Kubernetes cluster (kind/k3s for local, EKS/GKE/AKS stubs for cloud)", + ConfigFields: []ConfigFieldDef{ + {Key: "account", Label: "Cloud Account", Type: FieldTypeString, Description: "Name of the cloud.account module"}, + {Key: "type", Label: "Cluster Type", Type: FieldTypeString, Required: true, Description: "eks | gke | aks | kind | k3s"}, + {Key: "version", Label: "Kubernetes Version", Type: FieldTypeString, Description: "e.g. 1.29"}, + {Key: "nodeGroups", Label: "Node Groups", Type: FieldTypeJSON, Description: "Node group definitions"}, + }, + }) + + // ---- Platform Networking ---- + + r.Register(&ModuleSchema{ + Type: "platform.networking", + Label: "VPC Networking", + Category: "infrastructure", + Description: "Manages VPC, subnets, NAT gateway, and security groups (mock or AWS backend)", + ConfigFields: []ConfigFieldDef{ + {Key: "account", Label: "Cloud Account", Type: FieldTypeString, Description: "Name of the cloud.account module"}, + {Key: "provider", Label: "Provider", Type: FieldTypeString, Description: "mock | aws"}, + {Key: "vpc", Label: "VPC Config", Type: FieldTypeJSON, Required: true, Description: "VPC configuration (cidr, name)"}, + {Key: "subnets", Label: "Subnets", Type: FieldTypeJSON, Description: "List of subnet definitions"}, + {Key: "nat_gateway", Label: "NAT Gateway", Type: FieldTypeBool, Description: "Provision a NAT gateway"}, + {Key: "security_groups", Label: "Security Groups", Type: FieldTypeJSON, Description: "List of security group definitions"}, + }, + }) + + // ---- Platform Region ---- + + r.Register(&ModuleSchema{ + Type: "platform.region", + Label: "Multi-Region Deployment", + Category: "infrastructure", + Description: "Manages multi-region tenant deployments with failover, health checking, and traffic weight routing", + ConfigFields: []ConfigFieldDef{ + {Key: "provider", Label: "Provider", Type: FieldTypeString, Description: "mock (default)"}, + {Key: "regions", Label: "Regions", Type: FieldTypeJSON, Required: true, Description: "List of region definitions (name, provider, endpoint, priority, health_check)"}, + }, + }) + + // ---- Platform Region Router ---- + + r.Register(&ModuleSchema{ + Type: "platform.region_router", + Label: "Region Router", + Category: "infrastructure", + Description: "Routes traffic between regions based on weights, health, and failover policies", + ConfigFields: []ConfigFieldDef{ + {Key: "region", Label: "Region Module", Type: FieldTypeString, Required: true, Description: "Name of the platform.region module to route"}, + {Key: "strategy", Label: "Routing Strategy", Type: FieldTypeSelect, Options: []string{"weighted", "failover", "active-active"}, DefaultValue: "weighted", Description: "Traffic routing strategy"}, + }, + }) + + // ---- Policy Mock ---- + + r.Register(&ModuleSchema{ + Type: "policy.mock", + Label: "Mock Policy Engine", + Category: "security", + Description: "In-memory mock policy engine for testing. Denies if any loaded policy contains the word 'deny'.", + ConfigFields: []ConfigFieldDef{ + {Key: "policies", Label: "Pre-loaded Policies", Type: FieldTypeJSON, Description: "List of policies to load at startup"}, + }, + }) + + // ---- Security Field Protection ---- + + r.Register(&ModuleSchema{ + Type: "security.field-protection", + Label: "Field Protection", + Category: "security", + Description: "Field-level encryption/masking for sensitive data in pipeline responses", + ConfigFields: []ConfigFieldDef{ + {Key: "fields", Label: "Protected Fields", Type: FieldTypeJSON, Description: "List of field protection rules (path, action: mask|encrypt|redact)"}, + {Key: "key", Label: "Encryption Key", Type: FieldTypeString, Description: "Key used for field encryption", Sensitive: true}, + }, + }) + + // ---- Security Scanner ---- + + r.Register(&ModuleSchema{ + Type: "security.scanner", + Label: "Security Scanner", + Category: "security", + Description: "Security scanner provider supporting mock, semgrep, trivy, and grype backends", + ConfigFields: []ConfigFieldDef{ + {Key: "mode", Label: "Mode", Type: FieldTypeSelect, Options: []string{"mock", "cli"}, DefaultValue: "mock", Description: "Scanner mode: 'mock' for testing or 'cli' for real tools"}, + {Key: "semgrepBinary", Label: "Semgrep Binary", Type: FieldTypeString, DefaultValue: "semgrep", Description: "Path to semgrep binary"}, + {Key: "trivyBinary", Label: "Trivy Binary", Type: FieldTypeString, DefaultValue: "trivy", Description: "Path to trivy binary"}, + {Key: "grypeBinary", Label: "Grype Binary", Type: FieldTypeString, DefaultValue: "grype", Description: "Path to grype binary"}, + {Key: "mockFindings", Label: "Mock Findings", Type: FieldTypeJSON, Description: "Mock findings to return (keyed by scan type: sast, container, deps)"}, + }, + }) + + // ---- Storage Artifact ---- + + r.Register(&ModuleSchema{ + Type: "storage.artifact", + Label: "Artifact Store", + Category: "infrastructure", + Description: "Named artifact storage with metadata support (filesystem or S3)", + ConfigFields: []ConfigFieldDef{ + {Key: "backend", Label: "Backend", Type: FieldTypeSelect, Options: []string{"filesystem", "s3"}, DefaultValue: "filesystem", Description: "Storage backend to use"}, + {Key: "basePath", Label: "Base Path", Type: FieldTypeString, DefaultValue: "./data/artifacts", Description: "Root directory for filesystem backend"}, + {Key: "maxSize", Label: "Max Size (bytes)", Type: FieldTypeNumber, Description: "Maximum artifact size in bytes (0 = unlimited)"}, + {Key: "bucket", Label: "S3 Bucket", Type: FieldTypeString, Description: "S3 bucket name (s3 backend only)"}, + {Key: "region", Label: "S3 Region", Type: FieldTypeString, Description: "AWS region (s3 backend only)"}, + {Key: "endpoint", Label: "S3 Endpoint", Type: FieldTypeString, Description: "Custom S3 endpoint"}, + }, + }) + + // ---- Tracing Propagation ---- + + r.Register(&ModuleSchema{ + Type: "tracing.propagation", + Label: "Trace Propagation", + Category: "observability", + Description: "Propagates trace context across async boundaries (Kafka, EventBridge, webhooks, HTTP)", + ConfigFields: []ConfigFieldDef{ + {Key: "format", Label: "Propagation Format", Type: FieldTypeSelect, Options: []string{"w3c", "b3", "composite"}, DefaultValue: "w3c", Description: "Trace context propagation format"}, + }, + }) + + // ---- Auth M2M ---- + + r.Register(&ModuleSchema{ + Type: "auth.m2m", + Label: "M2M Auth", + Category: "security", + Description: "Machine-to-machine OAuth2 auth: client_credentials grant, JWT-bearer assertion, ES256/HS256 token issuance, and JWKS endpoint", + ConfigFields: []ConfigFieldDef{ + {Key: "secret", Label: "HMAC Secret", Type: FieldTypeString, Description: "Secret for HS256 token signing", Sensitive: true}, + {Key: "algorithm", Label: "Signing Algorithm", Type: FieldTypeSelect, Options: []string{"HS256", "ES256"}, DefaultValue: "ES256", Description: "JWT signing algorithm"}, + {Key: "tokenExpiry", Label: "Token Expiry", Type: FieldTypeDuration, DefaultValue: "1h", Description: "Access token expiration duration"}, + {Key: "issuer", Label: "Issuer", Type: FieldTypeString, DefaultValue: "workflow", Description: "Token issuer claim"}, + {Key: "clients", Label: "Registered Clients", Type: FieldTypeJSON, Description: "List of OAuth2 clients"}, + }, + }) + + // ---- Auth OAuth2 ---- + + r.Register(&ModuleSchema{ + Type: "auth.oauth2", + Label: "OAuth2", + Category: "security", + Description: "OAuth2 authorization code flow supporting Google, GitHub, and generic OIDC providers", + ConfigFields: []ConfigFieldDef{ + {Key: "providers", Label: "Providers", Type: FieldTypeJSON, Required: true, Description: "List of OAuth2 provider configurations"}, + }, + }) + + // ---- Step types (pipeline steps registered as module types) ---- + + for _, stepType := range []struct { + t, label, desc string + }{ + {"step.actor_send", "Actor Send", "Send a message to an actor without waiting for a response"}, + {"step.actor_ask", "Actor Ask", "Send a message to an actor and wait for a response"}, + {"step.apigw_apply", "API Gateway Apply", "Applies API gateway configuration"}, + {"step.apigw_destroy", "API Gateway Destroy", "Destroys a provisioned API gateway"}, + {"step.apigw_plan", "API Gateway Plan", "Plans API gateway changes without applying them"}, + {"step.apigw_status", "API Gateway Status", "Gets the current status of an API gateway"}, + {"step.app_deploy", "App Deploy", "Deploys an application container"}, + {"step.app_rollback", "App Rollback", "Rolls back an application to a previous version"}, + {"step.app_status", "App Status", "Gets the deployment status of an application"}, + {"step.argo_delete", "Argo Delete", "Deletes an Argo Workflow"}, + {"step.argo_list", "Argo List", "Lists Argo Workflows"}, + {"step.argo_logs", "Argo Logs", "Retrieves logs from an Argo Workflow"}, + {"step.argo_status", "Argo Status", "Gets the status of an Argo Workflow"}, + {"step.argo_submit", "Argo Submit", "Submits an Argo Workflow"}, + {"step.artifact_delete", "Artifact Delete", "Deletes an artifact from the artifact store"}, + {"step.artifact_download", "Artifact Download", "Downloads an artifact from the artifact store"}, + {"step.artifact_list", "Artifact List", "Lists artifacts in the artifact store"}, + {"step.artifact_upload", "Artifact Upload", "Uploads a file as an artifact"}, + {"step.build_binary", "Build Binary", "Builds a Go binary from source"}, + {"step.build_from_config", "Build From Config", "Builds using workflow engine config as build spec"}, + {"step.cloud_validate", "Cloud Validate", "Validates cloud provider credentials"}, + {"step.codebuild_create_project", "CodeBuild Create Project", "Creates an AWS CodeBuild project"}, + {"step.codebuild_delete_project", "CodeBuild Delete Project", "Deletes an AWS CodeBuild project"}, + {"step.codebuild_list_builds", "CodeBuild List Builds", "Lists builds for a CodeBuild project"}, + {"step.codebuild_logs", "CodeBuild Logs", "Retrieves logs for a CodeBuild build"}, + {"step.codebuild_start", "CodeBuild Start", "Starts an AWS CodeBuild build"}, + {"step.codebuild_status", "CodeBuild Status", "Gets the status of a CodeBuild build"}, + {"step.dns_apply", "DNS Apply", "Applies DNS zone and record changes"}, + {"step.dns_plan", "DNS Plan", "Plans DNS changes without applying them"}, + {"step.dns_status", "DNS Status", "Gets the current status of a DNS zone"}, + {"step.do_deploy", "DO Deploy", "Deploys to DigitalOcean App Platform"}, + {"step.do_destroy", "DO Destroy", "Destroys a DigitalOcean App Platform application"}, + {"step.do_logs", "DO Logs", "Retrieves logs from DigitalOcean App Platform"}, + {"step.do_scale", "DO Scale", "Scales a DigitalOcean App Platform application"}, + {"step.do_status", "DO Status", "Gets the status of a DigitalOcean App Platform application"}, + {"step.ecs_apply", "ECS Apply", "Applies ECS Fargate service deployment"}, + {"step.ecs_destroy", "ECS Destroy", "Destroys an ECS Fargate service"}, + {"step.ecs_plan", "ECS Plan", "Plans ECS service deployment changes"}, + {"step.ecs_status", "ECS Status", "Gets the status of an ECS Fargate service"}, + {"step.git_checkout", "Git Checkout", "Checks out a Git branch, tag, or commit"}, + {"step.git_clone", "Git Clone", "Clones a Git repository"}, + {"step.git_commit", "Git Commit", "Creates a Git commit"}, + {"step.git_push", "Git Push", "Pushes commits to a remote repository"}, + {"step.git_tag", "Git Tag", "Creates a Git tag"}, + {"step.gitlab_create_mr", "GitLab Create MR", "Creates a GitLab merge request"}, + {"step.gitlab_mr_comment", "GitLab MR Comment", "Adds a comment to a GitLab merge request"}, + {"step.gitlab_parse_webhook", "GitLab Parse Webhook", "Parses and validates a GitLab webhook"}, + {"step.gitlab_pipeline_status", "GitLab Pipeline Status", "Gets the status of a GitLab pipeline"}, + {"step.gitlab_trigger_pipeline", "GitLab Trigger Pipeline", "Triggers a GitLab CI/CD pipeline"}, + {"step.iac_apply", "IaC Apply", "Applies infrastructure changes"}, + {"step.iac_destroy", "IaC Destroy", "Destroys IaC-managed infrastructure"}, + {"step.iac_drift_detect", "IaC Drift Detect", "Detects IaC configuration drift"}, + {"step.iac_plan", "IaC Plan", "Plans infrastructure changes without applying"}, + {"step.iac_status", "IaC Status", "Gets IaC provisioning status"}, + {"step.k8s_apply", "K8s Apply", "Applies Kubernetes manifests"}, + {"step.k8s_destroy", "K8s Destroy", "Deletes Kubernetes resources"}, + {"step.k8s_plan", "K8s Plan", "Diffs Kubernetes manifests against cluster state"}, + {"step.k8s_status", "K8s Status", "Gets the status of Kubernetes resources"}, + {"step.marketplace_detail", "Marketplace Detail", "Gets details about a marketplace plugin"}, + {"step.marketplace_install", "Marketplace Install", "Installs a marketplace plugin"}, + {"step.marketplace_installed", "Marketplace Installed", "Lists installed marketplace plugins"}, + {"step.marketplace_search", "Marketplace Search", "Searches the plugin marketplace"}, + {"step.marketplace_uninstall", "Marketplace Uninstall", "Uninstalls a marketplace plugin"}, + {"step.marketplace_update", "Marketplace Update", "Updates an installed marketplace plugin"}, + {"step.network_apply", "Network Apply", "Applies VPC networking changes"}, + {"step.network_plan", "Network Plan", "Plans VPC networking changes"}, + {"step.network_status", "Network Status", "Gets VPC networking status"}, + {"step.nosql_delete", "NoSQL Delete", "Deletes an item from a NoSQL store"}, + {"step.policy_evaluate", "Policy Evaluate", "Evaluates input against a policy"}, + {"step.policy_list", "Policy List", "Lists loaded policies"}, + {"step.policy_load", "Policy Load", "Loads a policy at runtime"}, + {"step.policy_test", "Policy Test", "Tests a policy against cases"}, + {"step.region_deploy", "Region Deploy", "Deploys to a specific region"}, + {"step.region_failover", "Region Failover", "Triggers regional failover"}, + {"step.region_promote", "Region Promote", "Promotes a region to primary"}, + {"step.region_status", "Region Status", "Gets multi-region health status"}, + {"step.region_sync", "Region Sync", "Syncs state across regions"}, + {"step.region_weight", "Region Weight", "Sets traffic weight for a region"}, + {"step.scaling_apply", "Scaling Apply", "Applies autoscaling policies"}, + {"step.scaling_destroy", "Scaling Destroy", "Removes autoscaling policies"}, + {"step.scaling_plan", "Scaling Plan", "Plans autoscaling changes"}, + {"step.scaling_status", "Scaling Status", "Gets autoscaling status"}, + {"step.secret_rotate", "Secret Rotate", "Rotates a secret"}, + {"step.trace_annotate", "Trace Annotate", "Adds attributes to the current trace span"}, + {"step.trace_extract", "Trace Extract", "Extracts trace context from incoming headers"}, + {"step.trace_inject", "Trace Inject", "Injects trace context into outgoing headers"}, + {"step.trace_link", "Trace Link", "Links the current span to another span"}, + {"step.trace_start", "Trace Start", "Starts a new trace span"}, + } { + r.Register(&ModuleSchema{ + Type: stepType.t, + Label: stepType.label, + Category: "pipeline", + Description: stepType.desc, + ConfigFields: []ConfigFieldDef{}, + }) + } } diff --git a/schema/schema.go b/schema/schema.go index 114ba609..b3c46271 100644 --- a/schema/schema.go +++ b/schema/schema.go @@ -143,13 +143,23 @@ func configFieldDefToSchema(f ConfigFieldDef) *Schema { // coreModuleTypes is the hardcoded list of built-in module type identifiers // recognized by the workflow engine's BuildFromConfig. var coreModuleTypes = []string{ + "actor.pool", + "actor.system", "api.command", "api.gateway", "api.handler", "api.query", + "app.container", + "argo.workflows", "auth.jwt", + "auth.m2m", + "auth.oauth2", + "auth.token-blacklist", "auth.user-store", + "aws.codebuild", "cache.modular", + "cache.redis", + "cloud.account", "config.provider", "data.transformer", "database.partitioned", @@ -158,11 +168,14 @@ var coreModuleTypes = []string{ "dynamic.component", "eventstore.service", "featureflag.service", + "gitlab.client", + "gitlab.webhook", "health.checker", "http.handler", "http.middleware.auth", "http.middleware.cors", "http.middleware.logging", + "http.middleware.otel", "http.middleware.ratelimit", "http.middleware.requestid", "http.middleware.securityheaders", @@ -170,6 +183,7 @@ var coreModuleTypes = []string{ "http.router", "http.server", "http.simple_proxy", + "iac.state", "jsonschema.modular", "license.validator", "log.collector", @@ -179,33 +193,73 @@ var coreModuleTypes = []string{ "messaging.kafka", "messaging.nats", "metrics.collector", + "nosql.dynamodb", + "nosql.memory", + "nosql.mongodb", + "nosql.redis", "notification.slack", "observability.otel", "openapi", "openapi.consumer", "openapi.generator", "persistence.store", + "platform.apigateway", + "platform.autoscaling", "platform.context", + "platform.dns", + "platform.do_app", + "platform.do_database", + "platform.do_dns", + "platform.do_networking", + "platform.doks", + "platform.ecs", + "platform.kubernetes", + "platform.networking", "platform.provider", + "platform.region", + "platform.region_router", "platform.resource", + "policy.mock", "processing.step", "reverseproxy", "scheduler.modular", "secrets.aws", "secrets.vault", + "security.field-protection", + "security.scanner", "state.connector", "state.tracker", "statemachine.engine", "static.fileserver", + "step.actor_ask", + "step.actor_send", "step.ai_classify", "step.ai_complete", "step.ai_extract", + "step.apigw_apply", + "step.apigw_destroy", + "step.apigw_plan", + "step.apigw_status", + "step.app_deploy", + "step.app_rollback", + "step.app_status", + "step.argo_delete", + "step.argo_list", + "step.argo_logs", + "step.argo_status", + "step.argo_submit", + "step.artifact_delete", + "step.artifact_download", + "step.artifact_list", "step.artifact_pull", "step.artifact_push", + "step.artifact_upload", "step.auth_required", "step.auth_validate", "step.authz_check", "step.base64_decode", + "step.build_binary", + "step.build_from_config", "step.build_ui", "step.cache_delete", "step.cache_get", @@ -213,6 +267,13 @@ var coreModuleTypes = []string{ "step.circuit_breaker", "step.cli_invoke", "step.cli_print", + "step.cloud_validate", + "step.codebuild_create_project", + "step.codebuild_delete_project", + "step.codebuild_list_builds", + "step.codebuild_logs", + "step.codebuild_start", + "step.codebuild_status", "step.conditional", "step.constraint_check", "step.db_create_partition", @@ -224,10 +285,22 @@ var coreModuleTypes = []string{ "step.deploy", "step.dlq_replay", "step.dlq_send", + "step.dns_apply", + "step.dns_plan", + "step.dns_status", + "step.do_deploy", + "step.do_destroy", + "step.do_logs", + "step.do_scale", + "step.do_status", "step.docker_build", "step.docker_push", "step.docker_run", "step.drift_check", + "step.ecs_apply", + "step.ecs_destroy", + "step.ecs_plan", + "step.ecs_status", "step.event_decrypt", "step.event_publish", "step.feature_flag", @@ -235,15 +308,44 @@ var coreModuleTypes = []string{ "step.field_reencrypt", "step.foreach", "step.gate", + "step.git_checkout", + "step.git_clone", + "step.git_commit", + "step.git_push", + "step.git_tag", + "step.gitlab_create_mr", + "step.gitlab_mr_comment", + "step.gitlab_parse_webhook", + "step.gitlab_pipeline_status", + "step.gitlab_trigger_pipeline", "step.graphql", "step.hash", "step.http_call", "step.http_proxy", + "step.iac_apply", + "step.iac_destroy", + "step.iac_drift_detect", + "step.iac_plan", + "step.iac_status", "step.jq", "step.json_parse", "step.json_response", + "step.k8s_apply", + "step.k8s_destroy", + "step.k8s_plan", + "step.k8s_status", "step.log", "step.m2m_token", + "step.marketplace_detail", + "step.marketplace_install", + "step.marketplace_installed", + "step.marketplace_search", + "step.marketplace_uninstall", + "step.marketplace_update", + "step.network_apply", + "step.network_plan", + "step.network_status", + "step.nosql_delete", "step.nosql_get", "step.nosql_put", "step.nosql_query", @@ -254,19 +356,34 @@ var coreModuleTypes = []string{ "step.platform_destroy", "step.platform_plan", "step.platform_template", + "step.policy_evaluate", + "step.policy_list", + "step.policy_load", + "step.policy_test", "step.publish", "step.rate_limit", "step.raw_response", "step.regex_match", + "step.region_deploy", + "step.region_failover", + "step.region_promote", + "step.region_status", + "step.region_sync", + "step.region_weight", "step.request_parse", "step.resilient_circuit_breaker", "step.retry_with_backoff", "step.s3_upload", "step.sandbox_exec", + "step.scaling_apply", + "step.scaling_destroy", + "step.scaling_plan", + "step.scaling_status", "step.scan_container", "step.scan_deps", "step.scan_sast", "step.secret_fetch", + "step.secret_rotate", "step.set", "step.shell_exec", "step.statemachine_get", @@ -274,6 +391,11 @@ var coreModuleTypes = []string{ "step.static_file", "step.sub_workflow", "step.token_revoke", + "step.trace_annotate", + "step.trace_extract", + "step.trace_inject", + "step.trace_link", + "step.trace_start", "step.transform", "step.ui_scaffold", "step.ui_scaffold_analyze", @@ -283,11 +405,13 @@ var coreModuleTypes = []string{ "step.validate_request_body", "step.webhook_verify", "step.workflow_call", + "storage.artifact", "storage.gcs", "storage.local", "storage.s3", "storage.sqlite", "timeline.service", + "tracing.propagation", "webhook.sender", "workflow.registry", } diff --git a/schema/step_schema_builtins.go b/schema/step_schema_builtins.go index abfec9cd..f960f9a1 100644 --- a/schema/step_schema_builtins.go +++ b/schema/step_schema_builtins.go @@ -1357,4 +1357,1400 @@ func (r *StepSchemaRegistry) registerBuiltins() { {Key: "headers", Type: "map", Description: "Backend response headers (when no HTTP writer)"}, }, }) + + // ---- Actor Send ---- + + r.Register(&StepSchema{ + Type: "step.actor_send", + Plugin: "actors", + Description: "Send a message to an actor without waiting for a response (fire-and-forget).", + ConfigFields: []ConfigFieldDef{ + {Key: "pool", Type: FieldTypeString, Description: "Name of the actor.pool module to send to", Required: true}, + {Key: "identity", Type: FieldTypeString, Description: "Unique key for auto-managed actors"}, + {Key: "message", Type: FieldTypeJSON, Description: "Message to send (must include 'type' field)", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "delivered", Type: "boolean", Description: "Whether the message was delivered"}, + }, + }) + + // ---- Actor Ask ---- + + r.Register(&StepSchema{ + Type: "step.actor_ask", + Plugin: "actors", + Description: "Send a message to an actor and wait for a response.", + ConfigFields: []ConfigFieldDef{ + {Key: "pool", Type: FieldTypeString, Description: "Name of the actor.pool module to send to", Required: true}, + {Key: "identity", Type: FieldTypeString, Description: "Unique key for auto-managed actors"}, + {Key: "timeout", Type: FieldTypeDuration, Description: "How long to wait for the actor's reply before failing", DefaultValue: "10s"}, + {Key: "message", Type: FieldTypeJSON, Description: "Message to send (must include 'type' field)", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "*", Type: "any", Description: "The actor's reply — varies by message handler"}, + }, + }) + + // ---- API Gateway Apply ---- + + r.Register(&StepSchema{ + Type: "step.apigw_apply", + Plugin: "platform", + Description: "Applies (provisions or updates) an API gateway configuration.", + ConfigFields: []ConfigFieldDef{ + {Key: "gateway", Type: FieldTypeString, Description: "Name of the platform.apigateway module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "id", Type: "string", Description: "API gateway ID"}, + {Key: "endpoint", Type: "string", Description: "Gateway endpoint URL"}, + }, + }) + + // ---- API Gateway Destroy ---- + + r.Register(&StepSchema{ + Type: "step.apigw_destroy", + Plugin: "platform", + Description: "Destroys a provisioned API gateway.", + ConfigFields: []ConfigFieldDef{ + {Key: "gateway", Type: FieldTypeString, Description: "Name of the platform.apigateway module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "destroyed", Type: "boolean", Description: "Whether the gateway was destroyed"}, + }, + }) + + // ---- API Gateway Plan ---- + + r.Register(&StepSchema{ + Type: "step.apigw_plan", + Plugin: "platform", + Description: "Plans API gateway changes without applying them.", + ConfigFields: []ConfigFieldDef{ + {Key: "gateway", Type: FieldTypeString, Description: "Name of the platform.apigateway module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "plan", Type: "string", Description: "Human-readable plan output"}, + {Key: "changes", Type: "number", Description: "Number of changes planned"}, + }, + }) + + // ---- API Gateway Status ---- + + r.Register(&StepSchema{ + Type: "step.apigw_status", + Plugin: "platform", + Description: "Gets the current status of an API gateway.", + ConfigFields: []ConfigFieldDef{ + {Key: "gateway", Type: FieldTypeString, Description: "Name of the platform.apigateway module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "status", Type: "string", Description: "Current gateway status"}, + {Key: "endpoint", Type: "string", Description: "Gateway endpoint URL"}, + }, + }) + + // ---- App Deploy ---- + + r.Register(&StepSchema{ + Type: "step.app_deploy", + Plugin: "platform", + Description: "Deploys an application container to the target platform.", + ConfigFields: []ConfigFieldDef{ + {Key: "app", Type: FieldTypeString, Description: "Name of the app.container module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "deployed", Type: "boolean", Description: "Whether deployment succeeded"}, + {Key: "endpoint", Type: "string", Description: "Service endpoint after deployment"}, + }, + }) + + // ---- App Rollback ---- + + r.Register(&StepSchema{ + Type: "step.app_rollback", + Plugin: "platform", + Description: "Rolls back an application container to a previous version.", + ConfigFields: []ConfigFieldDef{ + {Key: "app", Type: FieldTypeString, Description: "Name of the app.container module", Required: true}, + {Key: "revision", Type: FieldTypeString, Description: "Target revision to roll back to (empty = previous)"}, + }, + Outputs: []StepOutputDef{ + {Key: "rolled_back", Type: "boolean", Description: "Whether rollback succeeded"}, + }, + }) + + // ---- App Status ---- + + r.Register(&StepSchema{ + Type: "step.app_status", + Plugin: "platform", + Description: "Gets the current deployment status of an application container.", + ConfigFields: []ConfigFieldDef{ + {Key: "app", Type: FieldTypeString, Description: "Name of the app.container module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "status", Type: "string", Description: "Deployment status"}, + {Key: "replicas", Type: "number", Description: "Current replica count"}, + }, + }) + + // ---- Argo Delete ---- + + r.Register(&StepSchema{ + Type: "step.argo_delete", + Plugin: "platform", + Description: "Deletes an Argo Workflow.", + ConfigFields: []ConfigFieldDef{ + {Key: "service", Type: FieldTypeString, Description: "Name of the argo.workflows module", Required: true}, + {Key: "workflow_run", Type: FieldTypeString, Description: "Workflow run name to delete"}, + }, + Outputs: []StepOutputDef{ + {Key: "deleted", Type: "boolean", Description: "Whether the workflow was deleted"}, + }, + }) + + // ---- Argo List ---- + + r.Register(&StepSchema{ + Type: "step.argo_list", + Plugin: "platform", + Description: "Lists Argo Workflows in a namespace.", + ConfigFields: []ConfigFieldDef{ + {Key: "service", Type: FieldTypeString, Description: "Name of the argo.workflows module", Required: true}, + {Key: "label_selector", Type: FieldTypeString, Description: "Label selector filter"}, + }, + Outputs: []StepOutputDef{ + {Key: "workflows", Type: "[]any", Description: "List of workflows"}, + {Key: "count", Type: "number", Description: "Number of workflows"}, + }, + }) + + // ---- Argo Logs ---- + + r.Register(&StepSchema{ + Type: "step.argo_logs", + Plugin: "platform", + Description: "Retrieves logs from an Argo Workflow.", + ConfigFields: []ConfigFieldDef{ + {Key: "service", Type: FieldTypeString, Description: "Name of the argo.workflows module", Required: true}, + {Key: "workflow_run", Type: FieldTypeString, Description: "Workflow run name to get logs for"}, + }, + Outputs: []StepOutputDef{ + {Key: "logs", Type: "string", Description: "Workflow logs"}, + }, + }) + + // ---- Argo Status ---- + + r.Register(&StepSchema{ + Type: "step.argo_status", + Plugin: "platform", + Description: "Gets the status of an Argo Workflow.", + ConfigFields: []ConfigFieldDef{ + {Key: "service", Type: FieldTypeString, Description: "Name of the argo.workflows module", Required: true}, + {Key: "workflow_run", Type: FieldTypeString, Description: "Workflow run name to check status"}, + }, + Outputs: []StepOutputDef{ + {Key: "phase", Type: "string", Description: "Workflow phase (Pending, Running, Succeeded, Failed)"}, + {Key: "message", Type: "string", Description: "Status message"}, + }, + }) + + // ---- Argo Submit ---- + + r.Register(&StepSchema{ + Type: "step.argo_submit", + Plugin: "platform", + Description: "Submits an Argo Workflow from a template or manifest.", + ConfigFields: []ConfigFieldDef{ + {Key: "service", Type: FieldTypeString, Description: "Name of the argo.workflows module", Required: true}, + {Key: "workflow_name", Type: FieldTypeString, Description: "Workflow template name (defaults to step name)"}, + {Key: "steps", Type: FieldTypeArray, Description: "Workflow step definitions"}, + }, + Outputs: []StepOutputDef{ + {Key: "name", Type: "string", Description: "Created workflow name"}, + {Key: "namespace", Type: "string", Description: "Workflow namespace"}, + }, + }) + + // ---- Artifact Delete ---- + + r.Register(&StepSchema{ + Type: "step.artifact_delete", + Plugin: "storage", + Description: "Deletes an artifact from the artifact store.", + ConfigFields: []ConfigFieldDef{ + {Key: "store", Type: FieldTypeString, Description: "Name of the storage.artifact module", Required: true}, + {Key: "key", Type: FieldTypeString, Description: "Artifact key to delete", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "deleted", Type: "boolean", Description: "Whether the artifact was deleted"}, + }, + }) + + // ---- Artifact Download ---- + + r.Register(&StepSchema{ + Type: "step.artifact_download", + Plugin: "storage", + Description: "Downloads an artifact from the artifact store.", + ConfigFields: []ConfigFieldDef{ + {Key: "store", Type: FieldTypeString, Description: "Name of the storage.artifact module", Required: true}, + {Key: "key", Type: FieldTypeString, Description: "Artifact key to download", Required: true}, + {Key: "dest", Type: FieldTypeString, Description: "Local path to write the artifact"}, + }, + Outputs: []StepOutputDef{ + {Key: "path", Type: "string", Description: "Local path where artifact was written"}, + {Key: "size", Type: "number", Description: "Artifact size in bytes"}, + }, + }) + + // ---- Artifact List ---- + + r.Register(&StepSchema{ + Type: "step.artifact_list", + Plugin: "storage", + Description: "Lists artifacts in the artifact store.", + ConfigFields: []ConfigFieldDef{ + {Key: "store", Type: FieldTypeString, Description: "Name of the storage.artifact module", Required: true}, + {Key: "prefix", Type: FieldTypeString, Description: "Optional prefix filter"}, + }, + Outputs: []StepOutputDef{ + {Key: "artifacts", Type: "[]any", Description: "List of artifact metadata"}, + {Key: "count", Type: "number", Description: "Number of artifacts"}, + }, + }) + + // ---- Artifact Upload ---- + + r.Register(&StepSchema{ + Type: "step.artifact_upload", + Plugin: "storage", + Description: "Uploads a file as an artifact to the artifact store.", + ConfigFields: []ConfigFieldDef{ + {Key: "store", Type: FieldTypeString, Description: "Name of the storage.artifact module", Required: true}, + {Key: "key", Type: FieldTypeString, Description: "Artifact key (storage path)", Required: true}, + {Key: "source", Type: FieldTypeString, Description: "Local file path to upload", Required: true}, + {Key: "metadata", Type: FieldTypeMap, Description: "Additional metadata to attach"}, + }, + Outputs: []StepOutputDef{ + {Key: "key", Type: "string", Description: "Stored artifact key"}, + {Key: "store", Type: "string", Description: "Name of the store used"}, + }, + }) + + // ---- Build Binary ---- + + r.Register(&StepSchema{ + Type: "step.build_binary", + Plugin: "cicd", + Description: "Builds a Go binary from source.", + ConfigFields: []ConfigFieldDef{ + {Key: "source", Type: FieldTypeString, Description: "Source directory or package path", Required: true}, + {Key: "output", Type: FieldTypeString, Description: "Output binary path"}, + {Key: "os", Type: FieldTypeString, Description: "Target OS (GOOS)"}, + {Key: "arch", Type: FieldTypeString, Description: "Target architecture (GOARCH)"}, + {Key: "ldflags", Type: FieldTypeString, Description: "Linker flags"}, + }, + Outputs: []StepOutputDef{ + {Key: "binary_path", Type: "string", Description: "Path to the built binary"}, + }, + }) + + // ---- Build From Config ---- + + r.Register(&StepSchema{ + Type: "step.build_from_config", + Plugin: "cicd", + Description: "Builds an application using the workflow engine config as build specification.", + ConfigFields: []ConfigFieldDef{ + {Key: "config", Type: FieldTypeString, Description: "Path to build config file", Required: true}, + {Key: "target", Type: FieldTypeString, Description: "Build target name"}, + }, + Outputs: []StepOutputDef{ + {Key: "artifact", Type: "string", Description: "Path to the built artifact"}, + {Key: "success", Type: "boolean", Description: "Whether the build succeeded"}, + }, + }) + + // ---- Cloud Validate ---- + + r.Register(&StepSchema{ + Type: "step.cloud_validate", + Plugin: "cloud", + Description: "Validates cloud provider credentials and connectivity.", + ConfigFields: []ConfigFieldDef{ + {Key: "account", Type: FieldTypeString, Description: "Name of the cloud.account module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "valid", Type: "boolean", Description: "Whether credentials are valid"}, + {Key: "provider", Type: "string", Description: "Cloud provider name"}, + {Key: "region", Type: "string", Description: "Configured region"}, + }, + }) + + // ---- CodeBuild Create Project ---- + + r.Register(&StepSchema{ + Type: "step.codebuild_create_project", + Plugin: "cicd", + Description: "Creates an AWS CodeBuild project.", + ConfigFields: []ConfigFieldDef{ + {Key: "project", Type: FieldTypeString, Description: "Name of the aws.codebuild module", Required: true}, + {Key: "project_name", Type: FieldTypeString, Description: "CodeBuild project name", Required: true}, + {Key: "source", Type: FieldTypeMap, Description: "Source configuration (type, location)"}, + {Key: "environment", Type: FieldTypeMap, Description: "Build environment configuration"}, + }, + Outputs: []StepOutputDef{ + {Key: "project_name", Type: "string", Description: "Created project name"}, + {Key: "arn", Type: "string", Description: "Project ARN"}, + }, + }) + + // ---- CodeBuild Delete Project ---- + + r.Register(&StepSchema{ + Type: "step.codebuild_delete_project", + Plugin: "cicd", + Description: "Deletes an AWS CodeBuild project.", + ConfigFields: []ConfigFieldDef{ + {Key: "project", Type: FieldTypeString, Description: "Name of the aws.codebuild module", Required: true}, + {Key: "project_name", Type: FieldTypeString, Description: "CodeBuild project name to delete", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "deleted", Type: "boolean", Description: "Whether the project was deleted"}, + }, + }) + + // ---- CodeBuild List Builds ---- + + r.Register(&StepSchema{ + Type: "step.codebuild_list_builds", + Plugin: "cicd", + Description: "Lists builds for an AWS CodeBuild project.", + ConfigFields: []ConfigFieldDef{ + {Key: "project", Type: FieldTypeString, Description: "Name of the aws.codebuild module", Required: true}, + {Key: "project_name", Type: FieldTypeString, Description: "CodeBuild project name", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "builds", Type: "[]any", Description: "List of build IDs"}, + {Key: "count", Type: "number", Description: "Number of builds"}, + }, + }) + + // ---- CodeBuild Logs ---- + + r.Register(&StepSchema{ + Type: "step.codebuild_logs", + Plugin: "cicd", + Description: "Retrieves logs for an AWS CodeBuild build.", + ConfigFields: []ConfigFieldDef{ + {Key: "project", Type: FieldTypeString, Description: "Name of the aws.codebuild module", Required: true}, + {Key: "build_id", Type: FieldTypeString, Description: "CodeBuild build ID", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "logs", Type: "string", Description: "Build log output"}, + }, + }) + + // ---- CodeBuild Start ---- + + r.Register(&StepSchema{ + Type: "step.codebuild_start", + Plugin: "cicd", + Description: "Starts an AWS CodeBuild build.", + ConfigFields: []ConfigFieldDef{ + {Key: "project", Type: FieldTypeString, Description: "Name of the aws.codebuild module", Required: true}, + {Key: "project_name", Type: FieldTypeString, Description: "CodeBuild project name", Required: true}, + {Key: "env_override", Type: FieldTypeMap, Description: "Environment variable overrides"}, + }, + Outputs: []StepOutputDef{ + {Key: "build_id", Type: "string", Description: "Started build ID"}, + {Key: "status", Type: "string", Description: "Initial build status"}, + }, + }) + + // ---- CodeBuild Status ---- + + r.Register(&StepSchema{ + Type: "step.codebuild_status", + Plugin: "cicd", + Description: "Gets the status of an AWS CodeBuild build.", + ConfigFields: []ConfigFieldDef{ + {Key: "project", Type: FieldTypeString, Description: "Name of the aws.codebuild module", Required: true}, + {Key: "build_id", Type: FieldTypeString, Description: "CodeBuild build ID", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "status", Type: "string", Description: "Build status (IN_PROGRESS, SUCCEEDED, FAILED, etc.)"}, + {Key: "phase", Type: "string", Description: "Current build phase"}, + }, + }) + + // ---- DNS Apply ---- + + r.Register(&StepSchema{ + Type: "step.dns_apply", + Plugin: "platform", + Description: "Applies DNS zone and record changes.", + ConfigFields: []ConfigFieldDef{ + {Key: "zone", Type: FieldTypeString, Description: "Name of the platform.dns module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "zone_id", Type: "string", Description: "DNS zone ID"}, + {Key: "nameservers", Type: "[]string", Description: "Zone nameservers"}, + }, + }) + + // ---- DNS Plan ---- + + r.Register(&StepSchema{ + Type: "step.dns_plan", + Plugin: "platform", + Description: "Plans DNS changes without applying them.", + ConfigFields: []ConfigFieldDef{ + {Key: "zone", Type: FieldTypeString, Description: "Name of the platform.dns module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "plan", Type: "string", Description: "Human-readable plan output"}, + {Key: "changes", Type: "number", Description: "Number of changes planned"}, + }, + }) + + // ---- DNS Status ---- + + r.Register(&StepSchema{ + Type: "step.dns_status", + Plugin: "platform", + Description: "Gets the current status of a DNS zone.", + ConfigFields: []ConfigFieldDef{ + {Key: "zone", Type: FieldTypeString, Description: "Name of the platform.dns module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "status", Type: "string", Description: "Zone status"}, + {Key: "zone_id", Type: "string", Description: "DNS zone ID"}, + }, + }) + + // ---- DigitalOcean Deploy ---- + + r.Register(&StepSchema{ + Type: "step.do_deploy", + Plugin: "platform", + Description: "Deploys an application to DigitalOcean App Platform.", + ConfigFields: []ConfigFieldDef{ + {Key: "app", Type: FieldTypeString, Description: "Name of the platform.do_app module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "app_id", Type: "string", Description: "DigitalOcean app ID"}, + {Key: "live_url", Type: "string", Description: "App live URL"}, + }, + }) + + // ---- DigitalOcean Destroy ---- + + r.Register(&StepSchema{ + Type: "step.do_destroy", + Plugin: "platform", + Description: "Destroys a DigitalOcean App Platform application.", + ConfigFields: []ConfigFieldDef{ + {Key: "app", Type: FieldTypeString, Description: "Name of the platform.do_app module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "destroyed", Type: "boolean", Description: "Whether the app was destroyed"}, + }, + }) + + // ---- DigitalOcean Logs ---- + + r.Register(&StepSchema{ + Type: "step.do_logs", + Plugin: "platform", + Description: "Retrieves logs from a DigitalOcean App Platform application.", + ConfigFields: []ConfigFieldDef{ + {Key: "app", Type: FieldTypeString, Description: "Name of the platform.do_app module", Required: true}, + {Key: "component", Type: FieldTypeString, Description: "App component name"}, + }, + Outputs: []StepOutputDef{ + {Key: "logs", Type: "string", Description: "Application log output"}, + }, + }) + + // ---- DigitalOcean Scale ---- + + r.Register(&StepSchema{ + Type: "step.do_scale", + Plugin: "platform", + Description: "Scales a DigitalOcean App Platform application.", + ConfigFields: []ConfigFieldDef{ + {Key: "app", Type: FieldTypeString, Description: "Name of the platform.do_app module", Required: true}, + {Key: "instances", Type: FieldTypeNumber, Description: "Desired instance count", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "instances", Type: "number", Description: "New instance count"}, + }, + }) + + // ---- DigitalOcean Status ---- + + r.Register(&StepSchema{ + Type: "step.do_status", + Plugin: "platform", + Description: "Gets the status of a DigitalOcean App Platform application.", + ConfigFields: []ConfigFieldDef{ + {Key: "app", Type: FieldTypeString, Description: "Name of the platform.do_app module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "phase", Type: "string", Description: "App deployment phase"}, + {Key: "live_url", Type: "string", Description: "App live URL"}, + }, + }) + + // ---- ECS Apply ---- + + r.Register(&StepSchema{ + Type: "step.ecs_apply", + Plugin: "platform", + Description: "Applies (deploys) an ECS Fargate service.", + ConfigFields: []ConfigFieldDef{ + {Key: "service", Type: FieldTypeString, Description: "Name of the platform.ecs module", Required: true}, + {Key: "image", Type: FieldTypeString, Description: "Container image to deploy"}, + }, + Outputs: []StepOutputDef{ + {Key: "service_arn", Type: "string", Description: "ECS service ARN"}, + {Key: "status", Type: "string", Description: "Service status"}, + }, + }) + + // ---- ECS Destroy ---- + + r.Register(&StepSchema{ + Type: "step.ecs_destroy", + Plugin: "platform", + Description: "Destroys an ECS Fargate service.", + ConfigFields: []ConfigFieldDef{ + {Key: "service", Type: FieldTypeString, Description: "Name of the platform.ecs module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "destroyed", Type: "boolean", Description: "Whether the service was destroyed"}, + }, + }) + + // ---- ECS Plan ---- + + r.Register(&StepSchema{ + Type: "step.ecs_plan", + Plugin: "platform", + Description: "Plans ECS service deployment changes without applying them.", + ConfigFields: []ConfigFieldDef{ + {Key: "service", Type: FieldTypeString, Description: "Name of the platform.ecs module", Required: true}, + {Key: "image", Type: FieldTypeString, Description: "Container image to plan for"}, + }, + Outputs: []StepOutputDef{ + {Key: "plan", Type: "string", Description: "Human-readable plan output"}, + {Key: "changes", Type: "number", Description: "Number of changes planned"}, + }, + }) + + // ---- ECS Status ---- + + r.Register(&StepSchema{ + Type: "step.ecs_status", + Plugin: "platform", + Description: "Gets the status of an ECS Fargate service.", + ConfigFields: []ConfigFieldDef{ + {Key: "service", Type: FieldTypeString, Description: "Name of the platform.ecs module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "status", Type: "string", Description: "Service status"}, + {Key: "running_count", Type: "number", Description: "Number of running tasks"}, + }, + }) + + // ---- Git Checkout ---- + + r.Register(&StepSchema{ + Type: "step.git_checkout", + Plugin: "cicd", + Description: "Checks out a Git branch, tag, or commit.", + ConfigFields: []ConfigFieldDef{ + {Key: "path", Type: FieldTypeString, Description: "Local repository path", Required: true}, + {Key: "ref", Type: FieldTypeString, Description: "Branch, tag, or commit SHA to checkout", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "commit", Type: "string", Description: "HEAD commit SHA after checkout"}, + {Key: "branch", Type: "string", Description: "Current branch name"}, + }, + }) + + // ---- Git Clone ---- + + r.Register(&StepSchema{ + Type: "step.git_clone", + Plugin: "cicd", + Description: "Clones a Git repository to a local path.", + ConfigFields: []ConfigFieldDef{ + {Key: "url", Type: FieldTypeString, Description: "Repository URL to clone", Required: true}, + {Key: "path", Type: FieldTypeString, Description: "Local path to clone into", Required: true}, + {Key: "branch", Type: FieldTypeString, Description: "Branch to clone (default: main)"}, + {Key: "depth", Type: FieldTypeNumber, Description: "Clone depth (0 = full history)"}, + {Key: "token", Type: FieldTypeString, Description: "Auth token for private repos", Sensitive: true}, + }, + Outputs: []StepOutputDef{ + {Key: "commit", Type: "string", Description: "HEAD commit SHA"}, + {Key: "path", Type: "string", Description: "Local path where repo was cloned"}, + }, + }) + + // ---- Git Commit ---- + + r.Register(&StepSchema{ + Type: "step.git_commit", + Plugin: "cicd", + Description: "Creates a Git commit with staged changes.", + ConfigFields: []ConfigFieldDef{ + {Key: "path", Type: FieldTypeString, Description: "Local repository path", Required: true}, + {Key: "message", Type: FieldTypeString, Description: "Commit message", Required: true}, + {Key: "author_name", Type: FieldTypeString, Description: "Commit author name"}, + {Key: "author_email", Type: FieldTypeString, Description: "Commit author email"}, + {Key: "add_all", Type: FieldTypeBool, Description: "Stage all changes before committing"}, + }, + Outputs: []StepOutputDef{ + {Key: "sha", Type: "string", Description: "New commit SHA"}, + }, + }) + + // ---- Git Push ---- + + r.Register(&StepSchema{ + Type: "step.git_push", + Plugin: "cicd", + Description: "Pushes local commits to a remote Git repository.", + ConfigFields: []ConfigFieldDef{ + {Key: "path", Type: FieldTypeString, Description: "Local repository path", Required: true}, + {Key: "remote", Type: FieldTypeString, Description: "Remote name (default: origin)", DefaultValue: "origin"}, + {Key: "branch", Type: FieldTypeString, Description: "Branch to push"}, + {Key: "token", Type: FieldTypeString, Description: "Auth token for private repos", Sensitive: true}, + {Key: "force", Type: FieldTypeBool, Description: "Force push"}, + }, + Outputs: []StepOutputDef{ + {Key: "pushed", Type: "boolean", Description: "Whether push succeeded"}, + }, + }) + + // ---- Git Tag ---- + + r.Register(&StepSchema{ + Type: "step.git_tag", + Plugin: "cicd", + Description: "Creates a Git tag on the current commit.", + ConfigFields: []ConfigFieldDef{ + {Key: "path", Type: FieldTypeString, Description: "Local repository path", Required: true}, + {Key: "tag", Type: FieldTypeString, Description: "Tag name to create", Required: true}, + {Key: "message", Type: FieldTypeString, Description: "Annotated tag message (empty = lightweight tag)"}, + {Key: "push", Type: FieldTypeBool, Description: "Push tag to remote after creating"}, + }, + Outputs: []StepOutputDef{ + {Key: "tag", Type: "string", Description: "Created tag name"}, + {Key: "sha", Type: "string", Description: "Tagged commit SHA"}, + }, + }) + + // ---- GitLab Create MR ---- + + r.Register(&StepSchema{ + Type: "step.gitlab_create_mr", + Plugin: "gitlab", + Description: "Creates a GitLab merge request.", + ConfigFields: []ConfigFieldDef{ + {Key: "client", Type: FieldTypeString, Description: "Name of the gitlab.client module", Required: true}, + {Key: "project_id", Type: FieldTypeString, Description: "GitLab project ID or path", Required: true}, + {Key: "source_branch", Type: FieldTypeString, Description: "Source branch for the MR", Required: true}, + {Key: "target_branch", Type: FieldTypeString, Description: "Target branch for the MR", Required: true}, + {Key: "title", Type: FieldTypeString, Description: "MR title", Required: true}, + {Key: "description", Type: FieldTypeString, Description: "MR description"}, + }, + Outputs: []StepOutputDef{ + {Key: "iid", Type: "number", Description: "Merge request internal ID"}, + {Key: "url", Type: "string", Description: "Merge request URL"}, + }, + }) + + // ---- GitLab MR Comment ---- + + r.Register(&StepSchema{ + Type: "step.gitlab_mr_comment", + Plugin: "gitlab", + Description: "Adds a comment to a GitLab merge request.", + ConfigFields: []ConfigFieldDef{ + {Key: "client", Type: FieldTypeString, Description: "Name of the gitlab.client module", Required: true}, + {Key: "project_id", Type: FieldTypeString, Description: "GitLab project ID or path", Required: true}, + {Key: "mr_iid", Type: FieldTypeNumber, Description: "Merge request internal ID", Required: true}, + {Key: "body", Type: FieldTypeString, Description: "Comment body text", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "note_id", Type: "number", Description: "Created note ID"}, + }, + }) + + // ---- GitLab Parse Webhook ---- + + r.Register(&StepSchema{ + Type: "step.gitlab_parse_webhook", + Plugin: "gitlab", + Description: "Parses and validates a GitLab webhook payload.", + ConfigFields: []ConfigFieldDef{ + {Key: "webhook", Type: FieldTypeString, Description: "Name of the gitlab.webhook module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "event_type", Type: "string", Description: "GitLab event type (push, tag, merge_request, etc.)"}, + {Key: "project_id", Type: "number", Description: "GitLab project ID"}, + {Key: "payload", Type: "any", Description: "Parsed webhook payload"}, + }, + }) + + // ---- GitLab Pipeline Status ---- + + r.Register(&StepSchema{ + Type: "step.gitlab_pipeline_status", + Plugin: "gitlab", + Description: "Gets the status of a GitLab pipeline.", + ConfigFields: []ConfigFieldDef{ + {Key: "client", Type: FieldTypeString, Description: "Name of the gitlab.client module", Required: true}, + {Key: "project_id", Type: FieldTypeString, Description: "GitLab project ID or path", Required: true}, + {Key: "pipeline_id", Type: FieldTypeNumber, Description: "Pipeline ID", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "status", Type: "string", Description: "Pipeline status (running, success, failed, etc.)"}, + {Key: "url", Type: "string", Description: "Pipeline web URL"}, + }, + }) + + // ---- GitLab Trigger Pipeline ---- + + r.Register(&StepSchema{ + Type: "step.gitlab_trigger_pipeline", + Plugin: "gitlab", + Description: "Triggers a GitLab CI/CD pipeline.", + ConfigFields: []ConfigFieldDef{ + {Key: "client", Type: FieldTypeString, Description: "Name of the gitlab.client module", Required: true}, + {Key: "project_id", Type: FieldTypeString, Description: "GitLab project ID or path", Required: true}, + {Key: "ref", Type: FieldTypeString, Description: "Branch or tag to run pipeline on", Required: true}, + {Key: "variables", Type: FieldTypeMap, Description: "Pipeline variables to pass"}, + }, + Outputs: []StepOutputDef{ + {Key: "pipeline_id", Type: "number", Description: "Triggered pipeline ID"}, + {Key: "status", Type: "string", Description: "Initial pipeline status"}, + {Key: "url", Type: "string", Description: "Pipeline web URL"}, + }, + }) + + // ---- IaC Apply ---- + + r.Register(&StepSchema{ + Type: "step.iac_apply", + Plugin: "platform", + Description: "Applies infrastructure changes from an IaC plan.", + ConfigFields: []ConfigFieldDef{ + {Key: "platform", Type: FieldTypeString, Description: "Name of the platform module", Required: true}, + {Key: "resource_id", Type: FieldTypeString, Description: "Resource ID to manage"}, + {Key: "state_store", Type: FieldTypeString, Description: "Name of the iac.state module for state backend"}, + }, + Outputs: []StepOutputDef{ + {Key: "applied", Type: "boolean", Description: "Whether changes were applied"}, + {Key: "resources", Type: "[]any", Description: "Applied resource details"}, + }, + }) + + // ---- IaC Destroy ---- + + r.Register(&StepSchema{ + Type: "step.iac_destroy", + Plugin: "platform", + Description: "Destroys infrastructure managed by an IaC module.", + ConfigFields: []ConfigFieldDef{ + {Key: "platform", Type: FieldTypeString, Description: "Name of the platform module", Required: true}, + {Key: "resource_id", Type: FieldTypeString, Description: "Resource ID to destroy"}, + {Key: "state_store", Type: FieldTypeString, Description: "Name of the iac.state module for state backend"}, + }, + Outputs: []StepOutputDef{ + {Key: "destroyed", Type: "boolean", Description: "Whether resources were destroyed"}, + }, + }) + + // ---- IaC Drift Detect ---- + + r.Register(&StepSchema{ + Type: "step.iac_drift_detect", + Plugin: "platform", + Description: "Detects configuration drift between IaC state and actual infrastructure.", + ConfigFields: []ConfigFieldDef{ + {Key: "platform", Type: FieldTypeString, Description: "Name of the platform module", Required: true}, + {Key: "resource_id", Type: FieldTypeString, Description: "Resource ID to check"}, + {Key: "state_store", Type: FieldTypeString, Description: "Name of the iac.state module for state backend"}, + {Key: "config", Type: FieldTypeMap, Description: "Current config to compare against state"}, + }, + Outputs: []StepOutputDef{ + {Key: "has_drift", Type: "boolean", Description: "Whether drift was detected"}, + {Key: "drifted_resources", Type: "[]any", Description: "List of drifted resources"}, + }, + }) + + // ---- IaC Plan ---- + + r.Register(&StepSchema{ + Type: "step.iac_plan", + Plugin: "platform", + Description: "Plans infrastructure changes without applying them.", + ConfigFields: []ConfigFieldDef{ + {Key: "platform", Type: FieldTypeString, Description: "Name of the platform module", Required: true}, + {Key: "resource_id", Type: FieldTypeString, Description: "Resource ID to plan"}, + {Key: "state_store", Type: FieldTypeString, Description: "Name of the iac.state module for state backend"}, + }, + Outputs: []StepOutputDef{ + {Key: "plan", Type: "string", Description: "Human-readable plan output"}, + {Key: "changes", Type: "number", Description: "Number of changes planned"}, + }, + }) + + // ---- IaC Status ---- + + r.Register(&StepSchema{ + Type: "step.iac_status", + Plugin: "platform", + Description: "Gets the current provisioning status of IaC-managed infrastructure.", + ConfigFields: []ConfigFieldDef{ + {Key: "platform", Type: FieldTypeString, Description: "Name of the platform module", Required: true}, + {Key: "resource_id", Type: FieldTypeString, Description: "Resource ID to query"}, + {Key: "state_store", Type: FieldTypeString, Description: "Name of the iac.state module for state backend"}, + }, + Outputs: []StepOutputDef{ + {Key: "status", Type: "string", Description: "Provisioning status"}, + {Key: "resources", Type: "[]any", Description: "Managed resource states"}, + }, + }) + + // ---- Kubernetes Apply ---- + + r.Register(&StepSchema{ + Type: "step.k8s_apply", + Plugin: "platform", + Description: "Applies Kubernetes manifests to a cluster.", + ConfigFields: []ConfigFieldDef{ + {Key: "cluster", Type: FieldTypeString, Description: "Name of the platform.kubernetes module", Required: true}, + {Key: "manifest", Type: FieldTypeString, Description: "YAML manifest or path to manifest file"}, + {Key: "namespace", Type: FieldTypeString, Description: "Kubernetes namespace"}, + }, + Outputs: []StepOutputDef{ + {Key: "applied", Type: "boolean", Description: "Whether manifests were applied"}, + {Key: "resources", Type: "[]any", Description: "Applied resource summaries"}, + }, + }) + + // ---- Kubernetes Destroy ---- + + r.Register(&StepSchema{ + Type: "step.k8s_destroy", + Plugin: "platform", + Description: "Deletes Kubernetes resources.", + ConfigFields: []ConfigFieldDef{ + {Key: "cluster", Type: FieldTypeString, Description: "Name of the platform.kubernetes module", Required: true}, + {Key: "manifest", Type: FieldTypeString, Description: "YAML manifest or path to manifest file"}, + {Key: "namespace", Type: FieldTypeString, Description: "Kubernetes namespace"}, + }, + Outputs: []StepOutputDef{ + {Key: "destroyed", Type: "boolean", Description: "Whether resources were deleted"}, + }, + }) + + // ---- Kubernetes Plan ---- + + r.Register(&StepSchema{ + Type: "step.k8s_plan", + Plugin: "platform", + Description: "Diffs Kubernetes manifests against the current cluster state.", + ConfigFields: []ConfigFieldDef{ + {Key: "cluster", Type: FieldTypeString, Description: "Name of the platform.kubernetes module", Required: true}, + {Key: "manifest", Type: FieldTypeString, Description: "YAML manifest or path to manifest file"}, + {Key: "namespace", Type: FieldTypeString, Description: "Kubernetes namespace"}, + }, + Outputs: []StepOutputDef{ + {Key: "diff", Type: "string", Description: "Diff output"}, + {Key: "changes", Type: "number", Description: "Number of changes detected"}, + }, + }) + + // ---- Kubernetes Status ---- + + r.Register(&StepSchema{ + Type: "step.k8s_status", + Plugin: "platform", + Description: "Gets the status of Kubernetes resources.", + ConfigFields: []ConfigFieldDef{ + {Key: "cluster", Type: FieldTypeString, Description: "Name of the platform.kubernetes module", Required: true}, + {Key: "kind", Type: FieldTypeString, Description: "Resource kind (Deployment, Service, etc.)"}, + {Key: "name", Type: FieldTypeString, Description: "Resource name"}, + {Key: "namespace", Type: FieldTypeString, Description: "Kubernetes namespace"}, + }, + Outputs: []StepOutputDef{ + {Key: "status", Type: "string", Description: "Resource status"}, + {Key: "ready", Type: "boolean", Description: "Whether resource is ready"}, + }, + }) + + // ---- Marketplace Detail ---- + + r.Register(&StepSchema{ + Type: "step.marketplace_detail", + Plugin: "marketplace", + Description: "Gets detailed information about a marketplace plugin.", + ConfigFields: []ConfigFieldDef{ + {Key: "plugin", Type: FieldTypeString, Description: "Plugin name to get details for", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "plugin", Type: "any", Description: "Plugin metadata and details"}, + }, + }) + + // ---- Marketplace Install ---- + + r.Register(&StepSchema{ + Type: "step.marketplace_install", + Plugin: "marketplace", + Description: "Installs a plugin from the marketplace.", + ConfigFields: []ConfigFieldDef{ + {Key: "plugin", Type: FieldTypeString, Description: "Plugin name to install", Required: true}, + {Key: "version", Type: FieldTypeString, Description: "Plugin version (default: latest)"}, + }, + Outputs: []StepOutputDef{ + {Key: "installed", Type: "boolean", Description: "Whether installation succeeded"}, + {Key: "version", Type: "string", Description: "Installed plugin version"}, + }, + }) + + // ---- Marketplace Installed ---- + + r.Register(&StepSchema{ + Type: "step.marketplace_installed", + Plugin: "marketplace", + Description: "Lists installed marketplace plugins.", + ConfigFields: []ConfigFieldDef{}, + Outputs: []StepOutputDef{ + {Key: "plugins", Type: "[]any", Description: "List of installed plugin metadata"}, + {Key: "count", Type: "number", Description: "Number of installed plugins"}, + }, + }) + + // ---- Marketplace Search ---- + + r.Register(&StepSchema{ + Type: "step.marketplace_search", + Plugin: "marketplace", + Description: "Searches the plugin marketplace.", + ConfigFields: []ConfigFieldDef{ + {Key: "query", Type: FieldTypeString, Description: "Search query string"}, + {Key: "category", Type: FieldTypeString, Description: "Filter by category"}, + }, + Outputs: []StepOutputDef{ + {Key: "results", Type: "[]any", Description: "Search result plugins"}, + {Key: "count", Type: "number", Description: "Number of results"}, + }, + }) + + // ---- Marketplace Uninstall ---- + + r.Register(&StepSchema{ + Type: "step.marketplace_uninstall", + Plugin: "marketplace", + Description: "Uninstalls a marketplace plugin.", + ConfigFields: []ConfigFieldDef{ + {Key: "plugin", Type: FieldTypeString, Description: "Plugin name to uninstall", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "uninstalled", Type: "boolean", Description: "Whether uninstall succeeded"}, + }, + }) + + // ---- Marketplace Update ---- + + r.Register(&StepSchema{ + Type: "step.marketplace_update", + Plugin: "marketplace", + Description: "Updates an installed marketplace plugin to a newer version.", + ConfigFields: []ConfigFieldDef{ + {Key: "plugin", Type: FieldTypeString, Description: "Plugin name to update", Required: true}, + {Key: "version", Type: FieldTypeString, Description: "Target version (default: latest)"}, + }, + Outputs: []StepOutputDef{ + {Key: "updated", Type: "boolean", Description: "Whether update succeeded"}, + {Key: "version", Type: "string", Description: "Updated plugin version"}, + }, + }) + + // ---- Network Apply ---- + + r.Register(&StepSchema{ + Type: "step.network_apply", + Plugin: "platform", + Description: "Applies VPC networking changes.", + ConfigFields: []ConfigFieldDef{ + {Key: "network", Type: FieldTypeString, Description: "Name of the platform.networking module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "vpc_id", Type: "string", Description: "VPC ID"}, + {Key: "subnet_ids", Type: "[]string", Description: "Created subnet IDs"}, + }, + }) + + // ---- Network Plan ---- + + r.Register(&StepSchema{ + Type: "step.network_plan", + Plugin: "platform", + Description: "Plans VPC networking changes without applying them.", + ConfigFields: []ConfigFieldDef{ + {Key: "network", Type: FieldTypeString, Description: "Name of the platform.networking module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "plan", Type: "string", Description: "Human-readable plan output"}, + {Key: "changes", Type: "number", Description: "Number of changes planned"}, + }, + }) + + // ---- Network Status ---- + + r.Register(&StepSchema{ + Type: "step.network_status", + Plugin: "platform", + Description: "Gets the status of VPC networking resources.", + ConfigFields: []ConfigFieldDef{ + {Key: "network", Type: FieldTypeString, Description: "Name of the platform.networking module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "status", Type: "string", Description: "Network status"}, + {Key: "vpc_id", Type: "string", Description: "VPC ID"}, + }, + }) + + // ---- NoSQL Delete ---- + + r.Register(&StepSchema{ + Type: "step.nosql_delete", + Plugin: "datastores", + Description: "Deletes an item from a NoSQL store by key.", + ConfigFields: []ConfigFieldDef{ + {Key: "store", Type: FieldTypeString, Description: "Name of the nosql.* module", Required: true}, + {Key: "key", Type: FieldTypeString, Description: "Item key to delete", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "deleted", Type: "boolean", Description: "Whether the item was deleted"}, + }, + }) + + // ---- Policy Evaluate ---- + + r.Register(&StepSchema{ + Type: "step.policy_evaluate", + Plugin: "policy", + Description: "Evaluates input data against a loaded policy and returns an allow/deny decision.", + ConfigFields: []ConfigFieldDef{ + {Key: "engine", Type: FieldTypeString, Description: "Name of the policy.* module", Required: true}, + {Key: "policy", Type: FieldTypeString, Description: "Policy name to evaluate", Required: true}, + {Key: "input", Type: FieldTypeJSON, Description: "Input data for policy evaluation"}, + }, + Outputs: []StepOutputDef{ + {Key: "allowed", Type: "boolean", Description: "Whether the policy allows the action"}, + {Key: "reason", Type: "string", Description: "Decision reason or denial message"}, + }, + }) + + // ---- Policy List ---- + + r.Register(&StepSchema{ + Type: "step.policy_list", + Plugin: "policy", + Description: "Lists all loaded policies in a policy engine.", + ConfigFields: []ConfigFieldDef{ + {Key: "engine", Type: FieldTypeString, Description: "Name of the policy.* module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "policies", Type: "[]string", Description: "List of loaded policy names"}, + {Key: "count", Type: "number", Description: "Number of loaded policies"}, + }, + }) + + // ---- Policy Load ---- + + r.Register(&StepSchema{ + Type: "step.policy_load", + Plugin: "policy", + Description: "Loads a policy into the policy engine at runtime.", + ConfigFields: []ConfigFieldDef{ + {Key: "engine", Type: FieldTypeString, Description: "Name of the policy.* module", Required: true}, + {Key: "name", Type: FieldTypeString, Description: "Policy name", Required: true}, + {Key: "content", Type: FieldTypeString, Description: "Policy content (Rego, CEL, etc.)", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "loaded", Type: "boolean", Description: "Whether the policy was loaded successfully"}, + }, + }) + + // ---- Policy Test ---- + + r.Register(&StepSchema{ + Type: "step.policy_test", + Plugin: "policy", + Description: "Runs tests against a policy to verify its behavior.", + ConfigFields: []ConfigFieldDef{ + {Key: "engine", Type: FieldTypeString, Description: "Name of the policy.* module", Required: true}, + {Key: "policy", Type: FieldTypeString, Description: "Policy name to test", Required: true}, + {Key: "cases", Type: FieldTypeJSON, Description: "Test cases (array of {input, expected_allow})"}, + }, + Outputs: []StepOutputDef{ + {Key: "passed", Type: "boolean", Description: "Whether all test cases passed"}, + {Key: "results", Type: "[]any", Description: "Per-case test results"}, + }, + }) + + // ---- Region Deploy ---- + + r.Register(&StepSchema{ + Type: "step.region_deploy", + Plugin: "platform", + Description: "Deploys to a specific region in a multi-region configuration.", + ConfigFields: []ConfigFieldDef{ + {Key: "module", Type: FieldTypeString, Description: "Name of the platform.region module", Required: true}, + {Key: "region", Type: FieldTypeString, Description: "Region name to deploy to"}, + }, + Outputs: []StepOutputDef{ + {Key: "deployed", Type: "boolean", Description: "Whether deployment succeeded"}, + {Key: "endpoint", Type: "string", Description: "Region endpoint after deployment"}, + }, + }) + + // ---- Region Failover ---- + + r.Register(&StepSchema{ + Type: "step.region_failover", + Plugin: "platform", + Description: "Triggers a failover to a secondary region.", + ConfigFields: []ConfigFieldDef{ + {Key: "module", Type: FieldTypeString, Description: "Name of the platform.region module", Required: true}, + {Key: "from_region", Type: FieldTypeString, Description: "Region to fail over from"}, + {Key: "to_region", Type: FieldTypeString, Description: "Region to fail over to"}, + }, + Outputs: []StepOutputDef{ + {Key: "active_region", Type: "string", Description: "Active region after failover"}, + }, + }) + + // ---- Region Promote ---- + + r.Register(&StepSchema{ + Type: "step.region_promote", + Plugin: "platform", + Description: "Promotes a region to primary (increases traffic weight or priority).", + ConfigFields: []ConfigFieldDef{ + {Key: "module", Type: FieldTypeString, Description: "Name of the platform.region module", Required: true}, + {Key: "region", Type: FieldTypeString, Description: "Region to promote", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "promoted", Type: "boolean", Description: "Whether promotion succeeded"}, + }, + }) + + // ---- Region Status ---- + + r.Register(&StepSchema{ + Type: "step.region_status", + Plugin: "platform", + Description: "Gets the health and status of all regions.", + ConfigFields: []ConfigFieldDef{ + {Key: "module", Type: FieldTypeString, Description: "Name of the platform.region module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "regions", Type: "[]any", Description: "Region status objects"}, + {Key: "active_count", Type: "number", Description: "Number of healthy regions"}, + }, + }) + + // ---- Region Sync ---- + + r.Register(&StepSchema{ + Type: "step.region_sync", + Plugin: "platform", + Description: "Syncs state or configuration across all regions.", + ConfigFields: []ConfigFieldDef{ + {Key: "module", Type: FieldTypeString, Description: "Name of the platform.region module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "synced", Type: "boolean", Description: "Whether sync succeeded"}, + {Key: "regions_synced", Type: "number", Description: "Number of regions synced"}, + }, + }) + + // ---- Region Weight ---- + + r.Register(&StepSchema{ + Type: "step.region_weight", + Plugin: "platform", + Description: "Sets the traffic weight for a region.", + ConfigFields: []ConfigFieldDef{ + {Key: "module", Type: FieldTypeString, Description: "Name of the platform.region module", Required: true}, + {Key: "region", Type: FieldTypeString, Description: "Region name", Required: true}, + {Key: "weight", Type: FieldTypeNumber, Description: "Traffic weight (0-100)", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "weight", Type: "number", Description: "Applied weight"}, + }, + }) + + // ---- Scaling Apply ---- + + r.Register(&StepSchema{ + Type: "step.scaling_apply", + Plugin: "platform", + Description: "Applies autoscaling policy changes.", + ConfigFields: []ConfigFieldDef{ + {Key: "scaling", Type: FieldTypeString, Description: "Name of the platform.autoscaling module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "applied", Type: "boolean", Description: "Whether scaling policies were applied"}, + }, + }) + + // ---- Scaling Destroy ---- + + r.Register(&StepSchema{ + Type: "step.scaling_destroy", + Plugin: "platform", + Description: "Removes autoscaling policies.", + ConfigFields: []ConfigFieldDef{ + {Key: "scaling", Type: FieldTypeString, Description: "Name of the platform.autoscaling module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "destroyed", Type: "boolean", Description: "Whether policies were removed"}, + }, + }) + + // ---- Scaling Plan ---- + + r.Register(&StepSchema{ + Type: "step.scaling_plan", + Plugin: "platform", + Description: "Plans autoscaling policy changes without applying them.", + ConfigFields: []ConfigFieldDef{ + {Key: "scaling", Type: FieldTypeString, Description: "Name of the platform.autoscaling module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "plan", Type: "string", Description: "Human-readable plan output"}, + {Key: "changes", Type: "number", Description: "Number of changes planned"}, + }, + }) + + // ---- Scaling Status ---- + + r.Register(&StepSchema{ + Type: "step.scaling_status", + Plugin: "platform", + Description: "Gets the status of autoscaling policies.", + ConfigFields: []ConfigFieldDef{ + {Key: "scaling", Type: FieldTypeString, Description: "Name of the platform.autoscaling module", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "status", Type: "string", Description: "Scaling status"}, + {Key: "policies", Type: "[]any", Description: "Active scaling policy details"}, + }, + }) + + // ---- Secret Rotate ---- + + r.Register(&StepSchema{ + Type: "step.secret_rotate", + Plugin: "secrets", + Description: "Rotates a secret by generating a new value and updating the secrets backend.", + ConfigFields: []ConfigFieldDef{ + {Key: "provider", Type: FieldTypeString, Description: "Name of the secrets module", Required: true}, + {Key: "secret_id", Type: FieldTypeString, Description: "Secret ID or ARN to rotate", Required: true}, + }, + Outputs: []StepOutputDef{ + {Key: "rotated", Type: "boolean", Description: "Whether the secret was rotated"}, + {Key: "version_id", Type: "string", Description: "New secret version ID"}, + }, + }) + + // ---- Trace Annotate ---- + + r.Register(&StepSchema{ + Type: "step.trace_annotate", + Plugin: "observability", + Description: "Adds attributes or events to the current trace span.", + ConfigFields: []ConfigFieldDef{ + {Key: "attributes", Type: FieldTypeMap, Description: "Key/value attributes to add to the span"}, + {Key: "event", Type: FieldTypeString, Description: "Event name to record on the span"}, + }, + Outputs: []StepOutputDef{ + {Key: "annotated", Type: "boolean", Description: "Whether annotation was applied"}, + }, + }) + + // ---- Trace Extract ---- + + r.Register(&StepSchema{ + Type: "step.trace_extract", + Plugin: "observability", + Description: "Extracts trace context from incoming request headers or message attributes.", + ConfigFields: []ConfigFieldDef{ + {Key: "source", Type: FieldTypeString, Description: "Source to extract from: headers, message, context", DefaultValue: "headers"}, + }, + Outputs: []StepOutputDef{ + {Key: "trace_id", Type: "string", Description: "Extracted trace ID"}, + {Key: "span_id", Type: "string", Description: "Extracted span ID"}, + }, + }) + + // ---- Trace Inject ---- + + r.Register(&StepSchema{ + Type: "step.trace_inject", + Plugin: "observability", + Description: "Injects trace context into outgoing request headers or message attributes.", + ConfigFields: []ConfigFieldDef{ + {Key: "target", Type: FieldTypeString, Description: "Target to inject into: headers, message", DefaultValue: "headers"}, + }, + Outputs: []StepOutputDef{ + {Key: "injected", Type: "boolean", Description: "Whether context was injected"}, + }, + }) + + // ---- Trace Link ---- + + r.Register(&StepSchema{ + Type: "step.trace_link", + Plugin: "observability", + Description: "Creates a causal link between the current span and another span.", + ConfigFields: []ConfigFieldDef{ + {Key: "trace_id", Type: FieldTypeString, Description: "Trace ID to link to", Required: true}, + {Key: "span_id", Type: FieldTypeString, Description: "Span ID to link to"}, + }, + Outputs: []StepOutputDef{ + {Key: "linked", Type: "boolean", Description: "Whether the link was created"}, + }, + }) + + // ---- Trace Start ---- + + r.Register(&StepSchema{ + Type: "step.trace_start", + Plugin: "observability", + Description: "Starts a new trace span for the current pipeline step or operation.", + ConfigFields: []ConfigFieldDef{ + {Key: "name", Type: FieldTypeString, Description: "Span name", Required: true}, + {Key: "attributes", Type: FieldTypeMap, Description: "Initial span attributes"}, + }, + Outputs: []StepOutputDef{ + {Key: "trace_id", Type: "string", Description: "New trace ID"}, + {Key: "span_id", Type: "string", Description: "New span ID"}, + }, + }) }