Skip to content

OADP-8446: add namesapce resource policy for oadp#2304

Open
weshayutin wants to merge 2 commits into
openshift:oadp-devfrom
weshayutin:OADP-8446
Open

OADP-8446: add namesapce resource policy for oadp#2304
weshayutin wants to merge 2 commits into
openshift:oadp-devfrom
weshayutin:OADP-8446

Conversation

@weshayutin

@weshayutin weshayutin commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Added automatic creation of a namespace resource quota with default limits for pods, CPU requests, and memory requests.
    • Preserves administrator-customized quota values and recreates the quota if it is deleted.
    • Expanded restore and configuration options in the Data Protection Application schema.
  • Documentation

    • Added resource quota configuration and design documentation.
  • Bug Fixes

    • Updated operator permissions to manage resource quota visibility and creation.

weshayutin and others added 2 commits July 16, 2026 09:45
Signed-off-by: Wesley Hayutin <weshayutin@gmail.com>
@weshayutin weshayutin changed the title Oadp 8446 OADP-8446: add namesapce resource policy for oadp Jul 16, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 16, 2026

Copy link
Copy Markdown

@weshayutin: This pull request references OADP-8446 which is a valid jira issue.

Details

In response to this:

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-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 16, 2026
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

The operator now ensures an oadp-resource-quota exists in each DPA namespace using create-if-absent behavior. RBAC, tests, configuration examples, documentation, generated manifests, and expanded CRD schema content are included.

Changes

ResourceQuota support

Layer / File(s) Summary
ResourceQuota contract and operator guidance
config/quota/resource_quota.yaml, docs/config/resource_quota.md, docs/design/...
Defines default pod and resource-request quotas, create-if-absent lifecycle behavior, administrator workflows, and implementation rules.
Quota reconciliation and validation
internal/controller/resourcequota.go, internal/controller/dataprotectionapplication_controller.go, internal/controller/resourcequota_test.go, config/rbac/role.yaml
Adds quota creation and preservation logic, wires it into DPA reconciliation, grants required permissions, and tests creation, customization preservation, and recreation.
Generated CRD and bundle updates
bundle/manifests/..., config/crd/bases/...
Updates generated RBAC and CSV metadata, normalizes CRD schema formatting, and includes expanded restore and operator configuration fields.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant DPAReconcile
  participant ReconcileResourceQuota
  participant KubernetesAPI
  DPAReconcile->>ReconcileResourceQuota: reconcile DPA namespace quota
  ReconcileResourceQuota->>KubernetesAPI: get oadp-resource-quota
  KubernetesAPI-->>ReconcileResourceQuota: existing quota or NotFound
  ReconcileResourceQuota->>KubernetesAPI: create default ResourceQuota when missing
  KubernetesAPI-->>ReconcileResourceQuota: created or AlreadyExists
Loading

Suggested reviewers: shubham-pampattiwar

🚥 Pre-merge checks | ✅ 13 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning No description was provided, so the required rationale and testing sections from the template are missing. Add the 'Why the changes were made' and 'How to test the changes made' sections, with issue context and verification steps.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (13 passed)
Check name Status Explanation
Title check ✅ Passed The title is relevant to the new namespace resource quota and RBAC changes, though it contains a typo and is a bit broad.
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.
Stable And Deterministic Test Names ✅ Passed The new test names are static, descriptive strings; none include dynamic values like timestamps, UUIDs, namespaces, or generated suffixes.
Test Structure And Quality ✅ Passed The new tests are isolated subtests over a fake client, each covers one ResourceQuota behavior, with no cluster waits or cleanup gaps, and they match existing unit-test patterns.
Microshift Test Compatibility ✅ Passed PASS: The only new test is a plain Go unit test; no Ginkgo e2e, MicroShift guards, or unsupported OpenShift APIs/features were added.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the only test is a Go unit test, so there are no SNO-specific multi-node assumptions to flag.
Topology-Aware Scheduling Compatibility ✅ Passed The PR only adds a namespace ResourceQuota, RBAC, and create-if-absent reconcile logic; no new affinity, spread, nodeSelector, or PDB constraints were introduced.
Ote Binary Stdout Contract ✅ Passed No modified process-level entrypoints write to stdout; new controller/test code only uses logr.Discard and no main/init/suite setup was touched.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the new test is a unit test using testing.T with no IPv4 assumptions or external network calls.
No-Weak-Crypto ✅ Passed No weak-crypto APIs or secret/token comparisons appear in the PR diff; new files only add ResourceQuota RBAC/reconcile logic and tests.
Container-Privileges ✅ Passed No changed manifest adds privileged/root/host* settings; the CSV container uses allowPrivilegeEscalation:false and runAsNonRoot:true.
No-Sensitive-Data-In-Logs ✅ Passed New logs are generic; they only include the DPA namespaced name and fixed ResourceQuota identifiers, with no secrets, tokens, PII, or customer data.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@openshift-ci
openshift-ci Bot requested review from Joeavaikath and mpryc July 16, 2026 16:02
@openshift-ci

openshift-ci Bot commented Jul 16, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: weshayutin
Once this PR has been reviewed and has the lgtm label, please assign sseago for approval. For more information see the Code Review Process.

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

Details Needs approval from an approver in each of these files:

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

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 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 `@internal/controller/resourcequota_test.go`:
- Around line 101-134: Add a ResourceQuota watch or ownership configuration in
SetupWithManager so deleting the quota enqueues the related DPA reconciliation
and restores defaults without a direct ReconcileResourceQuota call. Ensure the
watch maps the deleted ResourceQuota to the correct DataProtectionApplication.
🪄 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: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a9c35a98-fb3b-4da3-9373-69f992e4fe5b

📥 Commits

Reviewing files that changed from the base of the PR and between 03bb3b1 and aab5ea1.

📒 Files selected for processing (10)
  • bundle/manifests/oadp-operator.clusterserviceversion.yaml
  • bundle/manifests/oadp.openshift.io_dataprotectionapplications.yaml
  • config/crd/bases/oadp.openshift.io_dataprotectionapplications.yaml
  • config/quota/resource_quota.yaml
  • config/rbac/role.yaml
  • docs/config/resource_quota.md
  • docs/design/2026-07-16-resourcequota-design.md
  • internal/controller/dataprotectionapplication_controller.go
  • internal/controller/resourcequota.go
  • internal/controller/resourcequota_test.go

Comment on lines +101 to +134
t.Run("recreates defaults after admin deletes ResourceQuota", func(t *testing.T) {
fakeClient, err := getFakeClientFromObjects(dpa)
require.NoError(t, err)

r := &DataProtectionApplicationReconciler{
Client: fakeClient,
Scheme: fakeClient.Scheme(),
Context: context.Background(),
dpa: dpa,
}

_, err = r.ReconcileResourceQuota(logr.Discard())
require.NoError(t, err)

existing := &corev1.ResourceQuota{}
err = fakeClient.Get(context.Background(), types.NamespacedName{
Name: oadpResourceQuotaName,
Namespace: ns,
}, existing)
require.NoError(t, err)
require.NoError(t, fakeClient.Delete(context.Background(), existing))

cont, err := r.ReconcileResourceQuota(logr.Discard())
require.NoError(t, err)
assert.True(t, cont)

got := &corev1.ResourceQuota{}
err = fakeClient.Get(context.Background(), types.NamespacedName{
Name: oadpResourceQuotaName,
Namespace: ns,
}, got)
require.NoError(t, err)
assert.True(t, resource.MustParse("200").Equal(got.Spec.Hard[corev1.ResourcePods]))
})

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu

rg -n --type=go -C4 \
  'Owns\(&corev1\.ResourceQuota|Watches\([^)]*ResourceQuota|ResourceQuota\{\}' \
  .

Repository: openshift/oadp-operator

Length of output: 3824


🏁 Script executed:

#!/bin/bash
set -eu

printf '\n== resourcequota.go ==\n'
cat -n internal/controller/resourcequota.go

printf '\n== controller setup references ==\n'
rg -n --type=go -C3 'SetupWithManager|Owns\(|Watches\(|For\(|ResourceQuota|DataProtectionApplication' internal/controller

Repository: openshift/oadp-operator

Length of output: 50380


🏁 Script executed:

#!/bin/bash
set -eu

printf '\n== all references to ReconcileResourceQuota ==\n'
rg -n --type=go -C3 'ReconcileResourceQuota' .

printf '\n== controller registration/setup files ==\n'
rg -n --type=go -C3 'SetupWithManager|For\(|Owns\(|Watches\(' internal

Repository: openshift/oadp-operator

Length of output: 7650


🏁 Script executed:

#!/bin/bash
set -eu

rg -n --type=go -C4 'SetupWithManager|Owns\(|Watches\(|For\(' internal

Repository: openshift/oadp-operator

Length of output: 4141


Add a ResourceQuota watch if deletion should self-heal. This test only exercises a direct ReconcileResourceQuota call; SetupWithManager does not watch or own corev1.ResourceQuota, so deleting the quota will not enqueue a DPA reconcile on its own.

🧰 Tools
🪛 golangci-lint (2.12.2)

[error] 106-106: : # github.com/openshift/oadp-operator/api/v1alpha1
api/v1alpha1/cloudstorage_types.go:106:25: cannot use &CloudStorage{} (value of type *CloudStorage) as "k8s.io/apimachinery/pkg/runtime".Object value in argument to SchemeBuilder.Register: *CloudStorage does not implement "k8s.io/apimachinery/pkg/runtime".Object (missing method DeepCopyObject)
api/v1alpha1/cloudstorage_types.go:106:42: cannot use &CloudStorageList{} (value of type *CloudStorageList) as "k8s.io/apimachinery/pkg/runtime".Object value in argument to SchemeBuilder.Register: *CloudStorageList does not implement "k8s.io/apimachinery/pkg/runtime".Object (missing method DeepCopyObject)
api/v1alpha1/dataprotectionapplication_types.go:512:9: (*in).DeepCopyInto undefined (type *LoadConcurrency has no field or method DeepCopyInto)
api/v1alpha1/dataprotectionapplication_types.go:521:11: (*in).DeepCopyInto undefined (type *LoadAffinity has no field or method DeepCopyInto)
api/v1alpha1/dataprotectionapplication_types.go:1054:25: cannot use &DataProtectionApplication{} (value of type *DataProtectionApplication) as "k8s.io/apimachinery/pkg/runtime".Object value in argument to SchemeBuilder.Register: *DataProtectionApplication does not implement "k8s.io/apimachinery/pkg/runtime".Object (missing method DeepCopyObject)
api/v1alpha1/dataprotectionapplication_types.go:1054:55: cannot use &DataProtectionApplicationList{} (value of type *DataProtectionApplicationList) as "k8s.io/apimachinery/pkg/runtime".Object value in argument to SchemeBuilder.Register: *DataProtectionApplicationList does not implement "k8s.io/apimachinery/pkg/runtime".Object (missing method DeepCopyObject)
api/v1alpha1/dataprotectiontest_types.go:215:25: cannot use &DataProtectionTest{} (value of type *DataProtectionTest) as "k8s.io/apimachinery/pkg/runtime".Object value in argument to SchemeBuilder.Register: *DataProtectionTest does not implement "k8s.io/apimachinery/pkg/runtime".Object (missing method DeepCopyObject)
api/v1alpha1/dataprotectiontest_types.go:215:48: cannot use &DataProtectionTestList{} (value of type *DataProtectionTestList) as "k8s.io/apimachinery/pkg/runtime".Object value in argument to SchemeBuilder.Register: *DataProtectionTestList does not implement "k8s.io/apimachinery/pkg/runtime".Object (missing method DeepCopyObject)

(typecheck)

🤖 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 `@internal/controller/resourcequota_test.go` around lines 101 - 134, Add a
ResourceQuota watch or ownership configuration in SetupWithManager so deleting
the quota enqueues the related DPA reconciliation and restores defaults without
a direct ReconcileResourceQuota call. Ensure the watch maps the deleted
ResourceQuota to the correct DataProtectionApplication.

@kaovilai

Copy link
Copy Markdown
Member

/retest

@openshift-ci

openshift-ci Bot commented Jul 16, 2026

Copy link
Copy Markdown

@weshayutin: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/5.0-e2e-test-cli-aws aab5ea1 link true /test 5.0-e2e-test-cli-aws
ci/prow/4.22-e2e-test-aws aab5ea1 link true /test 4.22-e2e-test-aws
ci/prow/5.0-e2e-test-aws aab5ea1 link true /test 5.0-e2e-test-aws
ci/prow/unit-test aab5ea1 link true /test unit-test
ci/prow/4.22-e2e-test-cli-aws aab5ea1 link true /test 4.22-e2e-test-cli-aws
ci/prow/4.23-e2e-test-aws aab5ea1 link false /test 4.23-e2e-test-aws

Full PR test history. Your PR dashboard.

Details

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 kubernetes-sigs/prow repository. I understand the commands that are listed here.

@weshayutin weshayutin added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants