| doc_type | explanation |
|---|---|
| title | Codebase Organization |
| audience | developers |
Purpose: For developers, explains how the openCenter-cli codebase is organized and where to find specific functionality.
openCenter-cli/
├── cmd/ # CLI commands (Cobra)
├── internal/ # Internal packages
├── docs/ # Documentation
├── tests/ # BDD test scenarios
├── schema/ # JSON schema definitions
├── testdata/ # Test fixtures
├── hack/ # Scripts and utilities
├── bin/ # Compiled binaries (gitignored)
├── third-party/ # External dependencies
├── main.go # Entry point
├── go.mod # Go module definition
└── .mise.toml # Build tasks and tool versions
Commands follow the pattern cmd/<command>_<subcommand>.go:
Cluster commands (cluster_*.go):
cluster_init.go- Initialize cluster configurationcluster_validate.go- Validate configurationcluster_generate.go- Generate GitOps repositorycluster_deploy.go- Deploy cluster (no longer auto-commits)cluster_deploy_plan.go- Deploy dry-run plan formattingcluster_edit.go- Edit configuration interactivelycluster_set.go- Update configuration via dot-notation flagscluster_list.go- List clusterscluster_use.go- Set active clustercluster_describe.go- Show cluster detailscluster_status.go- Show cluster status with inventorycluster_destroy.go- Destroy clustercluster_render.go- Render templates without deployingcluster_drift.go- Infrastructure drift detection/reconciliationcluster_service.go- Service enable/disable/statuscluster_backup.go- Backup/restore operations
Secrets commands (secrets_*.go):
secrets.go- Secrets parent + CRUD subcommandssecrets_keys.go- Key lifecycle subcommandssecrets_keys_ops.go- Key operations (generate, rotate, backup, validate)secrets_sync.go- Synchronize secrets to encrypted manifestssecrets_validate.go- Validate secrets encryptionsecrets_sops.go- Encrypt/decrypt/status commands
Configuration commands (config_*.go):
config.go- Settings parent commandconfig_edit.go- Edit global configurationconfig_ide.go- IDE schema generationconfig_explain.go- Explain config effects
Utility commands:
version.go- Show version informationshell_init.go- Shell integration setupplugins.go- Plugin management
Command naming convention:
// Function returns *cobra.Command
func newCluster<Action>Cmd() *cobra.Command {
return &cobra.Command{
Use: "action",
Short: "Brief description",
RunE: runClusterAction,
}
}CLI settings management (the legacy monolithic config package was removed in May 2026):
cli_settings.go- CLI user preferences, cluster defaults, plugin checksumscli_settings_helpers.go- Path resolution from CLI config (ResolveClustersDir, GetGitOpsDir, etc.)manager.go- Global manager singletonpersistence.go- Config/state directory resolutionstatus.go- Cluster status updatesdefaults/- Default configuration templates per provider-regionv2/- Authoritative v2 configuration (loader, validator, manager, cache, errors, io_handler)flags/- CLI flag parsing and struct mutation via reflectionservices/- Typed service configs with dependency/provider validation
Key types (v2):
type Config struct {
Meta MetaConfig
OpenCenter OpenCenterConfig
Infrastructure InfrastructureConfig
Kubernetes KubernetesConfig
GitOps GitOpsConfig
Services ServiceMap
Secrets SecretsConfig
OpenTofu OpenTofuConfig
Deployment DeploymentConfig
}GitOps repository scaffolding:
copy.go- Template copying and rendering logicembed.go- Embedded template management (//go:embed)gitops-base-dir/- Base repository structure (embedded)templates/- Cluster-specific templates (embedded)
Template structure:
gitops-base-dir/
├── applications/
│ └── base/
│ └── services/
│ ├── cert-manager/
│ ├── kyverno/
│ └── ...
└── infrastructure/
└── clusters/
├── openstack/
├── vmware/
└── ...
SOPS and Age key management:
manager.go- SOPS manager interfacekeys.go- Age key generation and storageencrypt.go- Encryption/decryption operationsgit.go- Git integration for encrypted filesvalidator.go- SOPS configuration validation
Cloud provider adapters:
internal/cloud/openstack/- OpenStack drift detection + discoveryinternal/cloud/vmware/- VMware/vSphere drift detectioninternal/cloud/kind/- Kind cluster lifecycleinternal/cloud/- Provider factory, drift comparisoninternal/provision/- Embedded OpenTofu/Terraform provisioning templates
Security utilities:
input_validator.go- Input validation (path traversal, injection)command_sanitizer.go- Command sanitizationcredential_masker.go- Credential masking in logsaudit_logger.go- Audit logging with HMAC signatures
Shared utility packages:
crypto/- Key generation and managementerrors/- Error handling and aggregationfiles/- File operations (atomic writes, backups)paths/- Path resolution and validationtemplate/- Template engine and validation
internal/ansible/- Kubespray inventory generation from configinternal/barbican/- OpenStack Key Manager (Barbican) clientinternal/cluster/- Cluster lifecycle services (init, validate, setup, bootstrap, destroy)internal/core/- Shared path resolution (core/paths) and validation engine (core/validation)internal/credentials/- Cloud credential extraction from configinternal/di/- Dependency injection container (App struct + reflection-based Container)internal/importer/- Live cluster import/scan for existing workloadsinternal/localdev/- Local dev environment (Kind, Gitea, Flux)internal/logging/- Structured logging (global logger, level/format reconfiguration)internal/observability/- Log shipping (Loki, syslog), migration helpersinternal/operations/- Drift detection, backup, disaster recoveryinternal/plugins/- External CLI plugin discovery and checksum verificationinternal/resilience/- Retry, circuit breaker, distributed locksinternal/secrets/- Multi-cluster secrets management (rotation, registry, hooks, revocation)internal/services/- Platform service plugin registry with dependency resolutioninternal/template/- Template engine with caching, validation, sandboxinginternal/testenv/- Test environment helpers (isolated CLI config/state)internal/testing/- Shared test utilities (helpers, mocks, generators, benchmarks)internal/tofu/- OpenTofu/Terraform provisioning execution (falls back to terraform)internal/ui/- Prompts, error formatting, guided flows
BDD tests using Cucumber/Gherkin:
tests/
└── features/
├── workflow.feature
├── cluster_init.feature
├── validation.feature
└── steps/
├── cluster_steps.go
├── config_steps.go
└── test_suite.go
Tag convention:
@wip- Work in progress scenarios@priority1- High priority tests@priority2- Medium priority tests
User configurations stored in organization-based structure:
~/.config/opencenter/clusters/
└── <organization>/
├── .<cluster>-config.yaml # Cluster configuration (dot-prefixed)
├── secrets/
│ ├── age/
│ │ └── <cluster>-key.txt
│ └── ssh/
│ └── <cluster>-<env>-<region>
└── gitops/
├── applications/
└── infrastructure/
Each package has a single, well-defined responsibility:
cmd/- CLI interface and user interactioninternal/config/- Configuration managementinternal/gitops/- GitOps repository generationinternal/sops/- Secrets encryptioninternal/cloud/- Provider-specific logic
Avoid global state, pass dependencies explicitly:
// Good: Dependencies injected
func NewValidator(schema *jsonschema.Schema) *Validator {
return &Validator{schema: schema}
}
// Bad: Global state
var globalSchema *jsonschema.SchemaDefine interfaces in consumer packages:
// internal/config/interfaces.go
type SecretManager interface {
Encrypt(data []byte) ([]byte, error)
Decrypt(data []byte) ([]byte, error)
}
// internal/sops/manager.go implements SecretManagerTemplates and defaults embedded in binary via //go:embed:
//go:embed gitops-base-dir
var gitopsBaseFS embed.FS
//go:embed templates
var templatesFS embed.FSUse fmt.Errorf with %w for error context:
if err != nil {
return fmt.Errorf("failed to load config: %w", err)
}- Commands:
<noun>_<verb>.go(e.g.,cluster_init.go,secrets_keys_ops.go) - Tests:
<name>_test.go(unit),<name>_property_test.go(property-based) - Integration tests:
<name>_integration_test.go - Interfaces:
interfaces.goin each package - Documentation:
doc.gofor package documentation
To add a new command:
- Create
cmd/cluster_<action>.go - Implement
newCluster<Action>Cmd() - Register in
cmd/cluster.go
To modify configuration:
- Update
internal/config/v2/config.go(structs) - Update
internal/config/v2/validator.go(validation rules) - Update
internal/config/v2/defaults.go(defaults) - Run
go generate ./internal/config/v2schema/to regenerate JSON schema
To add a provider:
- Create
internal/cloud/<provider>/provider.go - Add defaults in
internal/config/defaults/<provider>.go - Add bootstrap steps in
internal/cluster/bootstrap_provider_infra.go - Add template in
internal/gitops/templates/infrastructure-cluster-template/
To add a service:
- Add service config in
internal/config/services/ - Create plugin in
internal/services/plugins/ - Add templates in
internal/gitops/gitops-base-dir/ - Add descriptor in
internal/services/descriptors/
To add validation:
- Create validator in
internal/core/validation/validators/ - Register in
internal/di/providers.go
- Total lines: ~226,000 LOC
- Go files: ~710 files
- Test files: ~350 files
- Internal packages: 30+ packages
- Commands: 50+ command files
- Dependencies: 19 direct dependencies
Commands encapsulate operations:
type Command interface {
Execute() error
}Configuration storage abstracted:
type ConfigRepository interface {
Load(path string) (*Config, error)
Save(path string, cfg *Config) error
}Base template with provider-specific overrides:
func GenerateInfrastructure(provider string) error {
// Common steps
loadConfig()
validateConfig()
// Provider-specific
switch provider {
case "openstack":
generateOpenStackTerraform()
case "aws":
generateAWSTerraform()
}
// Common steps
writeFiles()
}This documentation is based on the following repository files:
- Project structure:
.kiro/steering/structure.md:1-128 - Command layer:
cmd/directory (70+ files) - Internal packages:
internal/directory (25 packages) - Configuration:
internal/config/directory - GitOps:
internal/gitops/directory - Testing:
tests/features/directory - Code metrics: Session 1 summary (A1)
- Organization principles:
.kiro/steering/structure.md:130-145