diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 000000000..6a8b6d4d5 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,111 @@ +{ + "permissions": { + "allow": [ + "Bash(make)", + "Bash(make test-unit)", + "Bash(make test-e2e)", + "Bash(make verify)", + "Bash(make check)", + "Bash(./test-unit.sh *)", + "Bash(./test-unit.sh)", + + "Bash(go test *)", + "Bash(go vet *)", + "Bash(go build *)", + "Bash(go version)", + "Bash(gofmt *)", + + "Bash(tree *)", + + "Bash(git fetch *)", + "Bash(git status)", + "Bash(git diff *)", + "Bash(git log *)", + "Bash(git branch *)", + "Bash(git show *)", + "Bash(git stash *)", + "Bash(git remote *)", + + "Bash(gh pr view *)", + "Bash(gh pr list *)", + "Bash(gh pr diff *)", + "Bash(gh pr checks *)", + + "WebFetch(domain:github.com)", + "WebFetch(domain:patch-diff.githubusercontent.com)", + "WebFetch(domain:raw.githubusercontent.com)", + "WebFetch(domain:docs.openshift.com)", + "WebFetch(domain:kubernetes.io)", + + "Bash(oc get *)", + "Bash(oc describe *)", + "Bash(oc logs *)", + "Bash(kubectl get *)", + "Bash(kubectl describe *)", + "Bash(kubectl version *)", + + "Bash(docker --version)", + "Bash(docker ps *)", + "Bash(docker images *)", + + "Bash(claude --version)" + ], + + "deny": [ + "Bash(git push --force *)", + "Bash(git push -f *)", + "Bash(git reset --hard *)", + "Bash(git clean -fd *)", + "Bash(git clean -fdx *)", + + "Bash(git checkout -f *)", + "Bash(git checkout --force *)", + "Bash(git checkout -- . *)", + "Bash(git checkout HEAD -- . *)", + + "Bash(git fetch --force *)", + "Bash(git fetch -f *)", + + "Bash(git stash drop *)", + "Bash(git stash clear *)", + "Bash(git revert --no-commit *)", + "Bash(git branch -D *)", + "Bash(git branch --delete --force *)", + + "Bash(rm -rf *)", + "Bash(rm -fr *)", + + "Bash(oc delete *)", + "Bash(oc apply *)", + "Bash(oc create *)", + "Bash(kubectl delete *)", + "Bash(kubectl apply *)", + "Bash(kubectl create *)", + + "Bash(docker rm *)", + "Bash(docker rmi *)", + "Bash(docker stop *)", + "Bash(docker kill *)" + ], + + "ask": [ + "Bash(go get *)", + "Bash(go mod *)", + + "Bash(git commit *)", + "Bash(git push *)", + "Bash(git merge *)", + "Bash(git rebase *)", + "Bash(git checkout *)", + "Bash(git switch *)", + "Bash(git apply *)", + + "Bash(gh pr create *)", + "Bash(gh pr merge *)", + "Bash(gh pr close *)", + + "Bash(docker build *)", + "Bash(docker push *)" + ] + } +} diff --git a/.coderabbit.yaml b/.coderabbit.yaml new file mode 100644 index 000000000..24d3918dc --- /dev/null +++ b/.coderabbit.yaml @@ -0,0 +1,64 @@ +# CodeRabbit Configuration +# https://docs.coderabbit.ai/guides/configure-coderabbit + +version: 2 + +language: en-US + +early_access: false + +reviews: + profile: chill + request_changes_workflow: false + high_level_summary: true + poem: false + review_status: true + collapse_walkthrough: false + path_instructions: + - path: "pkg/**/*.go" + instructions: | + Review Go code following OpenShift operator patterns. + See CONVENTIONS.md for coding standards and patterns. + Controllers should use the library-go factory pattern. + Status conditions should use status.Handle* functions. + - path: "bindata/assets/**/*.yaml" + instructions: | + Review YAML assets for Kubernetes resource correctness. + Ensure proper annotations for cluster profiles. + - path: "manifests/**/*.yaml" + instructions: | + Review CVO manifests carefully. + These are deployed to clusters and changes have wide impact. + - path: "quickstarts/**/*.yaml" + instructions: | + Review quickstart YAML definitions. + Ensure cluster profile annotations are present. + See quickstarts/README.md for guidelines. + +chat: + auto_reply: true + +knowledge_base: + learnings: + scope: local + code_guidelines: + enabled: true + filePatterns: + - "AGENTS.md" + - "CLAUDE.md" + - "ARCHITECTURE.md" + - "CONVENTIONS.md" + - "TESTING.md" + issues: + scope: auto + jira: + project_keys: [] + linear: + team_keys: [] + pull_requests: + scope: auto + +path_filters: + - "!vendor/**" + - "!**/*_test.go" + diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..ff31b26f9 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,94 @@ +# OpenShift Console Operator - AI Context Hub + +This file serves as the central AI documentation hub for the OpenShift Console Operator project. AI assistants (Claude, Cursor, Copilot, CodeRabbit, etc.) use this and the linked documents to understand project context. +## Go Version and Dependencies +## Go Version and Dependencies + +- **Go version**: 1.24.0 (toolchain: go1.24.4) +- **Dependency management**: Uses `go.mod` with vendoring +- **Build flags**: Use `GOFLAGS="-mod=vendor"` for builds and tests to ensure vendored dependencies are used +- **Key dependencies**: openshift/api, openshift/library-go, k8s.io client libraries +- **Go version**: 1.24.0 (toolchain: go1.24.4) +- **Dependency management**: Uses `go.mod` with vendoring +- **Build flags**: Use `GOFLAGS="-mod=vendor"` for builds and tests to ensure vendored dependencies are used +- **Key dependencies**: openshift/api, openshift/library-go, k8s.io client libraries +## Quick Reference + +### This Repository + +| Document | Purpose | +|----------|---------| +| [ARCHITECTURE.md](./ARCHITECTURE.md) | System architecture, components, repository structure | +| [CONVENTIONS.md](./CONVENTIONS.md) | Go coding standards, patterns, import organization | +| [TESTING.md](./TESTING.md) | Testing patterns, commands, debugging | +| [README.md](./README.md) | Project README with setup instructions | + +### Console Repository (openshift/console) + +For frontend-related guidelines, see the [openshift/console](https://github.com/openshift/console) repository: + +| Document | Purpose | +|----------|---------| +| [STYLEGUIDE.md](https://github.com/openshift/console/blob/master/STYLEGUIDE.md) | Frontend code style guidelines | +| [INTERNATIONALIZATION.md](https://github.com/openshift/console/blob/master/INTERNATIONALIZATION.md) | i18n patterns and translation guidelines | +| [CONTRIBUTING.md](https://github.com/openshift/console/blob/master/CONTRIBUTING.md) | Contribution guidelines for the console project | + + +## Project Summary + +The **console-operator** is an OpenShift operator that installs and maintains the OpenShift web console on a cluster. It manages: + +- Console deployment and configuration +- OAuth client configuration for console authentication +- CLI downloads (oc, kubectl) deployment +- Routes, services, and secrets +- Console plugins and quickstarts +- Pod disruption budgets +- Health checks and monitoring + +## Essential Commands + +```bash +# Build +make # Build the operator binary +make build # Same as above + +# Test +make test-unit # Run unit tests +make test-e2e # Run e2e tests (requires cluster) +make check # Run verify + test-unit + +# Code Quality +gofmt -w ./pkg ./cmd # Format code +go vet ./pkg/... ./cmd/... # Run vet checks +make verify # Run all verification +``` + +## Key Namespaces + +| Namespace | Purpose | +|-----------|---------| +| `openshift-console` | Console deployment and resources | +| `openshift-console-operator` | Operator deployment | +| `openshift-config` | Cluster configuration | +| `openshift-config-managed` | Managed configuration | +| `openshift-ingress-operator` | Ingress controller (default ingress) | + +## Branch Naming + +- Feature work: `CONSOLE-####` (Jira story number) +- Bug fixes: `OCPBUGS-####` (Jira bug number) + +## Related Repositories + +- [openshift/console](https://github.com/openshift/console) - Web console frontend and backend (see STYLEGUIDE.md, INTERNATIONALIZATION.md, CONTRIBUTING.md) +- [openshift/api](https://github.com/openshift/api) - OpenShift API definitions +- [openshift/library-go](https://github.com/openshift/library-go) - Shared operator libraries + +## OWNERS + +Component: Management Console +- @spadgett +- @jhadvig +- @TheRealJon + diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 000000000..55d830cff --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,125 @@ +# Architecture + +This document outlines the system architecture for the OpenShift Console Operator. + +## Repository Structure + +``` +console-operator/ +├── cmd/console/ # Main entry point (main.go) +├── pkg/ +│ ├── api/ # API constants (namespaces, resource names, ports) +│ ├── cmd/ +│ │ ├── operator/ # Operator command setup +│ │ └── version/ # Version command +│ ├── console/ +│ │ ├── clientwrapper/ # Client wrapper utilities +│ │ ├── controllers/ # All controller implementations +│ │ │ ├── clidownloads/ # CLI downloads controller +│ │ │ ├── clioidcclientstatus/ # CLI OIDC client status controller +│ │ │ ├── downloadsdeployment/ # Downloads deployment controller +│ │ │ ├── healthcheck/ # Health check controller +│ │ │ ├── oauthclients/ # OAuth client controller +│ │ │ ├── oauthclientsecret/ # OAuth client secret controller +│ │ │ ├── oidcsetup/ # OIDC setup controller +│ │ │ ├── poddisruptionbudget/ # PDB controller +│ │ │ ├── route/ # Route controller +│ │ │ ├── service/ # Service controller +│ │ │ ├── storageversionmigration/ +│ │ │ ├── upgradenotification/ # Upgrade notification controller +│ │ │ └── util/ # Shared controller utilities +│ │ ├── errors/ # Custom error types (SyncError, CustomLogoErrors) +│ │ ├── metrics/ # Prometheus metrics +│ │ ├── operator/ # Main operator logic (sync_v400.go) +│ │ ├── starter/ # Operator startup, informer setup, controller wiring +│ │ ├── status/ # Status condition handling +│ │ ├── subresource/ # Resource builders for each managed resource +│ │ │ ├── authentication/ # Authentication config handling +│ │ │ ├── configmap/ # ConfigMap builders (branding, service CA, trusted CA) +│ │ │ ├── consoleserver/ # Console server config builder +│ │ │ ├── crd/ # CRD utilities +│ │ │ ├── deployment/ # Deployment builder +│ │ │ ├── infrastructure/ # Infrastructure config +│ │ │ ├── oauthclient/ # OAuth client builder +│ │ │ ├── route/ # Route builder +│ │ │ ├── secret/ # Secret builders (session secret) +│ │ │ └── util/ # Shared subresource utilities +│ │ ├── telemetry/ # Telemetry integration +│ │ └── version/ # Version information +│ └── crypto/ # Cryptographic utilities (random string generation) +├── bindata/assets/ # Static YAML assets +│ ├── configmaps/ # ConfigMap templates +│ ├── deployments/ # Deployment templates +│ ├── pdb/ # PodDisruptionBudget templates +│ ├── routes/ # Route templates (console, downloads, custom) +│ └── services/ # Service templates +├── manifests/ # CVO manifest files (deployed to cluster) +├── profile-patches/ # Profile-specific patches (e.g., IBM Cloud managed) +├── quickstarts/ # Console quickstart YAML definitions +├── examples/ # Example configurations +│ ├── cvo-unmanage-operator.yaml # Disable CVO management for dev +│ ├── cvo-manage-operator.yaml # Re-enable CVO management +│ └── 07-operator-alt-image.yaml # Custom operator image deployment +├── test/e2e/ # End-to-end tests +└── vendor/ # Vendored dependencies +``` + +## Controllers + +The operator runs multiple controllers (started in `pkg/console/starter/starter.go`): + +| Controller | Purpose | +|-----------|---------| +| `ConsoleOperator` | Main operator coordinating deployment, configmaps, secrets | +| `RouteController` | Manages console and downloads routes | +| `ServiceController` | Manages console and downloads services | +| `OAuthClientsController` | Creates/updates OAuth client for console authentication | +| `OAuthClientSecretController` | Syncs OAuth client secret | +| `OIDCSetupController` | Handles external OIDC authentication (feature-gated) | +| `CLIOIDCClientStatusController` | Reports CLI OIDC client status | +| `CLIDownloadsController` | Manages ConsoleCLIDownload resources | +| `DownloadsDeploymentController` | Manages the downloads deployment | +| `HealthCheckController` | Monitors console health | +| `PodDisruptionBudgetController` | Manages PDBs for console and downloads | +| `UpgradeNotificationController` | Displays upgrade notifications | +| `StorageVersionMigrationController` | Handles storage version migrations | + +## Key Resources + +| Resource | API Group | Purpose | +|----------|-----------|---------| +| `Console` | operator.openshift.io/v1 | Operator configuration CR | +| `Console` | config.openshift.io/v1 | Cluster console configuration | +| `ClusterOperator` | config.openshift.io/v1 | Cluster operator status | +| `OAuthClient` | oauth.openshift.io/v1 | Console OAuth client | +| `ConsoleCLIDownload` | console.openshift.io/v1 | CLI download configurations | +| `ConsolePlugin` | console.openshift.io/v1 | Dynamic console plugins | +| `ConsoleNotification` | console.openshift.io/v1 | Console notifications | +| `ConsoleQuickStart` | console.openshift.io/v1 | Guided tutorials | + +## Feature Gates + +Feature gates are accessed via `featuregates.FeatureGateAccess` (in `starter.go`): + +| Feature Gate | Purpose | +|-------------|---------| +| `ExternalOIDC` | External OIDC authentication support | +| `ConsolePluginContentSecurityPolicy` | Content Security Policy for plugins | + +## Resource Syncing + +Use `resourcesynccontroller` for syncing ConfigMaps and Secrets between namespaces: +- `oauth-serving-cert` from `openshift-config-managed` to `openshift-console` +- `default-ingress-cert` from `openshift-config-managed` to `openshift-console` + +## Quickstarts + +Console quickstarts are contributed to the `quickstarts/` directory. See [quickstarts/README.md](./quickstarts/README.md) for guidelines. Quickstarts require cluster profile annotations: + +```yaml +annotations: + include.release.openshift.io/ibm-cloud-managed: "true" + include.release.openshift.io/self-managed-high-availability: "true" + include.release.openshift.io/single-node-developer: "true" +``` + diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..c3abdfd2c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,25 @@ +# Claude Code Configuration + +This file configures Claude Code for the OpenShift Console Operator project. + +## AI Context + +See [AGENTS.md](./AGENTS.md) for the central AI documentation hub, which includes: + +- [ARCHITECTURE.md](./ARCHITECTURE.md) - System architecture, components, repository structure +- [CONVENTIONS.md](./CONVENTIONS.md) - Go coding standards, patterns, import organization +- [TESTING.md](./TESTING.md) - Testing patterns, commands, debugging + +## Quick Commands + +```bash +# Build +make + +# Test +make test-unit +make check + +# Format +gofmt -w ./pkg ./cmd +``` diff --git a/CONVENTIONS.md b/CONVENTIONS.md new file mode 100644 index 000000000..1f719c45b --- /dev/null +++ b/CONVENTIONS.md @@ -0,0 +1,95 @@ +# Conventions + +This document outlines coding standards and patterns for the OpenShift Console Operator. + +See the main OpenShift Go style guidelines for base rules. This document provides project-specific conventions. + +## Go Style + +- Use `gofmt` for formatting +- Follow standard Go naming conventions +- Group imports: standard lib, 3rd party, kube/openshift, internal (marked with comments) +- Use meaningful error messages with context + +## Import Organization + +Imports are grouped with comments: + +```go +import ( + // standard lib + "context" + + // 3rd party + "github.com/spf13/cobra" + + // kube + "k8s.io/client-go/kubernetes" + + // openshift + "github.com/openshift/api/config/v1" + + // operator (internal) + "github.com/openshift/console-operator/pkg/api" +) +``` + +## Controller Pattern + +Controllers use the OpenShift library-go factory pattern: + +```go +return factory.New(). + WithFilteredEventsInformers( + configNameFilter, + informers..., + ). + WithSync(c.Sync). + ToController("ControllerName", recorder) +``` + +## Sync Loop Pattern + +The main sync loop (`sync_v400`) works incrementally: +- Start from zero, work through requirements +- If anything is missing, create/update it and return +- Next loop continues from where previous left off +- Ensures simple, non-coordinated logic + +## Status Conditions + +Set conditions using `status.Handle*` functions with type prefixes: + +```go +// For errors that may be transient (SyncError) vs permanent +statusHandler.AddConditions(status.HandleProgressingOrDegraded("ConfigMapSync", reason, err)) + +// For single conditions +statusHandler.AddCondition(status.HandleDegraded("ConsoleConfig", "FailedUpdate", err)) +statusHandler.AddCondition(status.HandleProgressing("SyncLoopRefresh", "InProgress", err)) +statusHandler.AddCondition(status.HandleAvailable("Deployment", reason, err)) +``` + +Condition types (appended to prefix): +- `*Degraded` - Errors occurred (true when error present) +- `*Progressing` - Changes are being applied (true when error present) +- `*Available` - Resource is functioning (true when NO error) +- `*Upgradeable` - Safe to upgrade (true when NO error) + +## Error Handling + +- Use typed errors with meaningful context +- Wrap errors to preserve stack context +- Use `status.Handle*` functions to report conditions + +## Branch Naming + +- Feature work: `CONSOLE-####` (Jira story number) +- Bug fixes: `OCPBUGS-####` (Jira bug number) + +## Commit Strategy + +- Separate vendor folder changes into their own commit to isolate core logic changes +- Keep commits focused and atomic +- Write clear commit messages that explain the "why" + diff --git a/TESTING.md b/TESTING.md new file mode 100644 index 000000000..db6efa116 --- /dev/null +++ b/TESTING.md @@ -0,0 +1,139 @@ +# Testing + +This document covers testing patterns and debugging for the OpenShift Console Operator. + +## Running Tests + +```bash +# Unit tests +make test-unit + +# Run tests for specific package +PKG=./pkg/console/controllers/route ./test-unit.sh + +# End-to-end tests (requires cluster) +make test-e2e + +# All verification checks +make verify + +# Combined verify + test-unit +make check +``` + +## Code Quality + +```bash +# Format code +gofmt -w ./pkg ./cmd + +# Run vet checks +go vet ./pkg/... ./cmd/... + +# Run all verification +make verify +``` + +## Test Patterns + +- Use table-driven tests for comprehensive coverage +- Use `httptest` for HTTP handler testing +- Include proper cleanup functions +- Test both success and failure paths + +## Debugging + +### Inspect Cluster Operator Status + +```bash +oc describe clusteroperator console +``` + +### Get Operator Events + +```bash +oc get events -n openshift-console-operator +``` + +### View Operator Logs + +```bash +oc logs -f deployment/console-operator -n openshift-console-operator +``` + +### Describe Deployments + +```bash +oc describe deployment console -n openshift-console +``` + +### Check Console Pods + +```bash +oc get pods -n openshift-console +``` + +### Check Operator Config + +```bash +oc get console.operator.openshift.io cluster -o yaml +``` + +### Check Cluster Console Config + +```bash +oc get console.config.openshift.io cluster -o yaml +``` + +## Development Workflow + +### Against a Development Cluster + +1. **Disable CVO management:** + ```bash + oc apply -f examples/cvo-unmanage-operator.yaml + ``` + +2. **Scale down default operator:** + ```bash + oc scale --replicas 0 deployment console-operator -n openshift-console-operator + ``` + +3. **Build and push your image:** + ```bash + docker build -f Dockerfile.ocp -t quay.io//console-operator:latest . + docker push quay.io//console-operator:latest + ``` + +4. **Deploy with custom image** using modified `examples/07-operator-alt-image.yaml` + +5. **Delete pod to pull new image:** + ```bash + oc delete pod -l name=console-operator -n openshift-console-operator + ``` + +## Container Build + +```bash +# Build container image +docker build -f Dockerfile.ocp -t quay.io//console-operator:latest . + +# Push to registry +docker push quay.io//console-operator:latest +``` + +## Building for macOS Developers + +When targeting Linux from macOS: + +```bash +OS_DEBUG=true OS_BUILD_PLATFORMS=linux/amd64 make +``` + +The binary output is: `./_output/local/bin///console` +## Manual Build with Version Info + +To build the binary directly with proper version information embedded: + +```bash +go build -ldflags "-X $GO_PACKAGE/pkg/version.versionFromGit=$(git describe --long --tags --abbrev=7 --match 'v[0-9]*')" -tags="ocp" -o console ./cmd/console