Skip to content

support deny list in operator#729

Open
AdheipSingh wants to merge 3 commits intoStarRocks:mainfrom
deep-bi:Fix-728-DenyList
Open

support deny list in operator#729
AdheipSingh wants to merge 3 commits intoStarRocks:mainfrom
deep-bi:Fix-728-DenyList

Conversation

@AdheipSingh
Copy link

@AdheipSingh AdheipSingh commented Dec 3, 2025

Description

Introduce Deny List #728

Checklist

For operator, please complete the following checklist:

  • run make generate to generate the code.
  • run golangci-lint run to check the code style.
  • run make test to run UT.
  • run make manifests to update the yaml files of CRD.

For helm chart, please complete the following checklist:

  • make sure you have updated the values.yaml
    file of starrocks chart.
  • In scripts directory, run bash create-parent-chart-values.sh to update the values.yaml file of the parent
    chart( kube-starrocks chart).

@CLAassistant
Copy link

CLAassistant commented Dec 3, 2025

CLA assistant check
All committers have signed the CLA.

Signed-off-by: AdheipSingh <adheip1222@gmail.com>
Signed-off-by: AdheipSingh <adheip1222@gmail.com>
@AdheipSingh
Copy link
Author

Hi @yandongxiao can you help in reviewing this.

@AdheipSingh
Copy link
Author

Hi @yandongxiao any review on this :)


// ignoreNamespacePredicate returns false if the object is in a denied namespace
func ignoreNamespacePredicate(obj client.Object) bool {
namespaces := getEnvAsSlice("DENY_LIST", nil, ",")
Copy link
Collaborator

Choose a reason for hiding this comment

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

wondering why choose env vars to pass down this info to operator? how about commandline option?

Also would like to know the usage scenario for this deny list, are there too many sr cluster managed by the same operator?

Copy link
Author

Choose a reason for hiding this comment

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

Hi @kevincai , sure we can do cli option also. Yes, there too many sr cluster managed by the same operator.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request introduces deny list functionality to the StarRocks Kubernetes operator, allowing administrators to exclude specific namespaces from reconciliation. The implementation uses a new predicates package with event filters that check both namespace deny lists and an ignored annotation.

Changes:

  • Added new pkg/predicates package with GenericPredicates event filter that respects namespace deny lists and ignored annotations
  • Integrated predicates into both StarRocksCluster and StarRocksWarehouse controllers via WithEventFilter
  • Updated Helm charts to support configuring the deny list via the denyList value and DENY_LIST environment variable

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
pkg/predicates/predicates.go New package implementing predicate logic for filtering events based on namespace deny list and ignored annotation
pkg/predicates/predicates_test.go Comprehensive test coverage for predicate functionality including Create, Update, Delete, and Generic events
pkg/controllers/controllers.go Integration of GenericPredicates event filter into both cluster and warehouse reconcilers
helm-charts/charts/kube-starrocks/values.yaml Added denyList configuration field with documentation
helm-charts/charts/kube-starrocks/charts/operator/values.yaml Added denyList configuration field with documentation
helm-charts/charts/kube-starrocks/charts/operator/templates/deployment.yaml Added DENY_LIST environment variable configuration
Makefile Added predicates package to test coverage

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 56 to 57
os.Setenv("DENY_LIST", tt.envDenyList)
defer os.Unsetenv("DENY_LIST")
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

Tests that modify environment variables may have race conditions when run in parallel. Consider using t.Setenv() instead of os.Setenv() and os.Unsetenv(), as t.Setenv() automatically handles cleanup and prevents parallel execution of tests that modify the same environment variable. This is the recommended approach in Go 1.17+ for test isolation.

Copilot uses AI. Check for mistakes.
}

// ignoreIgnoredObjectPredicate returns false if the object has the ignored annotation set to "true"
func ignoreIgnoredObjectPredicate(obj client.Object) bool {
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The function name "ignoreIgnoredObjectPredicate" is confusing because it returns true when the object should NOT be ignored (i.e., when reconciliation should proceed). The double negative ("ignore" + "ignored") makes this particularly hard to understand. Consider renaming to "shouldReconcileObject" or "isObjectAllowed" to better reflect its actual behavior and improve code readability.

Copilot uses AI. Check for mistakes.

// ignoreNamespacePredicate returns false if the object is in a denied namespace
func ignoreNamespacePredicate(obj client.Object) bool {
namespaces := getEnvAsSlice("DENY_LIST", nil, ",")
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

Reading and parsing the environment variable on every predicate call may impact performance, as predicates are invoked frequently. Consider caching the parsed deny list at initialization time (e.g., in a package-level variable or during GenericPredicates construction) and only re-reading if a reload mechanism is needed. This would avoid repeated string parsing on every reconciliation event.

Copilot uses AI. Check for mistakes.
Comment on lines 112 to 115
// Set environment variable if needed
if tt.envDenyList != "" {
os.Setenv("DENY_LIST", tt.envDenyList)
defer os.Unsetenv("DENY_LIST")
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

Tests should explicitly clean up the DENY_LIST environment variable even when envDenyList is empty to prevent pollution from previous tests. Consider adding an unconditional defer os.Unsetenv("DENY_LIST") or using t.Setenv() which handles this automatically. This ensures test isolation regardless of execution order.

Suggested change
// Set environment variable if needed
if tt.envDenyList != "" {
os.Setenv("DENY_LIST", tt.envDenyList)
defer os.Unsetenv("DENY_LIST")
// Ensure DENY_LIST is cleaned up after each subtest
defer os.Unsetenv("DENY_LIST")
// Set environment variable if needed
if tt.envDenyList != "" {
os.Setenv("DENY_LIST", tt.envDenyList)

Copilot uses AI. Check for mistakes.
# the operator watching all namespaces uses too many memory resources, you can set this value.
# Defaults to all namespaces.
watchNamespace: ""
# Comma-separated list of namespaces to exclude from reconciliation
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The documentation should clarify how denyList interacts with watchNamespace. When watchNamespace is set, it restricts the operator to a single namespace, so the denyList would have no effect (or vice versa, if a namespace is both watched and denied). Consider adding a comment explaining this relationship to help users understand the interaction between these two configuration options.

Suggested change
# Comma-separated list of namespaces to exclude from reconciliation
# Comma-separated list of namespaces to exclude from reconciliation when the operator watches
# multiple namespaces (i.e. when watchNamespace is empty and all namespaces are watched).
# Note: If watchNamespace is set to a non-empty namespace, the operator only watches that single
# namespace and denyList has no additional effect. If that same namespace is included in denyList,
# the operator will effectively not reconcile any namespaces.

Copilot uses AI. Check for mistakes.
}

// ignoreNamespacePredicate returns false if the object is in a denied namespace
func ignoreNamespacePredicate(obj client.Object) bool {
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The function name "ignoreNamespacePredicate" is confusing because it returns true when the namespace should NOT be ignored (i.e., when reconciliation should proceed). Consider renaming to "shouldReconcileNamespace" or "isNamespaceAllowed" to better reflect its actual behavior and make the code more readable.

Copilot uses AI. Check for mistakes.
Comment on lines 35 to 42
// Delete returns true if the Delete event should be processed
func (GenericPredicates) Delete(e event.DeleteEvent) bool {
return shouldReconcile(e.Object)
}

// Generic returns true if the Generic event should be processed
func (GenericPredicates) Generic(e event.GenericEvent) bool {
return shouldReconcile(e.Object)
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The Delete and Generic event handling is not thoroughly tested. While TestShouldReconcile_WithNilObject tests nil objects, there are no tests that verify Delete and Generic events properly respect the deny list and ignored annotation. Consider adding comprehensive test cases for these event types similar to the Create and Update tests.

Copilot uses AI. Check for mistakes.
Comment on lines 54 to 58
// Set environment variable if needed
if tt.envDenyList != "" {
os.Setenv("DENY_LIST", tt.envDenyList)
defer os.Unsetenv("DENY_LIST")
}
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

Tests should explicitly clean up the DENY_LIST environment variable even when envDenyList is empty to prevent pollution from previous tests. Consider adding an unconditional defer os.Unsetenv("DENY_LIST") or using t.Setenv() which handles this automatically. This ensures test isolation regardless of execution order.

Suggested change
// Set environment variable if needed
if tt.envDenyList != "" {
os.Setenv("DENY_LIST", tt.envDenyList)
defer os.Unsetenv("DENY_LIST")
}
// Ensure DENY_LIST is controlled for this subtest
t.Setenv("DENY_LIST", tt.envDenyList)

Copilot uses AI. Check for mistakes.
Comment on lines 192 to 193
os.Setenv("TEST_ENV", tt.envValue)
defer os.Unsetenv("TEST_ENV")
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

Tests should explicitly clean up the TEST_ENV environment variable even when the test completes to prevent pollution. Consider using t.Setenv() instead which handles cleanup automatically and is the recommended approach in Go 1.17+ for test isolation.

Suggested change
os.Setenv("TEST_ENV", tt.envValue)
defer os.Unsetenv("TEST_ENV")
t.Setenv("TEST_ENV", tt.envValue)

Copilot uses AI. Check for mistakes.
Comment on lines 88 to 96
# Comma-separated list of namespaces to exclude from reconciliation
# Example: "kube-system,kube-public,monitoring"
denyList: ""
# Additional operator container environment variables
# You specify this manually like you would a raw deployment manifest.
# Ref: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/
# operator supports the following environment variables:
# KUBE_STARROCKS_UNSUPPORTED_ENVS: "XXX,YYY" # The environment variables that will not be passed to starrocks container.
# DENY_LIST: "namespace1,namespace2" # Comma-separated list of namespaces to exclude from reconciliation
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The documentation should clarify how denyList interacts with watchNamespace. When watchNamespace is set, it restricts the operator to a single namespace, so the denyList would have no effect (or vice versa, if a namespace is both watched and denied). Consider adding a comment explaining this relationship to help users understand the interaction between these two configuration options.

Suggested change
# Comma-separated list of namespaces to exclude from reconciliation
# Example: "kube-system,kube-public,monitoring"
denyList: ""
# Additional operator container environment variables
# You specify this manually like you would a raw deployment manifest.
# Ref: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/
# operator supports the following environment variables:
# KUBE_STARROCKS_UNSUPPORTED_ENVS: "XXX,YYY" # The environment variables that will not be passed to starrocks container.
# DENY_LIST: "namespace1,namespace2" # Comma-separated list of namespaces to exclude from reconciliation
# Comma-separated list of namespaces to exclude from reconciliation.
# This only applies to namespaces that the operator would otherwise watch.
# When watchNamespace is empty (default, watch all namespaces), denyList can be
# used to skip specific namespaces. When watchNamespace is set to a single
# namespace, excluding other namespaces via denyList has no additional effect.
# If the same namespace is specified in both watchNamespace and denyList, the
# watchNamespace setting takes precedence and the denyList entry is effectively
# redundant.
denyList: ""
# Additional operator container environment variables
# You specify this manually like you would a raw deployment manifest.
# Ref: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/
# operator supports the following environment variables:
# KUBE_STARROCKS_UNSUPPORTED_ENVS: "XXX,YYY" # The environment variables that will not be passed to starrocks container.
# DENY_LIST: "namespace1,namespace2" # Comma-separated list of namespaces to exclude from reconciliation.
# This environment variable has the same effect as .Values.starrocksOperator.denyList:
# it only excludes namespaces that the operator would otherwise watch. When
# watchNamespace is set to a single namespace, DENY_LIST entries for other
# namespaces have no additional effect, and listing the watched namespace
# itself is redundant.

Copilot uses AI. Check for mistakes.
@AdheipSingh
Copy link
Author

@kevincai i have addressed your comments.

Signed-off-by: AdheipSingh <adheip1222@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants