funops <resource> <action> [arguments] [flags]
FUN-8 funops - Operator CLI
1. Introduction
This FUN introduces funops, a command-line interface tool for Fundament platform operators. The tool provides direct database access for administrative tasks that require root-level system access, such as bootstrapping new organizations or performing system recovery operations.
2. Why funops
2.1. The Need for Operator Tooling
Fundament exposes APIs for end-users (used by Console UI, Terraform provider), but certain administrative operations require elevated privileges beyond what tenant-scoped APIs provide:
-
Bootstrap operations: Creating the initial organization before any users exist
-
System recovery: Fixing data inconsistencies or recovering from failures
-
Administrative tasks: Operations that span multiple organizations or require system-level access
-
Debugging: Inspecting system state during development or incident response
2.2. Direct Database Access
For the initial proof-of-concept, funops operates directly against the PostgreSQL database rather than through the existing APIs. This approach provides:
-
Simplicity: No additional API surface to design and maintain
-
Full access: No RLS restrictions when using a privileged database user
-
Speed of development: Faster iteration for PoC needs
This is not necessarily a permanent decision. Future versions may transition to API-based operations where appropriate, particularly for operations that benefit from audit logging or can be safely exposed to less privileged operators.
3. Design
3.1. CLI Philosophy
funops follows conventions established by similar cloud-native CLI tools:
| Tool | Pattern |
|---|---|
kubectl |
|
metalctl |
|
gardenctl |
|
funops adopts the resource-centric pattern:
Examples:
funops organization create acme-corp funops organization create acme-corp --output json
3.2. Non-Interactive Design
funops is designed to be non-interactive and scriptable:
-
All input comes from command-line arguments and flags
-
No interactive prompts or manifest files
-
Suitable for automation, CI/CD pipelines, and scripting
-
Clear exit codes for success/failure
This differs from kubectl’s declarative manifest approach. Fundament operators use imperative commands for administrative tasks rather than applying YAML files.
3.3. Output Formats
funops supports multiple output formats via the --output / -o flag:
| Format | Description |
|---|---|
|
Human-readable tabular format for terminal use |
|
Machine-readable JSON for scripting and automation |
3.4. Configuration
funops uses environment variables for configuration, following the 12-factor app methodology:
| Variable | Required | Description |
|---|---|---|
|
Yes |
PostgreSQL connection string (e.g., |
No configuration files are used. This keeps the tool simple and explicit about its dependencies.
3.5. Database Access
funops connects directly to the Fundament PostgreSQL database. The database user specified in DATABASE_URL should have appropriate permissions:
-
For full operator access: Use a PostgreSQL user that has explicit RLS policies granting full access, or a superuser role
-
RLS policies in the Fundament schema can be configured to allow specific users full access, or the bypassrls attribute
Initial development uses the superuser role and bypassrls attributes.
3.6. Logging
funops uses structured logging via Go’s slog package, with output directed to stderr:
-
Default level: INFO - Shows user feedback for operations that would otherwise be silent (e.g., successful deletes)
-
Debug level (
--debug) - Includes detailed internal operations like database connections and query parameters
This design keeps stdout clean for programmatic use (piping, scripting) while providing appropriate feedback to operators. Commands that produce data output (list, create) write to stdout; informational messages go to stderr via the logger.