Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions api/config/v2alpha2/projectconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ type ProjectConfig struct {
// running multiple controllers in the same cluster.
ControllerClass string `json:"controllerClass"`

// NamespaceExclusionSelector defines criteria for excluding namespaces from reconciliation.
// If a resource is in a namespace that matches the criteria defined in NamespaceExclusionSelector,
// it will be excluded from reconciliation even if the resource matches the ControllerClass.
// If not set, the controller will reconcile resources in all namespaces.
NamespaceExclusionSelector *NamespaceExclusionSelector `json:"namespaceExclusionSelector,omitempty"`

// DeletionProtectionDefault sets the default to use with regards to deletion
// protection if it is not set on the resource.
DeletionProtectionDefault bool `json:"deletionProtectionDefault"`
Expand Down Expand Up @@ -94,6 +100,12 @@ type OPAControlPlaneConfig struct {
LibraryDatasourceChanged string `json:"libraryDatasourceChanged,omitempty"`
}

// NamespaceExclusionSelector defines criteria for excluding namespaces.
type NamespaceExclusionSelector struct {
// MatchPatterns is a list of glob patterns to match namespace names against.
MatchPatterns []string `json:"matchPatterns,omitempty"`
}

// BundleObjectStorage defines the structure for object storage configuration used by bundles
type BundleObjectStorage struct {
S3 *S3ObjectStorage `json:"s3,omitempty" yaml:"s3,omitempty"`
Expand Down
6 changes: 6 additions & 0 deletions config/default/config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
apiVersion: config.bankdata.dk/v2alpha2
kind: ProjectConfig
#controllerClass:

#namespaceExclusionSelector:
# matchPatterns:
# - "*-dev"
# - "*-staging"

deletionProtectionDefault: false
#disableCRDWebhooks:
#gitCredentials:
Expand Down
21 changes: 21 additions & 0 deletions internal/controller/styra/system_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"fmt"
"net/http"
"net/url"
"path/filepath"
"strings"
"time"

Expand Down Expand Up @@ -112,6 +113,12 @@ func (r *SystemReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
log = log.WithValues("controlPlane", system.Labels["styra-controller/control-plane"])
log = log.WithValues("uniqueName", system.OCPUniqueName(r.Config.SystemPrefix, r.Config.SystemSuffix))

if r.isNamespaceExcluded(&system) {
log.Info("Namespace is excluded from reconciliation. Skipping.")
r.deleteMetrics(req)
return ctrl.Result{}, nil
}

if !labels.ControllerClassMatches(&system, r.Config.ControllerClass) {
log.Info("This is not a System we are managing. Skipping reconciliation.")
r.deleteMetrics(req)
Expand Down Expand Up @@ -152,6 +159,20 @@ func (r *SystemReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return res, err
}

func (r *SystemReconciler) isNamespaceExcluded(system *v1beta1.System) bool {
if r.Config.NamespaceExclusionSelector == nil {
return false
}

for _, pattern := range r.Config.NamespaceExclusionSelector.MatchPatterns {
if matched, _ := filepath.Match(pattern, system.Namespace); matched {
return true
}
}

return false
}

func (r *SystemReconciler) setSystemStatusError(System *v1beta1.System, err error) {
System.Status.FailureMessage = err.Error()
System.Status.Phase = v1beta1.SystemPhaseFailed
Expand Down
34 changes: 34 additions & 0 deletions internal/controller/styra/system_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ limitations under the License.
package styra

import (
configv2alpha2 "github.com/bankdata/styra-controller/api/config/v2alpha2"
"github.com/bankdata/styra-controller/api/styra/v1beta1"
ginkgo "github.com/onsi/ginkgo/v2"
gomega "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// test the isURLValid method
Expand All @@ -35,3 +38,34 @@ var _ = ginkgo.DescribeTable("isURLValid",
ginkgo.Entry("invalid url", "google.com", false),
ginkgo.Entry("invalid url", "google", false),
)

// test the isNamespaceExcluded method
var _ = ginkgo.DescribeTable("isNamespaceExcluded",
func(namespaceExclusionSelector *configv2alpha2.NamespaceExclusionSelector, systemNamespace string, expected bool) {
reconciler := &SystemReconciler{
Config: &configv2alpha2.ProjectConfig{
NamespaceExclusionSelector: namespaceExclusionSelector,
},
}
system := v1beta1.System{
ObjectMeta: metav1.ObjectMeta{
Namespace: systemNamespace,
},
}
gomega.Ω(reconciler.isNamespaceExcluded(&system)).To(gomega.Equal(expected))
},
ginkgo.Entry("no exclusion selector",
nil, "namespace-dev", false),
ginkgo.Entry("empty exclusion selector",
&configv2alpha2.NamespaceExclusionSelector{}, "namespace-dev", false),
ginkgo.Entry("no match multiple patterns",
&configv2alpha2.NamespaceExclusionSelector{MatchPatterns: []string{"dev-*"}}, "namespace-dev", false),
ginkgo.Entry("match single pattern",
&configv2alpha2.NamespaceExclusionSelector{MatchPatterns: []string{"*-dev"}}, "namespace-dev", true),
ginkgo.Entry("no match single pattern",
&configv2alpha2.NamespaceExclusionSelector{MatchPatterns: []string{"*-staging", "*-prod"}},
"namespace-dev", false),
ginkgo.Entry("match multiple patterns",
&configv2alpha2.NamespaceExclusionSelector{MatchPatterns: []string{"*-dev", "*-staging"}},
"namespace-dev", true),
)
Loading