Skip to content
This repository was archived by the owner on Sep 9, 2026. It is now read-only.

OSAC-874: Remove EDA provider and webhook client from osac-operator - #272

Merged
tchughesiv merged 12 commits into
osac-project:mainfrom
tchughesiv:OSAC-874-remove-eda-provider
Jun 4, 2026
Merged

tchughesiv merged 12 commits into
osac-project:mainfrom
tchughesiv:OSAC-874-remove-eda-provider

Conversation

@tchughesiv

@tchughesiv tchughesiv commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Removes the legacy EDA webhook provisioning provider from osac-operator. The operator now always uses AAP direct REST API integration. Provider selection configuration is deleted entirely (OSAC_PROVISIONING_PROVIDER, webhook URLs, OSAC_MINIMUM_REQUEST_INTERVAL).

Changes

  • Delete eda_provider, webhook_common, and internal/webhook packages (~990 lines)
  • Simplify provisioning factory and startup to AAP-only
  • Remove EDA job-ID compatibility paths from aap_provider
  • Update controllers, tests, CRD comments, Helm chart, and in-repo docs
  • Rebased onto current main (includes fix: Add missing config/testing/console-proxy kustomize overlay #276 test-kustomize overlay)

Related PRs

Jira

https://redhat.atlassian.net/browse/OSAC-874

Validation (2026-06-02, HEAD be521ed)

  • Rebased onto origin/main — 0 commits behind
  • make fmt, make lint, make build, make test
  • make manifests generate — no drift
  • make check-helm-crds
  • make test-kustomize — pass (includes config/testing/console-proxy via fix: Add missing config/testing/console-proxy kustomize overlay #276)
  • Grep clean for EDA webhook / provider selection references
  • make test-smoke

Acceptance criteria

  • EDA provider code fully removed
  • provisioning-provider flag removed (not single-option aap)
  • All unit tests pass
  • Integration manifest validation pass (test-kustomize, check-helm-crds); smoke deferred
  • No EDA webhook references in operator codebase

Summary by CodeRabbit

  • Documentation

    • Provisioning docs, samples, and README simplified to AAP-only provisioning and required AAP environment variables; EDA/webhook guidance removed
    • CRD status/job field descriptions clarified to reference AAP job IDs and AAP deprovision behavior
  • Refactor

    • Controller and provisioning wiring consolidated around direct AAP REST integration; provider selection and webhook/minimum-request-interval flows removed
    • Helm/operator values and deployment env restructured to use dedicated AAP configuration keys and env vars

@openshift-ci-robot

openshift-ci-robot commented Jun 1, 2026

Copy link
Copy Markdown

@tchughesiv: This pull request references OSAC-874 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

Removes the legacy EDA webhook provisioning provider from osac-operator. The operator now always uses AAP direct REST API integration. Provider selection configuration is deleted entirely (OSAC_PROVISIONING_PROVIDER, webhook URLs, OSAC_MINIMUM_REQUEST_INTERVAL).

Changes

  • Delete eda_provider, webhook_common, and internal/webhook packages (~990 lines)
  • Simplify provisioning factory and startup to AAP-only
  • Remove EDA job-ID compatibility paths from aap_provider
  • Update controllers, tests, CRD comments, Helm chart, and in-repo docs
  • Includes rebased Makefile GOTOOLCHAIN fix (Go 1.26.2)

Related PRs

  • osac-installer: (pending — depends on this PR for submodule commit)
  • docs: (pending — parallel)

Jira

https://redhat.atlassian.net/browse/OSAC-874

Test plan

  • make fmt, make lint, make build, make test
  • make manifests generate — no drift
  • Grep clean for EDA webhook / provider selection references
  • make test-kustomize — pre-existing failure on main (missing console-proxy test config)
  • make test-smoke — not run (requires kind)

Acceptance criteria

  • EDA provider code fully removed
  • provisioning-provider flag removed (not single-option aap)
  • All unit tests pass
  • Integration tests (test-kustomize pre-existing fail; smoke deferred)
  • No EDA webhook references in operator codebase

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci

openshift-ci Bot commented Jun 1, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@tchughesiv, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 11 minutes and 56 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 66456705-311c-4c89-9199-bc38e312e2ff

📥 Commits

Reviewing files that changed from the base of the PR and between 18937b6 and 8c16fb9.

📒 Files selected for processing (45)
  • .claude/rules/configuration.md
  • .claude/rules/controller-patterns.md
  • AGENTS.md
  • README.md
  • api/v1alpha1/job_types.go
  • charts/operator-crds/templates/osac.openshift.io_clusterorders.yaml
  • charts/operator-crds/templates/osac.openshift.io_computeinstances.yaml
  • charts/operator-crds/templates/osac.openshift.io_publicipattachments.yaml
  • charts/operator-crds/templates/osac.openshift.io_publicippools.yaml
  • charts/operator-crds/templates/osac.openshift.io_publicips.yaml
  • charts/operator-crds/templates/osac.openshift.io_securitygroups.yaml
  • charts/operator-crds/templates/osac.openshift.io_subnets.yaml
  • charts/operator-crds/templates/osac.openshift.io_tenants.yaml
  • charts/operator-crds/templates/osac.openshift.io_virtualnetworks.yaml
  • charts/operator/templates/deployment.yaml
  • charts/operator/values.yaml
  • cmd/main.go
  • config/crd/bases/osac.openshift.io_clusterorders.yaml
  • config/crd/bases/osac.openshift.io_computeinstances.yaml
  • config/crd/bases/osac.openshift.io_publicipattachments.yaml
  • config/crd/bases/osac.openshift.io_publicippools.yaml
  • config/crd/bases/osac.openshift.io_publicips.yaml
  • config/crd/bases/osac.openshift.io_securitygroups.yaml
  • config/crd/bases/osac.openshift.io_subnets.yaml
  • config/crd/bases/osac.openshift.io_tenants.yaml
  • config/crd/bases/osac.openshift.io_virtualnetworks.yaml
  • config/manager/manager.yaml
  • config/samples/osac-config-secret.yaml
  • internal/controller/clusterorder_controller_test.go
  • internal/controller/computeinstance_controller.go
  • internal/controller/computeinstance_controller_test.go
  • internal/controller/computeinstance_integration_test.go
  • internal/controller/computeinstance_provisioning_test.go
  • internal/controller/suite_test.go
  • internal/controller/webhook_common.go
  • internal/controller/webhook_common_test.go
  • internal/webhook/types.go
  • pkg/provisioning/aap_provider.go
  • pkg/provisioning/aap_provider_test.go
  • pkg/provisioning/eda_provider.go
  • pkg/provisioning/eda_provider_test.go
  • pkg/provisioning/factory.go
  • pkg/provisioning/factory_test.go
  • pkg/provisioning/provider.go
  • pkg/provisioning/provision_lifecycle.go

Walkthrough

This PR removes EDA/webhook provisioning and standardizes controllers, wiring, charts, CRDs, tests, and docs on direct AAP REST API provisioning. Risk: Medium — controller wiring and deprovision timing changed; verify AAP env, templates, and migration of webhook-based deployments.

Changes

EDA Removal and AAP Standardization

Layer / File(s) Summary
Docs & samples
.claude/rules/configuration.md, AGENTS.md, README.md, config/samples/osac-config-secret.yaml
Renamed “AAP Provider” to “AAP Provisioning”, removed EDA/provider-selection guidance and OSAC_MINIMUM_REQUEST_INTERVAL references, and documented direct AAP REST API integration.
API & CRD wording
api/v1alpha1/job_types.go, config/crd/bases/*, charts/operator-crds/templates/*
Updated JobStatus jobID and blockDeletionOnFailure comments and OpenAPI schema descriptions across CRDs to reference AAP-only behavior.
Helm & manifests
charts/operator/values.yaml, charts/operator/templates/deployment.yaml, config/manager/manager.yaml
Removed provisioning.provider and OSAC_PROVISIONING_PROVIDER env entries; introduced top-level aap config values.
cmd/main.go runtime wiring
cmd/main.go
Removed EDA/webhook factory and --minimum-request-interval; added createAAPProviderFromEnv and setupProvisioningController; updated controller setup signatures and call sites to use AAP-only provider creation.
Provisioning contract & factory
pkg/provisioning/provider.go, pkg/provisioning/factory.go, pkg/provisioning/factory_test.go
Removed exported ProviderType and EDA fields; ProviderConfig is now AAP-only and NewProvider always returns an AAPProvider.
AAP provider cleanup
pkg/provisioning/aap_provider.go, pkg/provisioning/aap_provider_test.go
Deleted EDA-specific readiness helpers and EDA job-id special-case; deprovision readiness now polls/query AAP job status; tests updated for cancelling running AAP jobs.
EDA & webhook removal
pkg/provisioning/eda_provider.go (deleted), internal/controller/webhook_common.go (deleted), related tests (deleted)
Removed EDA provider implementation, webhook client, inflight cache, and related tests and types.
Controller behavior & tests
internal/controller/computeinstance_controller.go, internal/controller/*_test.go, internal/controller/suite_test.go
Dropped custom PollCallbacks.IsCompleted, replaced noop webhook test stub with noop provisioning provider, and changed tests to use literal provider name "aap".

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

lgtm

Suggested reviewers

  • adriengentil
  • eranco74
  • danmanor
  • tzumainn

Sequence Diagram (high-level provisioning flow)

sequenceDiagram
  participant Controller
  participant AAPClient
  participant KubernetesAPI
  Controller->>AAPClient: TriggerProvision / launch job template
  AAPClient-->>Controller: jobID
  Controller->>KubernetesAPI: update CR status with jobID
  Controller->>AAPClient: RunProvisioningLifecycle / GetJob (poll)
  AAPClient-->>Controller: job status (running/failed/success)
  Controller->>KubernetesAPI: update CR status/conditions on poll result
  Note right of Controller: OnFailed callback -> set Failed if no VM reference yet
Loading

Security-focused risk summary: Risk severity — Medium. Impact: controller wiring and deprovision timing changes could cause delayed or skipped cleanup of cloud resources if AAP credentials/templates are misconfigured; verify AAP credentials, template names, and that deployments migrated from webhook/EDA are reconfigured to use AAP env vars.

"One provider now steers the flow,
Webhooks gone, AAP in the know.
Jobs launched, polled, and status set,
Tests and charts in tidy net.
🚀 controllers march, resources kept in tow."

🚥 Pre-merge checks | ✅ 11
✅ Passed checks (11 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: removal of EDA provider and webhook client from the osac-operator codebase.
Docstring Coverage ✅ Passed Docstring coverage is 92.31% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No-Hardcoded-Secrets ✅ Passed No hardcoded secrets found. All credentials (AAP token/URL) are environment variables with empty defaults; sample config uses placeholders in comments. No tokens are logged or embedded in URLs.
No-Weak-Crypto ✅ Passed No weak cryptographic implementations found. PR removes code (EDA/webhook) without introducing MD5, SHA1, DES, RC4, 3DES, Blowfish, ECB, custom crypto, or non-constant-time secret comparisons.
No-Injection-Vectors ✅ Passed No injection vectors found. Modified files show no SQL concatenation, shell execution, eval/exec, unsafe deserialization, or improper URL construction. Webhook code with SSRF risk was removed.
Container-Privileges ✅ Passed No privileged container settings found; all manifests enforce runAsNonRoot, allowPrivilegeEscalation: false, and drop ALL capabilities.
No-Sensitive-Data-In-Logs ✅ Passed PR introduces no new logging of sensitive data. Logging changes only log job IDs and state transitions. No tokens, credentials, or PII are exposed in new logging statements.
Ai-Attribution ✅ Passed Commit 18937b6 has no AI-attribution trailers (Assisted-by/Generated-by). Author is Tommy Hughes (Red Hat). .ai-bot/ files are AI tool configuration only, not evidence of AI-generated code.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cmd/main.go (1)

407-417: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Risk: Inconsistent AAP credential validation may cause deferred runtime failures.

setupTenantController explicitly checks aapURL != "" && aapToken != "" before creating a provider (allowing graceful no-op mode), but setupNetworkingControllers creates aapClient and networkingProvider unconditionally. If AAP credentials are missing, networking controllers will start successfully but fail at runtime when provisioning is attempted.

Severity: Low — No security vulnerability, but operational reliability is affected. Misconfiguration manifests as cryptic API errors during reconciliation rather than clear startup validation.

Consider harmonizing the validation pattern: either validate early and fail fast for all controllers, or document that networking controllers require AAP configuration while tenant can operate without it.

🔧 Optional: Add early validation for networking AAP configuration
 	// Get provider configuration
 	aapURL := os.Getenv(envAAPURL)
 	aapToken := os.Getenv(envAAPToken)
+	if aapURL == "" || aapToken == "" {
+		return fmt.Errorf("networking controllers require AAP configuration: %s and %s must be set", envAAPURL, envAAPToken)
+	}
 	aapInsecureSkipVerify := helpers.GetEnvWithDefault(envAAPInsecureSkipVerify, false)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/main.go` around lines 407 - 417, The networking setup creates aapClient
and networkingProvider unconditionally (call sites: aap.NewClient and
provisioning.NewAAPProviderWithPrefix in setupNetworkingControllers) while
setupTenantController guards on aapURL != "" && aapToken != ""; update
setupNetworkingControllers to check the AAP env vars (aapURL and aapToken)
before creating the client/provider and either (a) skip creating the provider
and initialize networking controllers in no-op mode when creds are missing or
(b) return an error to fail fast—mirror the credential check used by
setupTenantController so runtime reconciliations don’t fail unexpectedly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.claude/rules/configuration.md:
- Around line 5-6: Add a blank line immediately after the heading "## AAP
Provisioning" so the heading is followed by an empty line before the list item
`OSAC_AAP_URL`; edit the block containing the "## AAP Provisioning" heading and
insert one newline to satisfy MD022 and prevent markdown lint/CI failures.

---

Outside diff comments:
In `@cmd/main.go`:
- Around line 407-417: The networking setup creates aapClient and
networkingProvider unconditionally (call sites: aap.NewClient and
provisioning.NewAAPProviderWithPrefix in setupNetworkingControllers) while
setupTenantController guards on aapURL != "" && aapToken != ""; update
setupNetworkingControllers to check the AAP env vars (aapURL and aapToken)
before creating the client/provider and either (a) skip creating the provider
and initialize networking controllers in no-op mode when creds are missing or
(b) return an error to fail fast—mirror the credential check used by
setupTenantController so runtime reconciliations don’t fail unexpectedly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 663c6613-6876-4c1f-8354-c57fbd797bde

📥 Commits

Reviewing files that changed from the base of the PR and between b7409bf and be521ed.

📒 Files selected for processing (44)
  • .claude/rules/configuration.md
  • AGENTS.md
  • README.md
  • api/v1alpha1/job_types.go
  • charts/operator-crds/templates/osac.openshift.io_clusterorders.yaml
  • charts/operator-crds/templates/osac.openshift.io_computeinstances.yaml
  • charts/operator-crds/templates/osac.openshift.io_publicipattachments.yaml
  • charts/operator-crds/templates/osac.openshift.io_publicippools.yaml
  • charts/operator-crds/templates/osac.openshift.io_publicips.yaml
  • charts/operator-crds/templates/osac.openshift.io_securitygroups.yaml
  • charts/operator-crds/templates/osac.openshift.io_subnets.yaml
  • charts/operator-crds/templates/osac.openshift.io_tenants.yaml
  • charts/operator-crds/templates/osac.openshift.io_virtualnetworks.yaml
  • charts/operator/templates/deployment.yaml
  • charts/operator/values.yaml
  • cmd/main.go
  • config/crd/bases/osac.openshift.io_clusterorders.yaml
  • config/crd/bases/osac.openshift.io_computeinstances.yaml
  • config/crd/bases/osac.openshift.io_publicipattachments.yaml
  • config/crd/bases/osac.openshift.io_publicippools.yaml
  • config/crd/bases/osac.openshift.io_publicips.yaml
  • config/crd/bases/osac.openshift.io_securitygroups.yaml
  • config/crd/bases/osac.openshift.io_subnets.yaml
  • config/crd/bases/osac.openshift.io_tenants.yaml
  • config/crd/bases/osac.openshift.io_virtualnetworks.yaml
  • config/manager/manager.yaml
  • config/samples/osac-config-secret.yaml
  • internal/controller/clusterorder_controller_test.go
  • internal/controller/computeinstance_controller.go
  • internal/controller/computeinstance_controller_test.go
  • internal/controller/computeinstance_integration_test.go
  • internal/controller/computeinstance_provisioning_test.go
  • internal/controller/suite_test.go
  • internal/controller/webhook_common.go
  • internal/controller/webhook_common_test.go
  • internal/webhook/types.go
  • pkg/provisioning/aap_provider.go
  • pkg/provisioning/aap_provider_test.go
  • pkg/provisioning/eda_provider.go
  • pkg/provisioning/eda_provider_test.go
  • pkg/provisioning/factory.go
  • pkg/provisioning/factory_test.go
  • pkg/provisioning/provider.go
  • pkg/provisioning/provision_lifecycle.go
💤 Files with no reviewable changes (10)
  • internal/controller/webhook_common_test.go
  • charts/operator/values.yaml
  • internal/controller/webhook_common.go
  • pkg/provisioning/eda_provider_test.go
  • internal/webhook/types.go
  • pkg/provisioning/eda_provider.go
  • config/manager/manager.yaml
  • pkg/provisioning/provision_lifecycle.go
  • internal/controller/computeinstance_controller.go
  • charts/operator/templates/deployment.yaml

Comment thread .claude/rules/configuration.md
@tchughesiv

tchughesiv commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

Thanks — valid observation, but deferring to a follow-up outside OSAC-874 scope.

The tenant controller’s optional AAP guard is intentional: tenant storage provisioning can run in no-op mode when AAP templates aren’t configured, while the tenant reconciler still manages namespace/UDN lifecycle.

Cluster, compute, and networking controllers all assume AAP is configured in production (installer overlays always set OSAC_AAP_URL / OSAC_AAP_TOKEN). Harmonizing fail-fast validation across every controller entrypoint would be a separate operational-hardening change, not part of this deletion/simplification story.

Happy to track that as a follow-up if we want consistent startup validation everywhere.

@tchughesiv

Copy link
Copy Markdown
Contributor Author

/retest

@tchughesiv
tchughesiv enabled auto-merge (squash) June 3, 2026 23:14
@tchughesiv

Copy link
Copy Markdown
Contributor Author

/retest

@tchughesiv

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@tchughesiv
tchughesiv disabled auto-merge June 4, 2026 01:14
@tchughesiv

Copy link
Copy Markdown
Contributor Author

/retest-required

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cmd/main.go (1)

406-432: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Major: networking controllers no longer fail fast on missing AAP config.

Lines 406-417 now build the shared networking provider through aap.NewClient(...) + provisioning.NewAAPProviderWithPrefix(...), which skips the validating path used by createAAPProvider(...). If OSAC_AAP_URL or OSAC_AAP_TOKEN is empty/bad, the manager can still start and every networking reconcile fails later instead of aborting at startup. That widens the blast radius of a bad deployment and makes the misconfiguration much harder to detect.

Suggested fix
  aapURL := os.Getenv(envAAPURL)
  aapToken := os.Getenv(envAAPToken)
+ if aapURL == "" || aapToken == "" {
+ 	return fmt.Errorf("%s and %s must be set when networking controllers are enabled", envAAPURL, envAAPToken)
+ }
  aapInsecureSkipVerify := helpers.GetEnvWithDefault(envAAPInsecureSkipVerify, false)
  statusPollInterval := helpers.GetEnvWithDefault(envAAPStatusPollInterval, provisioning.DefaultStatusPollInterval)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/main.go` around lines 406 - 432, The code currently constructs the AAP
client and networking provider directly (aap.NewClient +
provisioning.NewAAPProviderWithPrefix) which skips startup validation; instead
call the existing createAAPProvider(...) helper to build and validate the shared
networking provider (and obtain the validated aap client) and propagate any
error to abort startup; then use the returned/validated aap client when creating
publicIPAttachmentProvider (so replace direct aap.NewClient and
provisioning.NewAAPProviderWithPrefix usages with the createAAPProvider call and
error handling).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Around line 30-33: The README overstates that "All controllers provision
infrastructure via direct Ansible Automation Platform REST API integration";
change this wording to clarify that only AAP-backed resource controllers require
direct AAP REST integration while tenant-only deployments and gRPC-only feedback
controllers do not; update the AAP provisioning section (the paragraph
mentioning controller behavior) to explicitly note that setupTenantController
can run without an AAP provider and that feedback controllers use gRPC-only, so
the document does not claim AAP is universally required.

---

Outside diff comments:
In `@cmd/main.go`:
- Around line 406-432: The code currently constructs the AAP client and
networking provider directly (aap.NewClient +
provisioning.NewAAPProviderWithPrefix) which skips startup validation; instead
call the existing createAAPProvider(...) helper to build and validate the shared
networking provider (and obtain the validated aap client) and propagate any
error to abort startup; then use the returned/validated aap client when creating
publicIPAttachmentProvider (so replace direct aap.NewClient and
provisioning.NewAAPProviderWithPrefix usages with the createAAPProvider call and
error handling).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 10417f92-9cab-4727-8c79-b48687c8aee9

📥 Commits

Reviewing files that changed from the base of the PR and between b7409bf and 5485571.

📒 Files selected for processing (44)
  • .claude/rules/configuration.md
  • AGENTS.md
  • README.md
  • api/v1alpha1/job_types.go
  • charts/operator-crds/templates/osac.openshift.io_clusterorders.yaml
  • charts/operator-crds/templates/osac.openshift.io_computeinstances.yaml
  • charts/operator-crds/templates/osac.openshift.io_publicipattachments.yaml
  • charts/operator-crds/templates/osac.openshift.io_publicippools.yaml
  • charts/operator-crds/templates/osac.openshift.io_publicips.yaml
  • charts/operator-crds/templates/osac.openshift.io_securitygroups.yaml
  • charts/operator-crds/templates/osac.openshift.io_subnets.yaml
  • charts/operator-crds/templates/osac.openshift.io_tenants.yaml
  • charts/operator-crds/templates/osac.openshift.io_virtualnetworks.yaml
  • charts/operator/templates/deployment.yaml
  • charts/operator/values.yaml
  • cmd/main.go
  • config/crd/bases/osac.openshift.io_clusterorders.yaml
  • config/crd/bases/osac.openshift.io_computeinstances.yaml
  • config/crd/bases/osac.openshift.io_publicipattachments.yaml
  • config/crd/bases/osac.openshift.io_publicippools.yaml
  • config/crd/bases/osac.openshift.io_publicips.yaml
  • config/crd/bases/osac.openshift.io_securitygroups.yaml
  • config/crd/bases/osac.openshift.io_subnets.yaml
  • config/crd/bases/osac.openshift.io_tenants.yaml
  • config/crd/bases/osac.openshift.io_virtualnetworks.yaml
  • config/manager/manager.yaml
  • config/samples/osac-config-secret.yaml
  • internal/controller/clusterorder_controller_test.go
  • internal/controller/computeinstance_controller.go
  • internal/controller/computeinstance_controller_test.go
  • internal/controller/computeinstance_integration_test.go
  • internal/controller/computeinstance_provisioning_test.go
  • internal/controller/suite_test.go
  • internal/controller/webhook_common.go
  • internal/controller/webhook_common_test.go
  • internal/webhook/types.go
  • pkg/provisioning/aap_provider.go
  • pkg/provisioning/aap_provider_test.go
  • pkg/provisioning/eda_provider.go
  • pkg/provisioning/eda_provider_test.go
  • pkg/provisioning/factory.go
  • pkg/provisioning/factory_test.go
  • pkg/provisioning/provider.go
  • pkg/provisioning/provision_lifecycle.go
💤 Files with no reviewable changes (10)
  • charts/operator/values.yaml
  • config/manager/manager.yaml
  • internal/controller/webhook_common.go
  • pkg/provisioning/provision_lifecycle.go
  • charts/operator/templates/deployment.yaml
  • pkg/provisioning/eda_provider.go
  • internal/webhook/types.go
  • internal/controller/webhook_common_test.go
  • internal/controller/computeinstance_controller.go
  • pkg/provisioning/eda_provider_test.go

Comment thread README.md Outdated
@tchughesiv

Copy link
Copy Markdown
Contributor Author

Re: cmd/main.go networking fail-fast (outside-diff comment from full review) — same answer as earlier.

Deferring harmonized AAP credential validation to a follow-up outside OSAC-874 scope. The tenant controller’s optional AAP guard is intentional (storage provisioning no-op without creds; namespace/UDN lifecycle still runs). Cluster, compute, and networking controllers assume AAP is configured in production — installer overlays always set OSAC_AAP_URL / OSAC_AAP_TOKEN. Adding fail-fast checks across every entrypoint is operational hardening, not EDA removal.

Also addressed the README wording in 71bc7b1 from the inline comment in this review round.

@tchughesiv

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@tchughesiv

Copy link
Copy Markdown
Contributor Author

/retest-required

@akshaynadkarni akshaynadkarni left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tchughesiv Left a few nit comments. PTAL.
Thanks for working on this.

@openshift-ci

openshift-ci Bot commented Jun 4, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: akshaynadkarni, jhernand, tchughesiv

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:
  • OWNERS [akshaynadkarni,jhernand]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot removed the lgtm label Jun 4, 2026
@akshaynadkarni

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm label Jun 4, 2026
@eranco74

eranco74 commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

/lgtm

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
cmd/main.go (1)

208-236: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Major: required AAP settings are not validated before these controllers start.

createAAPProvider() and the networking bootstrap both build an AAP client even when OSAC_AAP_URL and OSAC_AAP_TOKEN are empty. After this PR, cluster/compute/networking no longer have a non-AAP fallback, so the operator now boots successfully and only fails later on reconcile with opaque downstream errors.

Suggested guard
+func validateAAPConfig(aapURL, aapToken string) error {
+	if aapURL == "" || aapToken == "" {
+		return fmt.Errorf("%s and %s must be set", envAAPURL, envAAPToken)
+	}
+	return nil
+}
+
 func createAAPProvider(
 	aapURL, aapToken, provisionTemplate, deprovisionTemplate, templatePrefix string,
 	aapInsecureSkipVerify bool,
 ) (provisioning.ProvisioningProvider, time.Duration, error) {
+	if err := validateAAPConfig(aapURL, aapToken); err != nil {
+		return nil, 0, err
+	}
+
 	statusPollInterval := helpers.GetEnvWithDefault(envAAPStatusPollInterval, provisioning.DefaultStatusPollInterval)
 	aapURL := os.Getenv(envAAPURL)
 	aapToken := os.Getenv(envAAPToken)
+	if err := validateAAPConfig(aapURL, aapToken); err != nil {
+		return err
+	}
 	aapInsecureSkipVerify := helpers.GetEnvWithDefault(envAAPInsecureSkipVerify, false)

Also applies to: 406-417

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/main.go` around lines 208 - 236, createAAPProvider currently constructs
an AAP client even when required settings are empty; before calling
aap.NewClient (and similarly before the networking bootstrap that also
constructs an AAP client), validate the required AAP configuration (e.g.,
OSAC_AAP_URL and OSAC_AAP_TOKEN / the aapURL and aapToken parameters) and return
a clear error if they are missing/empty instead of proceeding; update
createAAPProvider (and the analogous bootstrap code that calls aap.NewClient) to
check these values up-front and fail fast with a descriptive error so
controllers do not start with an invalid AAP client.
pkg/provisioning/aap_provider.go (1)

193-223: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Minor: HTTP 405 from CancelJob is currently treated as “wait”, not “already terminal”.

cancelProvisionJob() converts *aap.MethodNotAllowedError to nil, so the branch at Line 194-Line 200 can never fire. If the provision job flips terminal between the status GET and cancel POST, deletion is delayed by an unnecessary extra poll interval instead of proceeding immediately.

Suggested fix
-func (p *AAPProvider) cancelProvisionJob(ctx context.Context, jobID string) error {
+func (p *AAPProvider) cancelProvisionJob(ctx context.Context, jobID string) (bool, error) {
 	err := p.client.CancelJob(ctx, jobID)
 	if err != nil {
 		var methodNotAllowedErr *aap.MethodNotAllowedError
 		if errors.As(err, &methodNotAllowedErr) {
-			return nil
+			return true, nil
 		}
-		return fmt.Errorf("failed to cancel job: %w", err)
+		return false, fmt.Errorf("failed to cancel job: %w", err)
 	}
-
-	return nil
+	return false, nil
 }
-	if err := p.cancelProvisionJob(ctx, latestProvisionJob.JobID); err != nil {
+	alreadyTerminal, err := p.cancelProvisionJob(ctx, latestProvisionJob.JobID)
+	if err != nil {
 		var methodNotAllowedErr *aap.MethodNotAllowedError
 		if !errors.As(err, &methodNotAllowedErr) {
 			return false, &status, fmt.Errorf("failed to cancel provision job: %w", err)
 		}
-		// 405 means already terminal, proceed
-		log.Info("job cancel returned 405 (already terminal), ready to deprovision", "jobID", latestProvisionJob.JobID)
-		return true, &status, nil
 	}
+	if alreadyTerminal {
+		log.Info("job cancel returned 405 (already terminal), ready to deprovision", "jobID", latestProvisionJob.JobID)
+		return true, &status, nil
+	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/provisioning/aap_provider.go` around lines 193 - 223, The
cancelProvisionJob function currently swallows *aap.MethodNotAllowedError by
returning nil, preventing the caller (the provision cancellation branch that
checks errors.As(err, &methodNotAllowedErr)) from detecting a 405 and proceeding
immediately; change cancelProvisionJob (in AAPProvider) to return the original
*aap.MethodNotAllowedError (or wrap and return it) instead of nil when errors.As
detects it so the caller's errors.As(check) on the result of
cancelProvisionJob(ctx, latestProvisionJob.JobID) can detect the 405 and take
the "already terminal" path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/provisioning/aap_provider_test.go`:
- Around line 555-589: Add a parallel test Context that simulates the AAP
cancelJob call returning an HTTP 405 (job already terminal) by setting
aapClient.cancelJobFunc to return an error that encodes status 405, then call
provider.TriggerDeprovision(ctx, instance) and assert the code path for the 405
case: expect the provider to treat the job as terminal and proceed to the
immediate-delete branch (i.e., expect result.Action to be
provisioning.DeprovisionImmediate and that ProvisionJobStatus reflects no
running job), using the same symbols used in the existing test
(provider.TriggerDeprovision and aapClient.cancelJobFunc).

---

Outside diff comments:
In `@cmd/main.go`:
- Around line 208-236: createAAPProvider currently constructs an AAP client even
when required settings are empty; before calling aap.NewClient (and similarly
before the networking bootstrap that also constructs an AAP client), validate
the required AAP configuration (e.g., OSAC_AAP_URL and OSAC_AAP_TOKEN / the
aapURL and aapToken parameters) and return a clear error if they are
missing/empty instead of proceeding; update createAAPProvider (and the analogous
bootstrap code that calls aap.NewClient) to check these values up-front and fail
fast with a descriptive error so controllers do not start with an invalid AAP
client.

In `@pkg/provisioning/aap_provider.go`:
- Around line 193-223: The cancelProvisionJob function currently swallows
*aap.MethodNotAllowedError by returning nil, preventing the caller (the
provision cancellation branch that checks errors.As(err, &methodNotAllowedErr))
from detecting a 405 and proceeding immediately; change cancelProvisionJob (in
AAPProvider) to return the original *aap.MethodNotAllowedError (or wrap and
return it) instead of nil when errors.As detects it so the caller's
errors.As(check) on the result of cancelProvisionJob(ctx,
latestProvisionJob.JobID) can detect the 405 and take the "already terminal"
path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: f4e4d902-8bdf-4ff8-9a17-5b70ffe26ebf

📥 Commits

Reviewing files that changed from the base of the PR and between 5485571 and 18937b6.

📒 Files selected for processing (45)
  • .claude/rules/configuration.md
  • .claude/rules/controller-patterns.md
  • AGENTS.md
  • README.md
  • api/v1alpha1/job_types.go
  • charts/operator-crds/templates/osac.openshift.io_clusterorders.yaml
  • charts/operator-crds/templates/osac.openshift.io_computeinstances.yaml
  • charts/operator-crds/templates/osac.openshift.io_publicipattachments.yaml
  • charts/operator-crds/templates/osac.openshift.io_publicippools.yaml
  • charts/operator-crds/templates/osac.openshift.io_publicips.yaml
  • charts/operator-crds/templates/osac.openshift.io_securitygroups.yaml
  • charts/operator-crds/templates/osac.openshift.io_subnets.yaml
  • charts/operator-crds/templates/osac.openshift.io_tenants.yaml
  • charts/operator-crds/templates/osac.openshift.io_virtualnetworks.yaml
  • charts/operator/templates/deployment.yaml
  • charts/operator/values.yaml
  • cmd/main.go
  • config/crd/bases/osac.openshift.io_clusterorders.yaml
  • config/crd/bases/osac.openshift.io_computeinstances.yaml
  • config/crd/bases/osac.openshift.io_publicipattachments.yaml
  • config/crd/bases/osac.openshift.io_publicippools.yaml
  • config/crd/bases/osac.openshift.io_publicips.yaml
  • config/crd/bases/osac.openshift.io_securitygroups.yaml
  • config/crd/bases/osac.openshift.io_subnets.yaml
  • config/crd/bases/osac.openshift.io_tenants.yaml
  • config/crd/bases/osac.openshift.io_virtualnetworks.yaml
  • config/manager/manager.yaml
  • config/samples/osac-config-secret.yaml
  • internal/controller/clusterorder_controller_test.go
  • internal/controller/computeinstance_controller.go
  • internal/controller/computeinstance_controller_test.go
  • internal/controller/computeinstance_integration_test.go
  • internal/controller/computeinstance_provisioning_test.go
  • internal/controller/suite_test.go
  • internal/controller/webhook_common.go
  • internal/controller/webhook_common_test.go
  • internal/webhook/types.go
  • pkg/provisioning/aap_provider.go
  • pkg/provisioning/aap_provider_test.go
  • pkg/provisioning/eda_provider.go
  • pkg/provisioning/eda_provider_test.go
  • pkg/provisioning/factory.go
  • pkg/provisioning/factory_test.go
  • pkg/provisioning/provider.go
  • pkg/provisioning/provision_lifecycle.go
💤 Files with no reviewable changes (9)
  • charts/operator/templates/deployment.yaml
  • internal/controller/webhook_common.go
  • internal/controller/webhook_common_test.go
  • internal/webhook/types.go
  • config/manager/manager.yaml
  • pkg/provisioning/eda_provider_test.go
  • pkg/provisioning/eda_provider.go
  • pkg/provisioning/provision_lifecycle.go
  • charts/operator/values.yaml

Comment thread pkg/provisioning/aap_provider_test.go
@tchughesiv

tchughesiv commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

Re: latest CodeRabbit review (outside-diff items):

  • aap_provider.go cancel 405 — fixed in the commit above; good catch that swallowing MethodNotAllowedError made the caller branch unreachable.
  • cmd/main.go AAP fail-fast validation — deferring outside OSAC-874 (same rationale as earlier): production installs always set AAP creds; harmonizing startup validation is follow-up hardening.

@openshift-ci openshift-ci Bot removed the lgtm label Jun 4, 2026
@openshift-ci

openshift-ci Bot commented Jun 4, 2026

Copy link
Copy Markdown

New changes are detected. LGTM label has been removed.

@tchughesiv
tchughesiv force-pushed the OSAC-874-remove-eda-provider branch from b2404f8 to 9f02f51 Compare June 4, 2026 15:52
// Job is already in terminal state, nothing to cancel
return nil
// Propagate 405 so the caller can proceed immediately instead of waiting another poll.
return err

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tchughesiv Returning 405 here seems logical, especially since the caller is explicity checking for it:
https://github.com/tchughesiv/osac-operator/blame/9f02f51fc54da2d6248c0dca78bcc01ae14b922d/pkg/provisioning/aap_provider.go#L192-L199

Please update the comment a few lines above: Line 209, Line 214, since we are no longer returning nil.

I'm not sure why "405: Method Not Allowed" was equating to "job is already in terminal state". @tzvatot What was your thought process here?

@tchughesiv tchughesiv Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@tchughesiv
tchughesiv merged commit 0217b64 into osac-project:main Jun 4, 2026
10 of 11 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants