diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 9866dae5..4442d591 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,4 +1,4 @@ -# Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +# Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index c75a30e5..c9cfb21c 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -1,4 +1,4 @@ -# Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +# Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 43dbe9ee..d10a15b3 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -1,4 +1,4 @@ -# Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +# Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.github/workflows/tags.yaml b/.github/workflows/tags.yaml index 19ba23df..0717d8af 100644 --- a/.github/workflows/tags.yaml +++ b/.github/workflows/tags.yaml @@ -1,4 +1,4 @@ -# Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +# Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index cc7c673d..bea6d774 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -1,4 +1,4 @@ -# Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +# Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.golangci.yml b/.golangci.yml index 338c2d2d..0a5fbc84 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,4 +1,4 @@ -# Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +# Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 86a83b68..13c0a388 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -1,4 +1,4 @@ -# Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +# Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/Makefile b/Makefile index aeef082e..351605a4 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +# Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/api/config/v2alpha2/groupversion_info.go b/api/config/v2alpha2/groupversion_info.go index a1e41169..aa48187f 100644 --- a/api/config/v2alpha2/groupversion_info.go +++ b/api/config/v2alpha2/groupversion_info.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/config/v2alpha2/projectconfig_types.go b/api/config/v2alpha2/projectconfig_types.go index 260b0897..903f34aa 100644 --- a/api/config/v2alpha2/projectconfig_types.go +++ b/api/config/v2alpha2/projectconfig_types.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import ( "sort" "strings" + "github.com/bankdata/styra-controller/api/config/v2alpha3" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -449,6 +450,236 @@ func (c *ProjectConfig) OPARestartEnabled() bool { return c.PodRestart.OPARestart.Enabled } +// ToV2Alpha3 returns this ProjectConfig converted to a v2alpha3.ProjectConfig +func (c *ProjectConfig) ToV2Alpha3() *v2alpha3.ProjectConfig { + v2cfg3 := &v2alpha3.ProjectConfig{ + ControllerClass: c.ControllerClass, + DeletionProtectionDefault: c.DeletionProtectionDefault, + ReadOnly: c.ReadOnly, + EnableDeltaBundlesDefault: c.EnableDeltaBundlesDefault, + DisableCRDWebhooks: c.DisableCRDWebhooks, + EnableMigrations: c.EnableMigrations, + DatasourceIgnorePatterns: c.DatasourceIgnorePatterns, + LogLevel: c.LogLevel, + Styra: v2alpha3.StyraConfig{ + Token: c.Styra.Token, + Address: c.Styra.Address, + TokenSecretPath: c.Styra.TokenSecretPath, + }, + SystemPrefix: c.SystemPrefix, + SystemSuffix: c.SystemSuffix, + SystemUserRoles: c.SystemUserRoles, + EnableStyraReconciliation: c.EnableStyraReconciliation, + EnableOPAControlPlaneReconciliation: c.EnableOPAControlPlaneReconciliation, + EnableOPAControlPlaneReconciliationTestData: c.EnableOPAControlPlaneReconciliationTestData, + } + + if c.GitCredentials != nil { + v2cfg3.GitCredentials = make([]*v2alpha3.GitCredential, len(c.GitCredentials)) + for i, c := range c.GitCredentials { + v2cfg3.GitCredentials[i] = &v2alpha3.GitCredential{ + User: c.User, + Password: c.Password, + RepoPrefix: c.RepoPrefix, + } + } + } + + if c.LeaderElection != nil { + v2cfg3.LeaderElection = &v2alpha3.LeaderElectionConfig{ + LeaseDuration: c.LeaderElection.LeaseDuration, + RenewDeadline: c.LeaderElection.RenewDeadline, + RetryPeriod: c.LeaderElection.RetryPeriod, + } + } + + if c.NotificationWebhooks != nil { + v2cfg3.NotificationWebhooks = &v2alpha3.NotificationWebhooksConfig{ + SystemDatasourceChanged: c.NotificationWebhooks.SystemDatasourceChanged, + LibraryDatasourceChanged: c.NotificationWebhooks.LibraryDatasourceChanged, + } + } + + if c.Sentry != nil { + v2cfg3.Sentry = &v2alpha3.SentryConfig{ + DSN: c.Sentry.DSN, + Debug: c.Sentry.Debug, + Environment: c.Sentry.Environment, + HTTPSProxy: c.Sentry.HTTPSProxy, + } + } + + if c.SSO != nil { + v2cfg3.SSO = &v2alpha3.SSOConfig{ + IdentityProvider: c.SSO.IdentityProvider, + JWTGroupsClaim: c.SSO.JWTGroupsClaim, + } + } + + v2cfg3.OPA = v2alpha3.OPAConfig{ + DecisionLogs: v2alpha3.DecisionLog{ + RequestContext: v2alpha3.RequestContext{ + HTTP: v2alpha3.HTTP{ + Headers: c.OPA.DecisionLogs.RequestContext.HTTP.Headers, + }, + }, + }, + Metrics: v2alpha3.MetricsConfig{ + Prometheus: v2alpha3.PrometheusMetricsConfig{ + HTTP: v2alpha3.HTTPMetricsConfig{ + Buckets: c.OPA.Metrics.Prometheus.HTTP.Buckets, + }, + }, + }, + PersistBundle: c.OPA.PersistBundle, + PersistBundleDirectory: c.OPA.PersistBundleDirectory, + } + + if c.OPA.BundleServer != nil { + v2cfg3.OPA.BundleServer = &v2alpha3.OPABundleServer{ + URL: c.OPA.BundleServer.URL, + Path: c.OPA.BundleServer.Path, + } + } + + if c.DecisionsExporter != nil { + v2cfg3.DecisionsExporter = &v2alpha3.ExporterConfig{ + Enabled: c.DecisionsExporter.Enabled, + Interval: c.DecisionsExporter.Interval, + } + + if c.DecisionsExporter.Kafka != nil { + v2cfg3.DecisionsExporter.Kafka = &v2alpha3.KafkaConfig{ + Brokers: c.DecisionsExporter.Kafka.Brokers, + Topic: c.DecisionsExporter.Kafka.Topic, + RequiredAcks: c.DecisionsExporter.Kafka.RequiredAcks, + } + + if c.DecisionsExporter.Kafka.TLS != nil { + v2cfg3.DecisionsExporter.Kafka.TLS = &v2alpha3.TLSConfig{ + ClientCertificateName: c.DecisionsExporter.Kafka.TLS.ClientCertificateName, + ClientCertificate: c.DecisionsExporter.Kafka.TLS.ClientCertificate, + ClientKey: c.DecisionsExporter.Kafka.TLS.ClientKey, + RootCA: c.DecisionsExporter.Kafka.TLS.RootCA, + InsecureSkipVerify: c.DecisionsExporter.Kafka.TLS.InsecureSkipVerify, + } + } + } + } + + if c.ActivityExporter != nil { + v2cfg3.ActivityExporter = &v2alpha3.ExporterConfig{ + Enabled: c.ActivityExporter.Enabled, + Interval: c.ActivityExporter.Interval, + } + + if c.ActivityExporter.Kafka != nil { + v2cfg3.ActivityExporter.Kafka = &v2alpha3.KafkaConfig{ + Brokers: c.ActivityExporter.Kafka.Brokers, + Topic: c.ActivityExporter.Kafka.Topic, + RequiredAcks: c.ActivityExporter.Kafka.RequiredAcks, + } + + if c.ActivityExporter.Kafka.TLS != nil { + v2cfg3.ActivityExporter.Kafka.TLS = &v2alpha3.TLSConfig{ + ClientCertificateName: c.ActivityExporter.Kafka.TLS.ClientCertificateName, + ClientCertificate: c.ActivityExporter.Kafka.TLS.ClientCertificate, + ClientKey: c.ActivityExporter.Kafka.TLS.ClientKey, + RootCA: c.ActivityExporter.Kafka.TLS.RootCA, + InsecureSkipVerify: c.ActivityExporter.Kafka.TLS.InsecureSkipVerify, + } + } + } + } + + if c.PodRestart != nil { + v2cfg3.PodRestart = &v2alpha3.PodRestartConfig{} + + if c.PodRestart.SLPRestart != nil { + v2cfg3.PodRestart.SLPRestart = &v2alpha3.SLPRestartConfig{ + Enabled: c.PodRestart.SLPRestart.Enabled, + DeploymentType: c.PodRestart.SLPRestart.DeploymentType, + } + } + + if c.PodRestart.OPARestart != nil { + v2cfg3.PodRestart.OPARestart = &v2alpha3.OPARestartConfig{ + Enabled: c.PodRestart.OPARestart.Enabled, + DeploymentType: c.PodRestart.OPARestart.DeploymentType, + } + } + } + + if c.OPAControlPlaneConfig != nil { + v2cfg3.OPAControlPlaneConfig = &v2alpha3.OPAControlPlaneConfig{ + Address: c.OPAControlPlaneConfig.Address, + Token: c.OPAControlPlaneConfig.Token, + SystemDatasourceChanged: c.OPAControlPlaneConfig.SystemDatasourceChanged, + LibraryDatasourceChanged: c.OPAControlPlaneConfig.LibraryDatasourceChanged, + } + + if c.OPAControlPlaneConfig.GitCredentials != nil { + v2cfg3.OPAControlPlaneConfig.GitCredentials = make( + []*v2alpha3.GitCredentials, + len(c.OPAControlPlaneConfig.GitCredentials), + ) + for i, c := range c.OPAControlPlaneConfig.GitCredentials { + v2cfg3.OPAControlPlaneConfig.GitCredentials[i] = &v2alpha3.GitCredentials{ + ID: c.ID, + RepoPrefix: c.RepoPrefix, + } + } + } + + if c.OPAControlPlaneConfig.BundleObjectStorage != nil && c.OPAControlPlaneConfig.BundleObjectStorage.S3 != nil { + v2cfg3.OPAControlPlaneConfig.BundleObjectStorage = &v2alpha3.BundleObjectStorage{ + S3: &v2alpha3.S3ObjectStorage{ + Bucket: c.OPAControlPlaneConfig.BundleObjectStorage.S3.Bucket, + URL: c.OPAControlPlaneConfig.BundleObjectStorage.S3.URL, + Region: c.OPAControlPlaneConfig.BundleObjectStorage.S3.Region, + OCPConfigSecretName: c.OPAControlPlaneConfig.BundleObjectStorage.S3.OCPConfigSecretName, + }, + } + } + + v2cfg3.OPAControlPlaneConfig.DefaultRequirements = make( + []v2alpha3.DefaultRequirement, + len(c.OPAControlPlaneConfig.DefaultRequirements), + ) + for i, requirement := range c.OPAControlPlaneConfig.DefaultRequirements { + v2cfg3.OPAControlPlaneConfig.DefaultRequirements[i] = v2alpha3.DefaultRequirement{ + Name: requirement, + RequirementType: v2alpha3.RequirementTypeUnknown, + } + } + + if c.OPAControlPlaneConfig.DecisionAPIConfig != nil { + v2cfg3.OPAControlPlaneConfig.DecisionAPIConfig = &v2alpha3.DecisionAPIConfig{ + ServiceURL: c.OPAControlPlaneConfig.DecisionAPIConfig.ServiceURL, + Reporting: v2alpha3.DecisionLogReporting{ + MaxDelaySeconds: c.OPAControlPlaneConfig.DecisionAPIConfig.Reporting.MaxDelaySeconds, + MinDelaySeconds: c.OPAControlPlaneConfig.DecisionAPIConfig.Reporting.MinDelaySeconds, + UploadSizeLimitBytes: c.OPAControlPlaneConfig.DecisionAPIConfig.Reporting.UploadSizeLimitBytes, + }, + } + } + } + + if c.UserCredentialHandler != nil && c.UserCredentialHandler.S3 != nil { + v2cfg3.UserCredentialHandler = &v2alpha3.UserCredentialHandler{ + S3: &v2alpha3.S3Handler{ + Bucket: c.UserCredentialHandler.S3.Bucket, + URL: c.UserCredentialHandler.S3.URL, + Region: c.UserCredentialHandler.S3.Region, + AccessKeyID: c.UserCredentialHandler.S3.AccessKeyID, + SecretAccessKey: c.UserCredentialHandler.S3.SecretAccessKey, + }, + } + } + + return v2cfg3 +} + func init() { SchemeBuilder.Register(&ProjectConfig{}) } diff --git a/api/config/v2alpha2/zz_generated.deepcopy.go b/api/config/v2alpha2/zz_generated.deepcopy.go index eef69be5..5b2d5d08 100644 --- a/api/config/v2alpha2/zz_generated.deepcopy.go +++ b/api/config/v2alpha2/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ //go:build !ignore_autogenerated /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/config/v2alpha3/groupversion_info.go b/api/config/v2alpha3/groupversion_info.go new file mode 100644 index 00000000..cd255860 --- /dev/null +++ b/api/config/v2alpha3/groupversion_info.go @@ -0,0 +1,37 @@ +/* +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v2alpha3 contains API Schema definitions for the config v2alpha3 API group +// +kubebuilder:object:generate=true +// +kubebuilder:skip +// +groupName=config.bankdata.dk +package v2alpha3 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "config.bankdata.dk", Version: "v2alpha3"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/api/config/v2alpha3/projectconfig_types.go b/api/config/v2alpha3/projectconfig_types.go new file mode 100644 index 00000000..e5250c2a --- /dev/null +++ b/api/config/v2alpha3/projectconfig_types.go @@ -0,0 +1,477 @@ +/* +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v2alpha3 + +import ( + "sort" + "strings" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +//+kubebuilder:object:root=true + +// ProjectConfig is the Schema for the projectconfigs API +type ProjectConfig struct { + metav1.TypeMeta `json:",inline"` + + // ControllerClass sets a controller class for this controller. This allows + // the provided CRDs to target a specific controller. This is useful when + // running multiple controllers in the same cluster. + ControllerClass string `json:"controllerClass"` + + // DeletionProtectionDefault sets the default to use with regards to deletion + // protection if it is not set on the resource. + DeletionProtectionDefault bool `json:"deletionProtectionDefault"` + + // ReadOnly sets the value of ReadOnly for systems + //+kubebuilder:deprecatedversion:warning="ReadOnly field is deprecated, only used in Styra" + // Deprecated: ReadOnly field is deprecated, only used in Styra. + // This field will be removed in a future version. + ReadOnly bool `json:"readOnly"` + + // EnableDeltaBundlesDefault sets the default of whether systems have delta-bundles or not + //+kubebuilder:deprecatedversion:warning="EnableDeltaBundlesDefault field is deprecated, only used in Styra" + // Deprecated: EnableDeltaBundlesDefault field is deprecated, only used in Styra. + // This field will be removed in a future version. + EnableDeltaBundlesDefault *bool `json:"enableDeltaBundlesDefault,omitempty"` + + // DisableCRDWebhooks disables the CRD webhooks on the controller. If running + // multiple controllers in the same cluster, only one will need to have it's + // webhooks enabled. + DisableCRDWebhooks bool `json:"disableCRDWebhooks"` + + // EnableMigrations enables the system migration annotation. This should be + // kept disabled unless migrations need to be done. + EnableMigrations bool `json:"enableMigrations"` + + // DatasourceIgnorePatterns is a list of regex patterns, that allow datasources in styra + // to be ignored based on their datasource id. + //+kubebuilder:deprecatedversion:warning="DatasourceIgnorePatterns field is deprecated, only used in Styra" + // Deprecated: DatasourceIgnorePatterns field is deprecated, only used in Styra. + // This field will be removed in a future version. + DatasourceIgnorePatterns []string `json:"datasourceIgnorePatterns,omitempty"` + + // GitCredentials holds a list of git credential configurations. The + // RepoPrefix of the GitCredential will be matched angainst repository URL in + // order to determine which credential to use. The GitCredential with the + // longest matching RepoPrefix will be selected. + //+kubebuilder:deprecatedversion:warning="GitCredentials field is deprecated, only used in Styra" + // Deprecated: GitCredentials field is deprecated, only used in Styra. + // This field will be removed in a future version. + GitCredentials []*GitCredential `json:"gitCredentials"` + + // LogLevel sets the logging level of the controller. A higher number gives + // more verbosity. A number higher than 0 should only be used for debugging + // purposes. + LogLevel int `json:"logLevel"` + + LeaderElection *LeaderElectionConfig `json:"leaderElection"` + + NotificationWebhooks *NotificationWebhooksConfig `json:"notificationWebhooks,omitempty"` + + Sentry *SentryConfig `json:"sentry"` + + //+kubebuilder:deprecatedversion:warning="SSO field is deprecated, only used in Styra" + // Deprecated: SSO field is deprecated, only used in Styra. This field will be removed in a future version. + SSO *SSOConfig `json:"sso"` + + //+kubebuilder:deprecatedversion:warning="Styra field is deprecated, use OPAControlPlaneConfig instead" + // Deprecated: Use OPAControlPlaneConfig instead. This field will be removed in a future version. + Styra StyraConfig `json:"styra"` + + OPA OPAConfig `json:"opa,omitempty"` + + // SystemPrefix is a prefix for all the systems that the controller creates + // in Styra DAS. This is useful in order to be able to identify what + // controller created a system in a shared Styra DAS instance. + SystemPrefix string `json:"systemPrefix"` + + // SystemSuffix is a suffix for all the systems that the controller creates + // in Styra DAS. This is useful in order to be able to identify what + // controller created a system in a shared Styra DAS instance. + SystemSuffix string `json:"systemSuffix"` + + // SystemUserRoles is a list of Styra DAS system level roles which the subjects of + // a system will be granted. + //+kubebuilder:deprecatedversion:warning="SystemUserRoles field is deprecated, only used in Styra" + // Deprecated: SystemUserRoles field is deprecated, only used in Styra. + // This field will be removed in a future version. + SystemUserRoles []string `json:"systemUserRoles"` + + //+kubebuilder:deprecatedversion:warning="DecisionsExporter field is deprecated, only used in Styra" + // Deprecated: DecisionsExporter field is deprecated, only used in Styra. + // This field will be removed in a future version. + DecisionsExporter *ExporterConfig `json:"decisionsExporter,omitempty"` + + //+kubebuilder:deprecatedversion:warning="ActivityExporter field is deprecated, only used in Styra" + // Deprecated: ActivityExporter field is deprecated, only used in Styra. + // This field will be removed in a future version. + ActivityExporter *ExporterConfig `json:"activityExporter,omitempty"` + + PodRestart *PodRestartConfig `json:"podRestart,omitempty"` + + // OPAControlPlaneConfig contains configuration for connecting to the + // OPA Control Plane APIs. If this is not set, the controller will not + // attempt to connect to the OPA Control Plane APIs. + OPAControlPlaneConfig *OPAControlPlaneConfig `json:"opaControlPlaneConfig,omitempty"` + + // UserCredentialHandler contains configuration for the controller to handle user credentials, e.g. in S3 + UserCredentialHandler *UserCredentialHandler `json:"userCredentialHandler,omitempty"` + + // EnableStyraReconciliation is a flag that sets whether the controller should use Styra + // A Migration flag to enable/disable Styra DAS reconciliation for all systems and libraries. + //+kubebuilder:deprecatedversion:warning="EnableStyraReconciliation field is deprecated. + // Only used in migration versions Styra->OCP" + // Deprecated: EnableStyraReconciliation field is deprecated, only used in migration versions Styra->OCP. + // This field will be removed in a future version. + EnableStyraReconciliation bool `json:"enableStyraReconciliation,omitempty"` + + // EnableOPAControlPlaneReconciliation is a flag that sets whether the controller should use OPAControlPlane + // A Migration flag to enable/disable OPA Control Plane reconciliation for all systems and libraries. + //+kubebuilder:deprecatedversion:warning="EnableOPAControlPlaneReconciliation field is deprecated, + // only used in migration versions Styra->OCP" + // Deprecated: EnableOPAControlPlaneReconciliation field is deprecated, only used in migration versions Styra->OCP. + // This field will be removed in a future version. + EnableOPAControlPlaneReconciliation bool `json:"enableOPAControlPlaneReconciliation,omitempty"` + + // EnableOPAControlPlaneReconciliationTestData is a flag that sets whether the controller should create + // OPAControlPlane test data. + // A Migration flag to allow adding test data to OPA Control Plane and not to modify k8s data + //+kubebuilder:deprecatedversion:warning="EnableOPAControlPlaneReconciliationTestData field is deprecated. + // Only used in migration versions Styra->OCP" + // Deprecated: EnableOPAControlPlaneReconciliationTestData field is deprecated. + // Only used in migration versions Styra->OCP. This field will be removed in a future version. + EnableOPAControlPlaneReconciliationTestData bool `json:"enableOPAControlPlaneReconciliationTestData,omitempty"` +} + +// PodRestartConfig contains configuration for restarting OPA and SLP pods +type PodRestartConfig struct { + SLPRestart *SLPRestartConfig `json:"slpRestart,omitempty"` + OPARestart *OPARestartConfig `json:"opaRestart,omitempty"` +} + +// SLPRestartConfig contains configuration for restarting SLP pods +type SLPRestartConfig struct { + Enabled bool `json:"enabled"` + DeploymentType string `json:"deploymentType"` // DeploymentType only currently supports "StatefulSet"" +} + +// OPARestartConfig contains configuration for restarting OPA pods -- This is not yet implemented +type OPARestartConfig struct { + Enabled bool `json:"enabled"` + DeploymentType string `json:"deploymentType"` +} + +// LeaderElectionConfig contains configuration for leader election +type LeaderElectionConfig struct { + LeaseDuration metav1.Duration `json:"leaseDuration"` + RenewDeadline metav1.Duration `json:"renewDeadline"` + RetryPeriod metav1.Duration `json:"retryPeriod"` +} + +// StyraConfig contains configuration for connecting to the Styra DAS apis +type StyraConfig struct { + // Address is the URL for the Styra DAS API server. + Address string `json:"address"` + + // Token is a Styra DAS API token. These can be created in the Styra DAS GUI + // or through the API. The token should have the `WorkspaceAdministrator` role. + Token string `json:"token"` + + // Alternative to the "token" whice define the Styra DAS API token directly in the config file, + // this "tokenSecretPath" will use a token from a secret (only if "token" is not set) + TokenSecretPath string `json:"tokenSecretPath"` +} + +// OPAControlPlaneConfig defines the config for the OPA Control Plane. +type OPAControlPlaneConfig struct { + // Address is the URL for the OPA Control Plane API server. + Address string `json:"address"` + + // Token is a OPA Control Plane API token. + Token string `json:"token"` + + // GitCredentials is the name of a secret used by the OPA Control Plane Git integration. + GitCredentials []*GitCredentials `json:"gitCredentials,omitempty"` + + // BundleObjectStorage is the object storage configuration to use for bundles. + // Currently only supports aws + BundleObjectStorage *BundleObjectStorage `json:"bundleObjectStorage,omitempty"` + + // DefaultRequirements is a list of requirements that will be added to all + // systems/bundles created by the controller in the OCP, in addition to any requirements/datasources + // specified on the System resource. + DefaultRequirements []DefaultRequirement `json:"defaultRequirements,omitempty"` + + // SystemDatasourceChanged is the URL to be called when a system datasource has changed. + SystemDatasourceChanged string `json:"systemDatasourceChanged,omitempty"` + // LibraryDatasourceChanged is the URL to be called when a library datasource has changed. + LibraryDatasourceChanged string `json:"libraryDatasourceChanged,omitempty"` + + // DecisionAPIConfig contains configuration for which api OPAs should use to and how + DecisionAPIConfig *DecisionAPIConfig `json:"decisionAPIConfig,omitempty"` +} + +// DefaultRequirement defines a requirement/source that is included in all bundles +type DefaultRequirement struct { + Name string `json:"name"` + RequirementType RequirementType `json:"requirementType,omitempty"` +} + +// RequirementType defines the different types of requirements +type RequirementType string + +const ( + // RequirementTypeGit means that the requirement is a git source + RequirementTypeGit RequirementType = "git" + + // RequirementTypeData means that the requirement is a data source + RequirementTypeData RequirementType = "data" + + // RequirementTypeGitAndData means that the requirement is both a git and a data source + RequirementTypeGitAndData RequirementType = "git_and_data" + + // RequirementTypeUnknown means that the requirement type is unknown + RequirementTypeUnknown RequirementType = "unknown" +) + +// UserCredentialHandler defines the structure of possible user credential handlers +type UserCredentialHandler struct { + S3 *S3Handler `json:"s3,omitempty" yaml:"s3,omitempty"` +} + +// S3Handler defines the structure for S3 handler configuration. +type S3Handler struct { + Bucket string `json:"bucket" yaml:"bucket"` + URL string `json:"url" yaml:"url"` + Region string `json:"region" yaml:"region"` + AccessKeyID string `json:"accessKeyID" yaml:"accessKeyID"` + SecretAccessKey string `json:"secretAccessKey" yaml:"secretAccessKey"` +} + +// BundleObjectStorage defines the structure for object storage configuration used by bundles +type BundleObjectStorage struct { + S3 *S3ObjectStorage `json:"s3,omitempty" yaml:"s3,omitempty"` +} + +// S3ObjectStorage defines the structure for S3 object storage configuration. +type S3ObjectStorage struct { + Bucket string `json:"bucket"` + URL string `json:"url,omitempty"` + Region string `json:"region"` + OCPConfigSecretName string `json:"ocpConfigSecretName"` +} + +// GitCredentials contains configuration for git credentials used by the OPA Control Plane. +type GitCredentials struct { + ID string `json:"id"` + + // RepoPrefix specifies a repo URL prefix. eg. if RepoPrefix is set to + // `https://github.com/bankdata`, then this credentials would apply for any + // repository under the bankdata github org. + RepoPrefix string `json:"repoPrefix"` +} + +// OPAConfig contains default configuration for the opa config generated by the styra-controller +type OPAConfig struct { + DecisionLogs DecisionLog `json:"decisionLogs,omitempty" yaml:"decisionLogs,omitempty"` + Metrics MetricsConfig `json:"metrics,omitempty" yaml:"metrics,omitempty"` + PersistBundle bool `json:"persist_bundle,omitempty" yaml:"persist_bundle,omitempty"` + PersistBundleDirectory string `json:"persist_bundle_directory,omitempty" yaml:"persist_bundle_directory,omitempty"` //nolint:lll + BundleServer *OPABundleServer `json:"bundleServer,omitempty" yaml:"bundleServer,omitempty"` +} + +// OPABundleServer contains configuration for the OPA bundle server +type OPABundleServer struct { + URL string `json:"url,omitempty" yaml:"url,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` +} + +// MetricsConfig contains configuration for OPA metrics +type MetricsConfig struct { + Prometheus PrometheusMetricsConfig `json:"prometheus,omitempty" yaml:"prometheus,omitempty"` +} + +// PrometheusMetricsConfig contains configuration for Prometheus metrics +type PrometheusMetricsConfig struct { + HTTP HTTPMetricsConfig `json:"http,omitempty" yaml:"http,omitempty"` +} + +// HTTPMetricsConfig contains configuration for HTTP metrics +type HTTPMetricsConfig struct { + Buckets []float64 `json:"buckets,omitempty" yaml:"buckets,omitempty"` +} + +// DecisionLog contains configuration for the decision logs +type DecisionLog struct { + RequestContext RequestContext `json:"requestContext,omitempty"` +} + +// DecisionAPIConfig contains configuration for decision log dispatch +type DecisionAPIConfig struct { + ServiceURL string `json:"serviceUrl,omitempty"` + Reporting DecisionLogReporting `json:"reporting,omitempty"` +} + +// DecisionLogReporting contains configuration for decision log reporting +type DecisionLogReporting struct { + MaxDelaySeconds int `json:"maxDelaySeconds,omitempty" yaml:"maxDelaySeconds,omitempty"` + MinDelaySeconds int `json:"minDelaySeconds,omitempty" yaml:"minDelaySeconds,omitempty"` + UploadSizeLimitBytes int `json:"uploadSizeLimitBytes,omitempty" yaml:"uploadSizeLimitBytes,omitempty"` +} + +// RequestContext contains configuration for the RequestContext in the decision logs +type RequestContext struct { + HTTP HTTP `json:"http"` +} + +// HTTP contains configuration for the HTTP config in the RequestContext +type HTTP struct { + // http headers that will be added to the decision logs + Headers []string `json:"headers"` +} + +// SentryConfig contains configuration for how errors should be reported to +// sentry. +type SentryConfig struct { + // Debug enables Sentry client debugging. + Debug bool `json:"debug"` + + // DSN is the Sentry project DSN. + DSN string `json:"dsn"` + + // Environment sets the environment of the events sent to Sentry. + Environment string `json:"environment"` + + // HTTPSProxy sets an HTTP proxy server for sentry to use. + HTTPSProxy string `json:"httpsProxy"` +} + +// NotificationWebhooksConfig contains configuration for how to call the notification +// webhook. +type NotificationWebhooksConfig struct { + // Address is the URL to be called when the controller should do a webhook + // notification. Currently the only supported notification is that a + // datasource configuration has changed. + + //+kubebuilder:deprecatedversion:warning="SystemDatasourceChanged field is deprecated, only used in Styra" + // Deprecated: SystemDatasourceChanged field is deprecated, only used in Styra. + // This field will be removed in a future version. + SystemDatasourceChanged string `json:"systemDatasourceChanged,omitempty"` + //+kubebuilder:deprecatedversion:warning="LibraryDatasourceChanged field is deprecated, only used in Styra" + // Deprecated: LibraryDatasourceChanged field is deprecated, only used in Styra. + // This field will be removed in a future version. + LibraryDatasourceChanged string `json:"libraryDatasourceChanged,omitempty"` +} + +// SSOConfig contains configuration for how to use SSO tokens for determining +// what groups a user belongs to. This can be used to grant members of a +// certain group access to systems. +type SSOConfig struct { + // IdentityProvider is the ID of a configured Styra DAS identity provider. + IdentityProvider string `json:"identityProvider"` + + // JWTGroupsClaim is the json path to a claim in issued JWTs which contain a + // list of groups that the user belongs to. + JWTGroupsClaim string `json:"jwtGroupsClaim"` +} + +// GitCredential represents a set of credentials to be used for repositories +// that match the RepoPrefix. +type GitCredential struct { + // User is a http basic auth username used for git. + User string `json:"user"` + + // Password is a http basic auth password used for git. + Password string `json:"password"` + + // RepoPrefix specifies a repo URL prefix. eg. if RepoPrefix is set to + // `https://github.com/bankdata`, then this credentials would apply for any + // repository under the bankdata github org. + RepoPrefix string `json:"repoPrefix"` +} + +// ExporterConfigType defines the type of exporter config +type ExporterConfigType string + +const ( + // ExporterConfigTypeDecisions is the type for decisions exporter config + ExporterConfigTypeDecisions ExporterConfigType = "DecisionsExporter" + // ExporterConfigTypeActivity is the type for activity exporter config + ExporterConfigTypeActivity ExporterConfigType = "ActivityExporter" +) + +// ExporterConfig contains configuration for exports +type ExporterConfig struct { + Enabled bool `json:"enabled,omitempty"` + Interval string `json:"interval,omitempty"` + Kafka *KafkaConfig `json:"kafka,omitempty"` +} + +// KafkaConfig contains configuration for exporting decisions to Kafka +type KafkaConfig struct { + Brokers []string `json:"brokers"` + Topic string `json:"topic"` + RequiredAcks string `json:"requiredAcks"` + TLS *TLSConfig `json:"tls,omitempty"` +} + +// TLSConfig contains TLS configuration for Kafka decisions export. +type TLSConfig struct { + ClientCertificateName string `json:"clientCertificateName"` + ClientCertificate string `json:"clientCertificate"` + ClientKey string `json:"clientKey"` + RootCA string `json:"rootCA"` + InsecureSkipVerify bool `json:"insecureSkipVerify"` +} + +// GetGitCredentialForRepo determines which default GitCredential to use for checking out the +// policy repository based on the URL to the policy repository. +func (c *ProjectConfig) GetGitCredentialForRepo(repo string) *GitCredential { + sort.Slice(c.GitCredentials, func(i, j int) bool { + return len(c.GitCredentials[i].RepoPrefix) > len(c.GitCredentials[j].RepoPrefix) + }) + + for _, gitCredential := range c.GitCredentials { + if strings.HasPrefix(repo, gitCredential.RepoPrefix) { + return gitCredential + } + } + + return nil +} + +// SLPRestartEnabled returns true if the OPA restart is enabled +func (c *ProjectConfig) SLPRestartEnabled() bool { + if c.PodRestart == nil || c.PodRestart.SLPRestart == nil { + return false + } + return c.PodRestart.SLPRestart.Enabled +} + +// OPARestartEnabled returns true if the OPA restart is enabled +func (c *ProjectConfig) OPARestartEnabled() bool { + if c.PodRestart == nil || c.PodRestart.OPARestart == nil { + return false + } + return c.PodRestart.OPARestart.Enabled +} + +func init() { + SchemeBuilder.Register(&ProjectConfig{}) +} diff --git a/api/config/v2alpha3/zz_generated.deepcopy.go b/api/config/v2alpha3/zz_generated.deepcopy.go new file mode 100644 index 00000000..7df806dd --- /dev/null +++ b/api/config/v2alpha3/zz_generated.deepcopy.go @@ -0,0 +1,643 @@ +//go:build !ignore_autogenerated + +/* +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v2alpha3 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BundleObjectStorage) DeepCopyInto(out *BundleObjectStorage) { + *out = *in + if in.S3 != nil { + in, out := &in.S3, &out.S3 + *out = new(S3ObjectStorage) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleObjectStorage. +func (in *BundleObjectStorage) DeepCopy() *BundleObjectStorage { + if in == nil { + return nil + } + out := new(BundleObjectStorage) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DecisionAPIConfig) DeepCopyInto(out *DecisionAPIConfig) { + *out = *in + out.Reporting = in.Reporting +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DecisionAPIConfig. +func (in *DecisionAPIConfig) DeepCopy() *DecisionAPIConfig { + if in == nil { + return nil + } + out := new(DecisionAPIConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DecisionLog) DeepCopyInto(out *DecisionLog) { + *out = *in + in.RequestContext.DeepCopyInto(&out.RequestContext) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DecisionLog. +func (in *DecisionLog) DeepCopy() *DecisionLog { + if in == nil { + return nil + } + out := new(DecisionLog) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DecisionLogReporting) DeepCopyInto(out *DecisionLogReporting) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DecisionLogReporting. +func (in *DecisionLogReporting) DeepCopy() *DecisionLogReporting { + if in == nil { + return nil + } + out := new(DecisionLogReporting) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DefaultRequirement) DeepCopyInto(out *DefaultRequirement) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DefaultRequirement. +func (in *DefaultRequirement) DeepCopy() *DefaultRequirement { + if in == nil { + return nil + } + out := new(DefaultRequirement) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExporterConfig) DeepCopyInto(out *ExporterConfig) { + *out = *in + if in.Kafka != nil { + in, out := &in.Kafka, &out.Kafka + *out = new(KafkaConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExporterConfig. +func (in *ExporterConfig) DeepCopy() *ExporterConfig { + if in == nil { + return nil + } + out := new(ExporterConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GitCredential) DeepCopyInto(out *GitCredential) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitCredential. +func (in *GitCredential) DeepCopy() *GitCredential { + if in == nil { + return nil + } + out := new(GitCredential) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GitCredentials) DeepCopyInto(out *GitCredentials) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitCredentials. +func (in *GitCredentials) DeepCopy() *GitCredentials { + if in == nil { + return nil + } + out := new(GitCredentials) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HTTP) DeepCopyInto(out *HTTP) { + *out = *in + if in.Headers != nil { + in, out := &in.Headers, &out.Headers + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTP. +func (in *HTTP) DeepCopy() *HTTP { + if in == nil { + return nil + } + out := new(HTTP) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HTTPMetricsConfig) DeepCopyInto(out *HTTPMetricsConfig) { + *out = *in + if in.Buckets != nil { + in, out := &in.Buckets, &out.Buckets + *out = make([]float64, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPMetricsConfig. +func (in *HTTPMetricsConfig) DeepCopy() *HTTPMetricsConfig { + if in == nil { + return nil + } + out := new(HTTPMetricsConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KafkaConfig) DeepCopyInto(out *KafkaConfig) { + *out = *in + if in.Brokers != nil { + in, out := &in.Brokers, &out.Brokers + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(TLSConfig) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KafkaConfig. +func (in *KafkaConfig) DeepCopy() *KafkaConfig { + if in == nil { + return nil + } + out := new(KafkaConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeaderElectionConfig) DeepCopyInto(out *LeaderElectionConfig) { + *out = *in + out.LeaseDuration = in.LeaseDuration + out.RenewDeadline = in.RenewDeadline + out.RetryPeriod = in.RetryPeriod +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaderElectionConfig. +func (in *LeaderElectionConfig) DeepCopy() *LeaderElectionConfig { + if in == nil { + return nil + } + out := new(LeaderElectionConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MetricsConfig) DeepCopyInto(out *MetricsConfig) { + *out = *in + in.Prometheus.DeepCopyInto(&out.Prometheus) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricsConfig. +func (in *MetricsConfig) DeepCopy() *MetricsConfig { + if in == nil { + return nil + } + out := new(MetricsConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NotificationWebhooksConfig) DeepCopyInto(out *NotificationWebhooksConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NotificationWebhooksConfig. +func (in *NotificationWebhooksConfig) DeepCopy() *NotificationWebhooksConfig { + if in == nil { + return nil + } + out := new(NotificationWebhooksConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OPABundleServer) DeepCopyInto(out *OPABundleServer) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OPABundleServer. +func (in *OPABundleServer) DeepCopy() *OPABundleServer { + if in == nil { + return nil + } + out := new(OPABundleServer) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OPAConfig) DeepCopyInto(out *OPAConfig) { + *out = *in + in.DecisionLogs.DeepCopyInto(&out.DecisionLogs) + in.Metrics.DeepCopyInto(&out.Metrics) + if in.BundleServer != nil { + in, out := &in.BundleServer, &out.BundleServer + *out = new(OPABundleServer) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OPAConfig. +func (in *OPAConfig) DeepCopy() *OPAConfig { + if in == nil { + return nil + } + out := new(OPAConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OPAControlPlaneConfig) DeepCopyInto(out *OPAControlPlaneConfig) { + *out = *in + if in.GitCredentials != nil { + in, out := &in.GitCredentials, &out.GitCredentials + *out = make([]*GitCredentials, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(GitCredentials) + **out = **in + } + } + } + if in.BundleObjectStorage != nil { + in, out := &in.BundleObjectStorage, &out.BundleObjectStorage + *out = new(BundleObjectStorage) + (*in).DeepCopyInto(*out) + } + if in.DefaultRequirements != nil { + in, out := &in.DefaultRequirements, &out.DefaultRequirements + *out = make([]DefaultRequirement, len(*in)) + copy(*out, *in) + } + if in.DecisionAPIConfig != nil { + in, out := &in.DecisionAPIConfig, &out.DecisionAPIConfig + *out = new(DecisionAPIConfig) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OPAControlPlaneConfig. +func (in *OPAControlPlaneConfig) DeepCopy() *OPAControlPlaneConfig { + if in == nil { + return nil + } + out := new(OPAControlPlaneConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OPARestartConfig) DeepCopyInto(out *OPARestartConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OPARestartConfig. +func (in *OPARestartConfig) DeepCopy() *OPARestartConfig { + if in == nil { + return nil + } + out := new(OPARestartConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodRestartConfig) DeepCopyInto(out *PodRestartConfig) { + *out = *in + if in.SLPRestart != nil { + in, out := &in.SLPRestart, &out.SLPRestart + *out = new(SLPRestartConfig) + **out = **in + } + if in.OPARestart != nil { + in, out := &in.OPARestart, &out.OPARestart + *out = new(OPARestartConfig) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodRestartConfig. +func (in *PodRestartConfig) DeepCopy() *PodRestartConfig { + if in == nil { + return nil + } + out := new(PodRestartConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectConfig) DeepCopyInto(out *ProjectConfig) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.EnableDeltaBundlesDefault != nil { + in, out := &in.EnableDeltaBundlesDefault, &out.EnableDeltaBundlesDefault + *out = new(bool) + **out = **in + } + if in.DatasourceIgnorePatterns != nil { + in, out := &in.DatasourceIgnorePatterns, &out.DatasourceIgnorePatterns + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.GitCredentials != nil { + in, out := &in.GitCredentials, &out.GitCredentials + *out = make([]*GitCredential, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(GitCredential) + **out = **in + } + } + } + if in.LeaderElection != nil { + in, out := &in.LeaderElection, &out.LeaderElection + *out = new(LeaderElectionConfig) + **out = **in + } + if in.NotificationWebhooks != nil { + in, out := &in.NotificationWebhooks, &out.NotificationWebhooks + *out = new(NotificationWebhooksConfig) + **out = **in + } + if in.Sentry != nil { + in, out := &in.Sentry, &out.Sentry + *out = new(SentryConfig) + **out = **in + } + if in.SSO != nil { + in, out := &in.SSO, &out.SSO + *out = new(SSOConfig) + **out = **in + } + out.Styra = in.Styra + in.OPA.DeepCopyInto(&out.OPA) + if in.SystemUserRoles != nil { + in, out := &in.SystemUserRoles, &out.SystemUserRoles + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.DecisionsExporter != nil { + in, out := &in.DecisionsExporter, &out.DecisionsExporter + *out = new(ExporterConfig) + (*in).DeepCopyInto(*out) + } + if in.ActivityExporter != nil { + in, out := &in.ActivityExporter, &out.ActivityExporter + *out = new(ExporterConfig) + (*in).DeepCopyInto(*out) + } + if in.PodRestart != nil { + in, out := &in.PodRestart, &out.PodRestart + *out = new(PodRestartConfig) + (*in).DeepCopyInto(*out) + } + if in.OPAControlPlaneConfig != nil { + in, out := &in.OPAControlPlaneConfig, &out.OPAControlPlaneConfig + *out = new(OPAControlPlaneConfig) + (*in).DeepCopyInto(*out) + } + if in.UserCredentialHandler != nil { + in, out := &in.UserCredentialHandler, &out.UserCredentialHandler + *out = new(UserCredentialHandler) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectConfig. +func (in *ProjectConfig) DeepCopy() *ProjectConfig { + if in == nil { + return nil + } + out := new(ProjectConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ProjectConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PrometheusMetricsConfig) DeepCopyInto(out *PrometheusMetricsConfig) { + *out = *in + in.HTTP.DeepCopyInto(&out.HTTP) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PrometheusMetricsConfig. +func (in *PrometheusMetricsConfig) DeepCopy() *PrometheusMetricsConfig { + if in == nil { + return nil + } + out := new(PrometheusMetricsConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RequestContext) DeepCopyInto(out *RequestContext) { + *out = *in + in.HTTP.DeepCopyInto(&out.HTTP) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RequestContext. +func (in *RequestContext) DeepCopy() *RequestContext { + if in == nil { + return nil + } + out := new(RequestContext) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *S3Handler) DeepCopyInto(out *S3Handler) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new S3Handler. +func (in *S3Handler) DeepCopy() *S3Handler { + if in == nil { + return nil + } + out := new(S3Handler) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *S3ObjectStorage) DeepCopyInto(out *S3ObjectStorage) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new S3ObjectStorage. +func (in *S3ObjectStorage) DeepCopy() *S3ObjectStorage { + if in == nil { + return nil + } + out := new(S3ObjectStorage) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SLPRestartConfig) DeepCopyInto(out *SLPRestartConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SLPRestartConfig. +func (in *SLPRestartConfig) DeepCopy() *SLPRestartConfig { + if in == nil { + return nil + } + out := new(SLPRestartConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SSOConfig) DeepCopyInto(out *SSOConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SSOConfig. +func (in *SSOConfig) DeepCopy() *SSOConfig { + if in == nil { + return nil + } + out := new(SSOConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SentryConfig) DeepCopyInto(out *SentryConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SentryConfig. +func (in *SentryConfig) DeepCopy() *SentryConfig { + if in == nil { + return nil + } + out := new(SentryConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StyraConfig) DeepCopyInto(out *StyraConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StyraConfig. +func (in *StyraConfig) DeepCopy() *StyraConfig { + if in == nil { + return nil + } + out := new(StyraConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLSConfig) DeepCopyInto(out *TLSConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSConfig. +func (in *TLSConfig) DeepCopy() *TLSConfig { + if in == nil { + return nil + } + out := new(TLSConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UserCredentialHandler) DeepCopyInto(out *UserCredentialHandler) { + *out = *in + if in.S3 != nil { + in, out := &in.S3, &out.S3 + *out = new(S3Handler) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserCredentialHandler. +func (in *UserCredentialHandler) DeepCopy() *UserCredentialHandler { + if in == nil { + return nil + } + out := new(UserCredentialHandler) + in.DeepCopyInto(out) + return out +} diff --git a/api/styra/v1alpha1/groupversion_info.go b/api/styra/v1alpha1/groupversion_info.go index c9c50377..78ccec87 100644 --- a/api/styra/v1alpha1/groupversion_info.go +++ b/api/styra/v1alpha1/groupversion_info.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/styra/v1alpha1/library_types.go b/api/styra/v1alpha1/library_types.go index 08a97fd3..18cdac83 100644 --- a/api/styra/v1alpha1/library_types.go +++ b/api/styra/v1alpha1/library_types.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/styra/v1alpha1/zz_generated.deepcopy.go b/api/styra/v1alpha1/zz_generated.deepcopy.go index acb9438c..0ff6343f 100644 --- a/api/styra/v1alpha1/zz_generated.deepcopy.go +++ b/api/styra/v1alpha1/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ //go:build !ignore_autogenerated /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/styra/v1beta1/groupversion_info.go b/api/styra/v1beta1/groupversion_info.go index d68fe1d6..4104bcaf 100644 --- a/api/styra/v1beta1/groupversion_info.go +++ b/api/styra/v1beta1/groupversion_info.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/styra/v1beta1/system_types.go b/api/styra/v1beta1/system_types.go index 78971a42..1365c7ca 100644 --- a/api/styra/v1beta1/system_types.go +++ b/api/styra/v1beta1/system_types.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/styra/v1beta1/system_types_test.go b/api/styra/v1beta1/system_types_test.go index beeb625b..457dd579 100644 --- a/api/styra/v1beta1/system_types_test.go +++ b/api/styra/v1beta1/system_types_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/styra/v1beta1/v1beta1_suite_test.go b/api/styra/v1beta1/v1beta1_suite_test.go index c67026a9..10fc6d83 100644 --- a/api/styra/v1beta1/v1beta1_suite_test.go +++ b/api/styra/v1beta1/v1beta1_suite_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/styra/v1beta1/zz_generated.deepcopy.go b/api/styra/v1beta1/zz_generated.deepcopy.go index bdcf0a30..3194b8ee 100644 --- a/api/styra/v1beta1/zz_generated.deepcopy.go +++ b/api/styra/v1beta1/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ //go:build !ignore_autogenerated /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/test/v1/groupversion_info.go b/api/test/v1/groupversion_info.go index 3a2fc22e..ca292993 100644 --- a/api/test/v1/groupversion_info.go +++ b/api/test/v1/groupversion_info.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/test/v1/object_types.go b/api/test/v1/object_types.go index 4ab42596..ca13e635 100644 --- a/api/test/v1/object_types.go +++ b/api/test/v1/object_types.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/test/v1/zz_generated.deepcopy.go b/api/test/v1/zz_generated.deepcopy.go index 9483962e..be9c8cfd 100644 --- a/api/test/v1/zz_generated.deepcopy.go +++ b/api/test/v1/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ //go:build !ignore_autogenerated /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/build/package/Dockerfile b/build/package/Dockerfile index d2c4350d..b649a64a 100644 --- a/build/package/Dockerfile +++ b/build/package/Dockerfile @@ -1,4 +1,4 @@ -# Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +# Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cmd/main.go b/cmd/main.go index fb4b3f8b..103a2c95 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -44,6 +44,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/metrics" configv2alpha2 "github.com/bankdata/styra-controller/api/config/v2alpha2" + configv2alpha3 "github.com/bankdata/styra-controller/api/config/v2alpha3" styrav1alpha1 "github.com/bankdata/styra-controller/api/styra/v1alpha1" styrav1beta1 "github.com/bankdata/styra-controller/api/styra/v1beta1" "github.com/bankdata/styra-controller/internal/config" @@ -75,6 +76,7 @@ func init() { utilruntime.Must(styrav1alpha1.AddToScheme(scheme)) utilruntime.Must(styrav1beta1.AddToScheme(scheme)) utilruntime.Must(configv2alpha2.AddToScheme(scheme)) + utilruntime.Must(configv2alpha3.AddToScheme(scheme)) //+kubebuilder:scaffold:scheme } @@ -194,13 +196,13 @@ func main() { styraClient = styra.New(styraHostURL, styraToken) if err := configureExporter( - styraClient, ctrlConfig.DecisionsExporter, configv2alpha2.ExporterConfigTypeDecisions); err != nil { - log.Error(err, fmt.Sprintf("unable to configure %s", configv2alpha2.ExporterConfigTypeDecisions)) + styraClient, ctrlConfig.DecisionsExporter, configv2alpha3.ExporterConfigTypeDecisions); err != nil { + log.Error(err, fmt.Sprintf("unable to configure %s", configv2alpha3.ExporterConfigTypeDecisions)) } if err := configureExporter( - styraClient, ctrlConfig.ActivityExporter, configv2alpha2.ExporterConfigTypeActivity); err != nil { - log.Error(err, fmt.Sprintf("unable to configure %s", configv2alpha2.ExporterConfigTypeActivity)) + styraClient, ctrlConfig.ActivityExporter, configv2alpha3.ExporterConfigTypeActivity); err != nil { + log.Error(err, fmt.Sprintf("unable to configure %s", configv2alpha3.ExporterConfigTypeActivity)) } } @@ -354,8 +356,8 @@ func exit(err error) { func configureExporter( styraClient styra.ClientInterface, - exporterConfig *configv2alpha2.ExporterConfig, - exporterType configv2alpha2.ExporterConfigType) error { + exporterConfig *configv2alpha3.ExporterConfig, + exporterType configv2alpha3.ExporterConfigType) error { if exporterConfig == nil { ctrl.Log.Info(fmt.Sprintf("no exporter configuration found for %s", exporterType)) return nil @@ -371,10 +373,10 @@ func configureExporter( return err } - if exporterType == configv2alpha2.ExporterConfigTypeActivity { + if exporterType == configv2alpha3.ExporterConfigTypeActivity { rawJSON := json.RawMessage("{\"activity_exporter\": null}") _, err = styraClient.UpdateWorkspaceRaw(context.Background(), rawJSON) - } else if exporterType == configv2alpha2.ExporterConfigTypeDecisions { + } else if exporterType == configv2alpha3.ExporterConfigTypeDecisions { rawJSON := json.RawMessage("{\"decisions_exporter\": null}") _, err = styraClient.UpdateWorkspaceRaw(context.Background(), rawJSON) } diff --git a/cmd/main_test.go b/cmd/main_test.go index efcbb2e1..cd97e334 100644 --- a/cmd/main_test.go +++ b/cmd/main_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ package main import ( "encoding/json" - configv2alpha2 "github.com/bankdata/styra-controller/api/config/v2alpha2" + configv2alpha3 "github.com/bankdata/styra-controller/api/config/v2alpha3" "github.com/bankdata/styra-controller/pkg/styra" styraclientmock "github.com/bankdata/styra-controller/pkg/styra/mocks" ginkgo "github.com/onsi/ginkgo/v2" @@ -41,11 +41,11 @@ var _ = ginkgo.Describe("ConfigureDecisionsExporter", func() { // Test cases for ConfigureExporter for Decisions ginkgo.DescribeTable("ConfigureDecisionsExporter", func(test test) { // Arrange - ctrlConfig := &configv2alpha2.ProjectConfig{ - DecisionsExporter: &configv2alpha2.ExporterConfig{ + ctrlConfig := &configv2alpha3.ProjectConfig{ + DecisionsExporter: &configv2alpha3.ExporterConfig{ Enabled: test.enabled, - Kafka: &configv2alpha2.KafkaConfig{ - TLS: &configv2alpha2.TLSConfig{ + Kafka: &configv2alpha3.KafkaConfig{ + TLS: &configv2alpha3.TLSConfig{ ClientCertificateName: "test-cert-name", ClientCertificate: "test-cert", ClientKey: "test-key", @@ -168,11 +168,11 @@ var _ = ginkgo.Describe("ConfigureActivityExporter", func() { // Test cases for ConfigureExporter for Activity ginkgo.DescribeTable("ConfigureActivityExporter", func(test test) { // Arrange - ctrlConfig := &configv2alpha2.ProjectConfig{ - ActivityExporter: &configv2alpha2.ExporterConfig{ + ctrlConfig := &configv2alpha3.ProjectConfig{ + ActivityExporter: &configv2alpha3.ExporterConfig{ Enabled: test.enabled, - Kafka: &configv2alpha2.KafkaConfig{ - TLS: &configv2alpha2.TLSConfig{ + Kafka: &configv2alpha3.KafkaConfig{ + TLS: &configv2alpha3.TLSConfig{ ClientCertificateName: "test-cert-name", ClientCertificate: "test-cert", ClientKey: "test-key", diff --git a/cmd/suite_test.go b/cmd/suite_test.go index 394a9e9f..d6bc181b 100644 --- a/cmd/suite_test.go +++ b/cmd/suite_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/config/default/config.yaml b/config/default/config.yaml index efc6d78b..2f564973 100644 --- a/config/default/config.yaml +++ b/config/default/config.yaml @@ -35,7 +35,8 @@ opaControlPlaneConfig: url: https://minio-host ocpConfigSecretName: minio # Name of secret in ocp config defaultRequirements: - - library1 + - name: library1 + requirementType: git # used by controller to create users and policies userCredentialHandler: diff --git a/config/samples/config_v2alpha3_projectconfig.yaml b/config/samples/config_v2alpha3_projectconfig.yaml new file mode 100644 index 00000000..37253b98 --- /dev/null +++ b/config/samples/config_v2alpha3_projectconfig.yaml @@ -0,0 +1,148 @@ +apiVersion: config.bankdata.dk/v2alpha3 +kind: ProjectConfig + +# controllerClass sets a controller class for this controller. This allows the +# provided CRDs to target a specific controller. This is useful when running +# multiple controllers in the same cluster. +controllerClass: "" + +# deletionProtectionDefault sets the default to use with regards to deletion +# protection if it is not set on the resource. +deletionProtectionDefault: false + +# disableCRDWebhooks disables the CRD webhooks on the controller. If running +# multiple controllers in the same cluster, only one will need to have it's +# webhooks enabled. +disableCRDWebhooks: false + +# enableMigrations enables the system migration annotation. This should be kept +# disabled unless migrations need to be done. +enableMigrations: false + +# enableDeltaBundlesDefault sets the default to use with regards to delta +enableDeltaBundlesDefault: false + +# gitCredentials holds a list of git credential configurations. The repoPrefix +# of the git credential will be matched angainst repository URL in order to +# determine which credential to use. The git credential with the longest +# matching repoPrefix will be selected. +gitCredentials: [] +# - user: my-git-user +# password: my-git-password +# repoPrefix: https://github.com/my-org + +# leaderElection contains configuration for the controller-runtime leader +# election. +#leaderElection: +# leaseDuration: 15s +# renewDeadLine: 10s +# retryPeriod: 2s + +# logLevel sets the logging level of the controller. A higher number gives more +# verbosity. A number higher than 0 should only be used for debugging purposes. +logLevel: 0 + +# notificationWebhook contains configuration for how to call the notification +# webhook. +#notificationWebhook: +# address: "" + +# sentry contains configuration for how errors should be reported to sentry. +#sentry: +# debug: false +# dsn: "" +# environment: "" +# httpsProxy: "" + +# sso contains configuration for how to use SSO tokens for determining what +# groups a user belongs to. This can be used to grant members of a certain +# group access to systems. +#sso: +# identityProvider: "" +# jwtGroupsClaim: "" + +# styra contains configuration for connecting to the Styra DAS apis +styra: + address: "" + token: "" + +# systemPrefix is a prefix for all the systems that the controller creates +# in Styra DAS. This is useful in order to be able to identify what +# controller created a system in a shared Styra DAS instance. +systemPrefix: "" + +# systemSuffix is a suffix for all the systems that the controller creates +# in Styra DAS. This is useful in order to be able to identify what +# controller created a system in a shared Styra DAS instance. +systemSuffix: "" + +# systemUserRoles is a list of Styra DAS system level roles which the subjects of +# a system will be granted. +systemUserRoles: [] +# - SystemViewer +# - SystemInstall + +readOnly: true + +# possibility to enable and disable Styra and OCP reconciliation +#enableStyraReconciliation: false +#enableOPAControlPlaneReconciliation: true + +# opa contains default configuration for the opa configmap holding the opa config generated by the styra-controller +# decision_logs: https://www.openpolicyagent.org/docs/latest/configuration/#decision-logs +# request_context.http.headers: list of strings that will be added to the decision_logs +# opa: +# decision_logs: +# request_context: +# http: +# headers: +# - "Accept" +# bundleServer: +# url: https://s3-url +# path: /bundles +# metrics: +# prometheus: +# http: +# buckets: +# - 0.01 +# - 0.05 +# - 0.1 +# - 0.5 +# - 1 +# - 5 +# - 10 + +# opaControlPlaneConfig contains configuration relevant for OCP, e.g. config for creating bundles and sources. +# also contains configuration for where OPAs should send decisions to. +# opaControlPlaneConfig: +# address: ocp-url +# bundleObjectStorage: +# s3: +# bucket: bucket +# ocpConfigSecretName: ocp-config-s3-secret-name +# region: region +# url: s3-url +# defaultRequirements: +# - name: requirement1 +# requirementType: git +# gitCredentials: +# - id: github-creds +# repoPrefix: https://github.com +# libraryDatasourceChanged: webhook-url +# systemDatasourceChanged: webhook-url +# token: ocp-token +# decisionAPIConfig: +# serviceUrl: log-server-url +# reporting: +# maxDelaySeconds: 30 +# minDelaySeconds: 1 +# uploadSizeLimitBytes: 1048576 + +# userCredentialHandler contains configuration needed for creating credentials used by OPAs to fetch bundles from s3. +# userCredentialHandler: +# s3: +# accessKeyID: access-key +# bucket: bucket +# region: region +# secretAccessKey: secret-access-key +# url: s3-url \ No newline at end of file diff --git a/config/samples/styra_v1beta1_system.yaml b/config/samples/styra_v1beta1_system.yaml index df397cfc..51553b4a 100644 --- a/config/samples/styra_v1beta1_system.yaml +++ b/config/samples/styra_v1beta1_system.yaml @@ -19,6 +19,9 @@ spec: reason: path: result.reasons datasources: - - path: "test" - # TODO(user): Add fields here - \ No newline at end of file + - path: "example" + sourceControl: + origin: + path: policy + reference: refs/heads/master + url: 'https://github.com/org/repo.git' diff --git a/hack/boilerplate.go.txt b/hack/boilerplate.go.txt index 571b8c56..a15e0315 100644 --- a/hack/boilerplate.go.txt +++ b/hack/boilerplate.go.txt @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/config/config.go b/internal/config/config.go index 33ae1007..1f9382ce 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import ( "regexp" "github.com/bankdata/styra-controller/api/config/v2alpha2" + "github.com/bankdata/styra-controller/api/config/v2alpha3" "github.com/pkg/errors" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/serializer" @@ -39,7 +40,7 @@ const ( // Load loads controller configuration from the given file using the types // registered in the scheme. -func Load(file string, scheme *runtime.Scheme) (*v2alpha2.ProjectConfig, error) { +func Load(file string, scheme *runtime.Scheme) (*v2alpha3.ProjectConfig, error) { bs, err := os.ReadFile(file) if err != nil { return nil, errors.Wrap(err, "could not read config file") @@ -48,7 +49,7 @@ func Load(file string, scheme *runtime.Scheme) (*v2alpha2.ProjectConfig, error) } // OptionsFromConfig creates a manager.Options based on a configuration file -func OptionsFromConfig(cfg *v2alpha2.ProjectConfig, scheme *runtime.Scheme) manager.Options { +func OptionsFromConfig(cfg *v2alpha3.ProjectConfig, scheme *runtime.Scheme) manager.Options { o := manager.Options{ Scheme: scheme, HealthProbeBindAddress: healthProbeBindAddress, @@ -71,7 +72,7 @@ func OptionsFromConfig(cfg *v2alpha2.ProjectConfig, scheme *runtime.Scheme) mana // TokenFromConfig returns the Styra DAS api token directly from "styra.token" // in the config or using the "styra.tokenSecretPath" to retrieve it fra a secret -func TokenFromConfig(cfg *v2alpha2.ProjectConfig) (string, error) { +func TokenFromConfig(cfg *v2alpha3.ProjectConfig) (string, error) { if cfg.Styra.Token != "" { return cfg.Styra.Token, nil } @@ -87,7 +88,7 @@ func TokenFromConfig(cfg *v2alpha2.ProjectConfig) (string, error) { return "", errors.New("No token or tokenSecretPath defined in the config") } -func deserialize(data []byte, scheme *runtime.Scheme) (*v2alpha2.ProjectConfig, error) { +func deserialize(data []byte, scheme *runtime.Scheme) (*v2alpha3.ProjectConfig, error) { decoder := serializer.NewCodecFactory(scheme).UniversalDeserializer() _, gvk, err := decoder.Decode(data, nil, nil) if err != nil { @@ -102,13 +103,19 @@ func deserialize(data []byte, scheme *runtime.Scheme) (*v2alpha2.ProjectConfig, return nil, errors.New("unsupported api kind") } - cfg := &v2alpha2.ProjectConfig{} + cfg := &v2alpha3.ProjectConfig{} switch gvk.Version { - case v2alpha2.GroupVersion.Version: + case v2alpha3.GroupVersion.Version: if _, _, err := decoder.Decode(data, nil, cfg); err != nil { return nil, errors.Wrap(err, "could not decode into kind") } + case v2alpha2.GroupVersion.Version: + var v2cfg v2alpha2.ProjectConfig + if _, _, err := decoder.Decode(data, nil, &v2cfg); err != nil { + return nil, errors.Wrap(err, "could not decode into kind") + } + cfg = v2cfg.ToV2Alpha3() default: return nil, errors.New("unsupported api version") } diff --git a/internal/config/config_suite_test.go b/internal/config/config_suite_test.go index b89319e9..867de5eb 100644 --- a/internal/config/config_suite_test.go +++ b/internal/config/config_suite_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 464d1b79..5787bc0b 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -23,12 +23,15 @@ import ( "k8s.io/apimachinery/pkg/runtime" "github.com/bankdata/styra-controller/api/config/v2alpha2" + "github.com/bankdata/styra-controller/api/config/v2alpha3" ) var _ = ginkgo.DescribeTable("deserialize", - func(data []byte, expected *v2alpha2.ProjectConfig, shouldErr bool) { + func(data []byte, expected *v2alpha3.ProjectConfig, shouldErr bool) { scheme := runtime.NewScheme() - err := v2alpha2.AddToScheme(scheme) + err := v2alpha3.AddToScheme(scheme) + gomega.Ω(err).ShouldNot(gomega.HaveOccurred()) + err = v2alpha2.AddToScheme(scheme) gomega.Ω(err).ShouldNot(gomega.HaveOccurred()) actual, err := deserialize(data, scheme) if shouldErr { @@ -50,19 +53,19 @@ styra: true, ), - ginkgo.Entry("can deserialize v2alpha2", + ginkgo.Entry("can deserialize v2alpha3", []byte(` -apiVersion: config.bankdata.dk/v2alpha2 +apiVersion: config.bankdata.dk/v2alpha3 kind: ProjectConfig styra: token: my-token `), - &v2alpha2.ProjectConfig{ + &v2alpha3.ProjectConfig{ TypeMeta: metav1.TypeMeta{ Kind: "ProjectConfig", - APIVersion: v2alpha2.GroupVersion.Identifier(), + APIVersion: v2alpha3.GroupVersion.Identifier(), }, - Styra: v2alpha2.StyraConfig{ + Styra: v2alpha3.StyraConfig{ Token: "my-token", }, }, diff --git a/internal/controller/styra/library_controller.go b/internal/controller/styra/library_controller.go index 593f3f87..9b298c35 100644 --- a/internal/controller/styra/library_controller.go +++ b/internal/controller/styra/library_controller.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -41,7 +41,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" - configv2alpha2 "github.com/bankdata/styra-controller/api/config/v2alpha2" + configv2alpha3 "github.com/bankdata/styra-controller/api/config/v2alpha3" styrav1alpha1 "github.com/bankdata/styra-controller/api/styra/v1alpha1" "github.com/bankdata/styra-controller/pkg/ocp" ) @@ -52,7 +52,7 @@ type LibraryReconciler struct { Scheme *runtime.Scheme Styra styra.ClientInterface OCP ocp.ClientInterface - Config *configv2alpha2.ProjectConfig + Config *configv2alpha3.ProjectConfig WebhookClient webhook.Client } @@ -543,7 +543,7 @@ func (r *LibraryReconciler) updateRoleBindingSubjects( func createLibraryRolebindingSubjects( subjects []styrav1alpha1.LibrarySubject, - sso *configv2alpha2.SSOConfig, + sso *configv2alpha3.SSOConfig, ) []*styra.Subject { styraSubjectsByUserID := map[string]struct{}{} styraSubjectsByClaimValue := map[string]struct{}{} diff --git a/internal/controller/styra/system_controller.go b/internal/controller/styra/system_controller.go index e6634fda..24bac002 100644 --- a/internal/controller/styra/system_controller.go +++ b/internal/controller/styra/system_controller.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -48,7 +48,7 @@ import ( ctrlpred "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/reconcile" - configv2alpha2 "github.com/bankdata/styra-controller/api/config/v2alpha2" + configv2alpha3 "github.com/bankdata/styra-controller/api/config/v2alpha3" "github.com/bankdata/styra-controller/api/styra/v1beta1" "github.com/bankdata/styra-controller/internal/config" ctrlerr "github.com/bankdata/styra-controller/internal/errors" @@ -83,7 +83,7 @@ type SystemReconciler struct { WebhookClient webhook.Client Recorder record.EventRecorder Metrics *SystemReconcilerMetrics - Config *configv2alpha2.ProjectConfig + Config *configv2alpha3.ProjectConfig } //+kubebuilder:rbac:groups=styra.bankdata.dk,resources=systems,verbs=get;list;watch;create;update;patch;delete @@ -400,7 +400,7 @@ func (r *SystemReconciler) ocpReconcile( } } - requirements = append(requirements, ocp.NewRequirement(datasource.Path)) + requirements = append(requirements, ocp.NewRequirement(datasource.Path, ocp.RequirementTypeData)) } system.SetCondition(v1beta1.ConditionTypeRequirementsUpdated, metav1.ConditionTrue) @@ -416,11 +416,11 @@ func (r *SystemReconciler) ocpReconcile( WithEvent(v1beta1.EventErrorUpdateSource). WithSystemCondition(v1beta1.ConditionTypeSystemSourceUpdated) } - requirements = append(requirements, ocp.NewRequirement(uniqueName)) + requirements = append(requirements, ocp.NewRequirement(uniqueName, ocp.RequirementTypeGit)) system.SetCondition(v1beta1.ConditionTypeSystemSourceUpdated, metav1.ConditionTrue) reconcileSystemBundleStart := time.Now() - result, err = r.reconcileSystemBundle(ctx, uniqueName, requirements) + result, err = r.reconcileSystemBundle(ctx, system, uniqueName, requirements) r.Metrics.ReconcileSegmentTime. WithLabelValues("reconcileSystemBundleOcp"). Observe(time.Since(reconcileSystemBundleStart).Seconds()) @@ -801,6 +801,7 @@ func (r *SystemReconciler) reconcileS3Credentials( func (r *SystemReconciler) reconcileSystemBundle( ctx context.Context, + system *v1beta1.System, uniqueName string, requirements []ocp.Requirement) (ctrl.Result, error) { if r.Config.OPAControlPlaneConfig.BundleObjectStorage.S3 == nil { @@ -821,6 +822,7 @@ func (r *SystemReconciler) reconcileSystemBundle( Name: uniqueName, ObjectStorage: objectStorage, Requirements: requirements, + Revision: bundleRevision(system, requirements), } err := r.OCP.PutBundle(ctx, bundle) @@ -830,6 +832,54 @@ func (r *SystemReconciler) reconcileSystemBundle( return ctrl.Result{}, nil } +func bundleRevision(system *v1beta1.System, requirements []ocp.Requirement) string { + if system.Spec.SourceControl == nil { + return "" + } + if len(requirements) == 0 { + return "" + } + + parts := make([]string, 0, len(requirements)+1) + + for _, requirement := range requirements { + parts = append(parts, + fmt.Sprintf(`%s:%s`, + requirement.Source, + requirementRevisionExpression(requirement), + ), + ) + } + + return fmt.Sprintf(`$"%s"`, strings.Join(parts, ",")) +} + +func requirementRevisionExpression(requirement ocp.Requirement) string { + if requirement.RequirementType == ocp.RequirementTypeGitAndData { + return fmt.Sprintf( + "commit:{input.sources[\"%s\"].git.commit}-data:{input.sources[\"%s\"].sql.hash}", + requirement.Source, + requirement.Source, + ) + } + + if requirement.RequirementType == ocp.RequirementTypeData { + return fmt.Sprintf( + "data:{input.sources[\"%s\"].sql.hash}", + requirement.Source, + ) + } + + if requirement.RequirementType == ocp.RequirementTypeGit { + return fmt.Sprintf( + "commit:{input.sources[\"%s\"].git.commit}", + requirement.Source, + ) + } + + return "no-requirement-type" +} + func (r *SystemReconciler) reconcileSystemSource( ctx context.Context, log logr.Logger, @@ -1603,7 +1653,7 @@ func (r *SystemReconciler) reconcileSubjects( func createRolebindingSubjects( subjects []v1beta1.Subject, - sso *configv2alpha2.SSOConfig, + sso *configv2alpha3.SSOConfig, ) []*styra.Subject { styraSubjectsByUserID := map[string]struct{}{} styraSubjectsByClaimValue := map[string]struct{}{} @@ -2227,7 +2277,7 @@ func (r *SystemReconciler) CreateDefaultRequirements(ctx context.Context, log lo if r.Config.EnableOPAControlPlaneReconciliation || r.Config.EnableOPAControlPlaneReconciliationTestData { log.Info("Creating ocp default requirements") for _, defaultRequirement := range r.Config.OPAControlPlaneConfig.DefaultRequirements { - _, err := r.createSourceIfNotExists(ctx, log, v1beta1.Datasource{Path: defaultRequirement}) + _, err := r.createSourceIfNotExists(ctx, log, v1beta1.Datasource{Path: defaultRequirement.Name}) if err != nil { return err } diff --git a/internal/controller/styra/system_controller_test.go b/internal/controller/styra/system_controller_test.go index 77b81b4b..ed4654b5 100644 --- a/internal/controller/styra/system_controller_test.go +++ b/internal/controller/styra/system_controller_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,14 +20,15 @@ import ( ginkgo "github.com/onsi/ginkgo/v2" gomega "github.com/onsi/gomega" - configv2alpha2 "github.com/bankdata/styra-controller/api/config/v2alpha2" + configv2alpha3 "github.com/bankdata/styra-controller/api/config/v2alpha3" styrav1beta1 "github.com/bankdata/styra-controller/api/styra/v1beta1" + "github.com/bankdata/styra-controller/pkg/ocp" "github.com/bankdata/styra-controller/pkg/styra" ) var _ = ginkgo.DescribeTable("createRolebindingSubjects", func(subjects []styrav1beta1.Subject, expectedSubject []*styra.Subject) { - gomega.Ω(createRolebindingSubjects(subjects, &configv2alpha2.SSOConfig{ + gomega.Ω(createRolebindingSubjects(subjects, &configv2alpha3.SSOConfig{ IdentityProvider: "BDAD", JWTGroupsClaim: "groups", })).To(gomega.Equal(expectedSubject)) @@ -131,3 +132,33 @@ var _ = ginkgo.DescribeTable("isURLValid", ginkgo.Entry("invalid url", "google.com", false), ginkgo.Entry("invalid url", "google", false), ) + +var _ = ginkgo.DescribeTable("requirementRevisionExpression", + func(requirement ocp.Requirement, expected string) { + gomega.Ω(requirementRevisionExpression(requirement)).To(gomega.Equal(expected)) + }, + ginkgo.Entry("git revision", ocp.Requirement{ + Source: "git", + RequirementType: ocp.RequirementTypeGit, + }, + `commit:{input.sources["git"].git.commit}`, + ), + ginkgo.Entry("data revision", ocp.Requirement{ + Source: "data", + RequirementType: ocp.RequirementTypeData, + }, + `data:{input.sources["data"].sql.hash}`, + ), + ginkgo.Entry("git and data revision", ocp.Requirement{ + Source: "policy", + RequirementType: ocp.RequirementTypeGitAndData, + }, + `commit:{input.sources["policy"].git.commit}-data:{input.sources["policy"].sql.hash}`, + ), + ginkgo.Entry("unknown revision", ocp.Requirement{ + Source: "unknown", + RequirementType: ocp.RequirementTypeUnknown, + }, + "no-requirement-type", + ), +) diff --git a/internal/errors/errors.go b/internal/errors/errors.go index 285f9833..5daeab7e 100644 --- a/internal/errors/errors.go +++ b/internal/errors/errors.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/fields/fields.go b/internal/fields/fields.go index 7d80386f..be452519 100644 --- a/internal/fields/fields.go +++ b/internal/fields/fields.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/finalizer/finalizer.go b/internal/finalizer/finalizer.go index 799446f8..9afaee12 100644 --- a/internal/finalizer/finalizer.go +++ b/internal/finalizer/finalizer.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/k8sconv/k8sconv.go b/internal/k8sconv/k8sconv.go index 438b1244..67adc62f 100644 --- a/internal/k8sconv/k8sconv.go +++ b/internal/k8sconv/k8sconv.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ import ( "gopkg.in/yaml.v2" corev1 "k8s.io/api/core/v1" - configv2alpha2 "github.com/bankdata/styra-controller/api/config/v2alpha2" + configv2alpha3 "github.com/bankdata/styra-controller/api/config/v2alpha3" "github.com/bankdata/styra-controller/pkg/ocp" "github.com/bankdata/styra-controller/pkg/styra" ) @@ -143,7 +143,7 @@ type HTTPMetricsConfig struct { // OPAConfToK8sOPAConfigMapforOCP merges the information given as input into a ConfigMap for OPA func OPAConfToK8sOPAConfigMapforOCP( opaconf ocp.OPAConfig, - opaDefaultConfig configv2alpha2.OPAConfig, + opaDefaultConfig configv2alpha3.OPAConfig, customConfig map[string]interface{}, _ logr.Logger, ) (corev1.ConfigMap, error) { @@ -233,7 +233,7 @@ func OPAConfToK8sOPAConfigMapforOCP( func OPAConfToK8sOPAConfigMap( opaconf styra.OPAConfig, slpURL string, - opaDefaultConfig configv2alpha2.OPAConfig, + opaDefaultConfig configv2alpha3.OPAConfig, customConfig map[string]interface{}, ) (corev1.ConfigMap, error) { @@ -356,7 +356,7 @@ func OPAConfToK8sSLPConfigMap(opaconf styra.OPAConfig) (corev1.ConfigMap, error) // directly to Styra and not via an SLP. func OPAConfToK8sOPAConfigMapNoSLP( opaconf styra.OPAConfig, - opaDefaultConfig configv2alpha2.OPAConfig, + opaDefaultConfig configv2alpha3.OPAConfig, customConfig map[string]interface{}, ) (corev1.ConfigMap, error) { diff --git a/internal/k8sconv/k8sconv_test.go b/internal/k8sconv/k8sconv_test.go index 02d8d22a..c195c54c 100644 --- a/internal/k8sconv/k8sconv_test.go +++ b/internal/k8sconv/k8sconv_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ import ( ginkgo "github.com/onsi/ginkgo/v2" gomega "github.com/onsi/gomega" - configv2alpha2 "github.com/bankdata/styra-controller/api/config/v2alpha2" + configv2alpha3 "github.com/bankdata/styra-controller/api/config/v2alpha3" "github.com/bankdata/styra-controller/internal/k8sconv" "github.com/bankdata/styra-controller/pkg/ocp" "github.com/bankdata/styra-controller/pkg/styra" @@ -33,7 +33,7 @@ import ( var _ = ginkgo.Describe("OPAConfToK8sOPAConfigMap", func() { type test struct { - opaDefaultConfig configv2alpha2.OPAConfig + opaDefaultConfig configv2alpha3.OPAConfig opaconf styra.OPAConfig slpURL string expectedCMContent string @@ -58,10 +58,10 @@ var _ = ginkgo.Describe("OPAConfToK8sOPAConfigMap", func() { }, ginkgo.Entry("success", test{ - opaDefaultConfig: configv2alpha2.OPAConfig{ - DecisionLogs: configv2alpha2.DecisionLog{ - RequestContext: configv2alpha2.RequestContext{ - HTTP: configv2alpha2.HTTP{ + opaDefaultConfig: configv2alpha3.OPAConfig{ + DecisionLogs: configv2alpha3.DecisionLog{ + RequestContext: configv2alpha3.RequestContext{ + HTTP: configv2alpha3.HTTP{ Headers: strings.Split("header1,header2", ","), }, }, @@ -148,7 +148,7 @@ discovery: var _ = ginkgo.Describe("OPAConfToK8sOPAConfigMapNoSLP", func() { type test struct { - opaDefaultConfig configv2alpha2.OPAConfig + opaDefaultConfig configv2alpha3.OPAConfig opaconf styra.OPAConfig expectedCMContent string } @@ -173,10 +173,10 @@ var _ = ginkgo.Describe("OPAConfToK8sOPAConfigMapNoSLP", func() { }, ginkgo.Entry("success", test{ - opaDefaultConfig: configv2alpha2.OPAConfig{ - DecisionLogs: configv2alpha2.DecisionLog{ - RequestContext: configv2alpha2.RequestContext{ - HTTP: configv2alpha2.HTTP{ + opaDefaultConfig: configv2alpha3.OPAConfig{ + DecisionLogs: configv2alpha3.DecisionLog{ + RequestContext: configv2alpha3.RequestContext{ + HTTP: configv2alpha3.HTTP{ Headers: strings.Split("header1,header2", ","), }, }, @@ -221,7 +221,7 @@ decision_logs: var _ = ginkgo.Describe("OPACustomConfToK8sWithSLP", func() { type test struct { - opaDefaultConfig configv2alpha2.OPAConfig + opaDefaultConfig configv2alpha3.OPAConfig opaconf styra.OPAConfig customConfig map[string]interface{} slpURL string @@ -247,10 +247,10 @@ var _ = ginkgo.Describe("OPACustomConfToK8sWithSLP", func() { }, ginkgo.Entry("success", test{ - opaDefaultConfig: configv2alpha2.OPAConfig{ - DecisionLogs: configv2alpha2.DecisionLog{ - RequestContext: configv2alpha2.RequestContext{ - HTTP: configv2alpha2.HTTP{ + opaDefaultConfig: configv2alpha3.OPAConfig{ + DecisionLogs: configv2alpha3.DecisionLog{ + RequestContext: configv2alpha3.RequestContext{ + HTTP: configv2alpha3.HTTP{ Headers: strings.Split("header1,header2", ","), }, }, @@ -296,7 +296,7 @@ distributed_tracing: var _ = ginkgo.Describe("OPACustomConfToK8sNoSLP", func() { type test struct { - opaDefaultConfig configv2alpha2.OPAConfig + opaDefaultConfig configv2alpha3.OPAConfig opaconf styra.OPAConfig customConfig map[string]interface{} expectedCMContent string @@ -321,10 +321,10 @@ var _ = ginkgo.Describe("OPACustomConfToK8sNoSLP", func() { }, ginkgo.Entry("success", test{ - opaDefaultConfig: configv2alpha2.OPAConfig{ - DecisionLogs: configv2alpha2.DecisionLog{ - RequestContext: configv2alpha2.RequestContext{ - HTTP: configv2alpha2.HTTP{ + opaDefaultConfig: configv2alpha3.OPAConfig{ + DecisionLogs: configv2alpha3.DecisionLog{ + RequestContext: configv2alpha3.RequestContext{ + HTTP: configv2alpha3.HTTP{ Headers: strings.Split("header1,header2", ","), }, }, @@ -379,7 +379,7 @@ distributed_tracing: var _ = ginkgo.Describe("OPAConfToK8sOPAConfigMapforOCP", func() { type test struct { - opaDefaultConfig configv2alpha2.OPAConfig + opaDefaultConfig configv2alpha3.OPAConfig opaconf ocp.OPAConfig customConfig map[string]interface{} expectedCMContent string @@ -407,10 +407,10 @@ var _ = ginkgo.Describe("OPAConfToK8sOPAConfigMapforOCP", func() { gomega.Expect(actualMap).To(gomega.Equal(expectedMap)) }, ginkgo.Entry("success", test{ - opaDefaultConfig: configv2alpha2.OPAConfig{ - DecisionLogs: configv2alpha2.DecisionLog{ - RequestContext: configv2alpha2.RequestContext{ - HTTP: configv2alpha2.HTTP{ + opaDefaultConfig: configv2alpha3.OPAConfig{ + DecisionLogs: configv2alpha3.DecisionLog{ + RequestContext: configv2alpha3.RequestContext{ + HTTP: configv2alpha3.HTTP{ Headers: strings.Split("header1,header2", ","), }, }, @@ -438,7 +438,7 @@ var _ = ginkgo.Describe("OPAConfToK8sOPAConfigMapforOCP", func() { }, }, }, - DecisionLogReporting: configv2alpha2.DecisionLogReporting{ + DecisionLogReporting: configv2alpha3.DecisionLogReporting{ UploadSizeLimitBytes: 1, MinDelaySeconds: 2, MaxDelaySeconds: 3, @@ -498,7 +498,7 @@ distributed_tracing: var _ = ginkgo.Describe("OPAConfToK8sOPAConfigMapforOCP", func() { type test struct { - opaDefaultConfig configv2alpha2.OPAConfig + opaDefaultConfig configv2alpha3.OPAConfig opaconf ocp.OPAConfig customConfig map[string]interface{} expectedCMContent string @@ -527,10 +527,10 @@ var _ = ginkgo.Describe("OPAConfToK8sOPAConfigMapforOCP", func() { }, ginkgo.Entry("success", test{ - opaDefaultConfig: configv2alpha2.OPAConfig{ - DecisionLogs: configv2alpha2.DecisionLog{ - RequestContext: configv2alpha2.RequestContext{ - HTTP: configv2alpha2.HTTP{ + opaDefaultConfig: configv2alpha3.OPAConfig{ + DecisionLogs: configv2alpha3.DecisionLog{ + RequestContext: configv2alpha3.RequestContext{ + HTTP: configv2alpha3.HTTP{ Headers: strings.Split("header1,header2", ","), }, }, @@ -557,7 +557,7 @@ var _ = ginkgo.Describe("OPAConfToK8sOPAConfigMapforOCP", func() { }, }, }, - DecisionLogReporting: configv2alpha2.DecisionLogReporting{ + DecisionLogReporting: configv2alpha3.DecisionLogReporting{ UploadSizeLimitBytes: 1048576, MinDelaySeconds: 1, MaxDelaySeconds: 30, diff --git a/internal/k8sconv/suite_test.go b/internal/k8sconv/suite_test.go index f858eba3..fc69c3fd 100644 --- a/internal/k8sconv/suite_test.go +++ b/internal/k8sconv/suite_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/labels/labels.go b/internal/labels/labels.go index 23ede075..4be8a922 100644 --- a/internal/labels/labels.go +++ b/internal/labels/labels.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/labels/labels_suite_test.go b/internal/labels/labels_suite_test.go index 42a61c14..8fedf793 100644 --- a/internal/labels/labels_suite_test.go +++ b/internal/labels/labels_suite_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/labels/labels_test.go b/internal/labels/labels_test.go index 4e4d63d7..450a984e 100644 --- a/internal/labels/labels_test.go +++ b/internal/labels/labels_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/predicate/predicate.go b/internal/predicate/predicate.go index ef23101c..1f45d66c 100644 --- a/internal/predicate/predicate.go +++ b/internal/predicate/predicate.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/predicate/predicate_test.go b/internal/predicate/predicate_test.go index d8624484..92b80c9b 100644 --- a/internal/predicate/predicate_test.go +++ b/internal/predicate/predicate_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/predicate/suite_test.go b/internal/predicate/suite_test.go index 8e7d7120..f391213e 100644 --- a/internal/predicate/suite_test.go +++ b/internal/predicate/suite_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/sentry/sentry.go b/internal/sentry/sentry.go index d5fc1ddb..d36d0f7e 100644 --- a/internal/sentry/sentry.go +++ b/internal/sentry/sentry.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/webhook/styra/v1alpha1/library_webhook.go b/internal/webhook/styra/v1alpha1/library_webhook.go index a6146968..a69b4920 100644 --- a/internal/webhook/styra/v1alpha1/library_webhook.go +++ b/internal/webhook/styra/v1alpha1/library_webhook.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/webhook/styra/v1beta1/system_webhook.go b/internal/webhook/styra/v1beta1/system_webhook.go index e68a6fe5..d98077e4 100644 --- a/internal/webhook/styra/v1beta1/system_webhook.go +++ b/internal/webhook/styra/v1beta1/system_webhook.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/webhook/styra/v1beta1/system_webhook_test.go b/internal/webhook/styra/v1beta1/system_webhook_test.go index 3da419dc..34e70fe1 100644 --- a/internal/webhook/styra/v1beta1/system_webhook_test.go +++ b/internal/webhook/styra/v1beta1/system_webhook_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/webhook/styra/v1beta1/webhook_suite_test.go b/internal/webhook/styra/v1beta1/webhook_suite_test.go index bd0d55c2..c9607c00 100644 --- a/internal/webhook/styra/v1beta1/webhook_suite_test.go +++ b/internal/webhook/styra/v1beta1/webhook_suite_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/webhook/suite_test.go b/internal/webhook/suite_test.go index 09ad3ea0..60436648 100644 --- a/internal/webhook/suite_test.go +++ b/internal/webhook/suite_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/webhook/webhook.go b/internal/webhook/webhook.go index 68b27d1c..9acc4e2c 100644 --- a/internal/webhook/webhook.go +++ b/internal/webhook/webhook.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/webhook/webhook_test.go b/internal/webhook/webhook_test.go index ab99905b..d3262449 100644 --- a/internal/webhook/webhook_test.go +++ b/internal/webhook/webhook_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/httperror/httperror.go b/pkg/httperror/httperror.go index f14aeccc..9cd221e7 100644 --- a/pkg/httperror/httperror.go +++ b/pkg/httperror/httperror.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/ocp/bundles.go b/pkg/ocp/bundles.go index 4e3b1e0e..0c23b9f7 100644 --- a/pkg/ocp/bundles.go +++ b/pkg/ocp/bundles.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -30,15 +30,6 @@ const ( endpointV1Bundles = "/v1/bundles" ) -// BundleConfig represents the configuration of a bundle in the OCP APIs. -type BundleConfig struct { - Name string `json:"-" yaml:"-"` - Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` - ObjectStorage ObjectStorage `json:"object_storage,omitempty" yaml:"object_storage,omitempty"` - Requirements []Requirement `json:"requirements,omitempty" yaml:"requirements,omitempty"` - ExcludedFiles []string `json:"excluded_files,omitempty" yaml:"excluded_files,omitempty"` -} - // ObjectStorage represents the object storage configuration for a bundle. type ObjectStorage struct { AmazonS3 *AmazonS3 `json:"aws,omitempty" yaml:"aws,omitempty"` @@ -84,6 +75,7 @@ type PutBundleRequest struct { Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` ObjectStorage ObjectStorage `json:"object_storage,omitempty" yaml:"object_storage,omitempty"` Requirements []Requirement `json:"requirements,omitempty" yaml:"requirements,omitempty"` + Revision string `json:"revision,omitempty" yaml:"revision,omitempty"` ExcludedFiles []string `json:"excluded_files,omitempty" yaml:"excluded_files,omitempty"` } diff --git a/pkg/ocp/client.go b/pkg/ocp/client.go index 443810bf..b6b1f3f8 100644 --- a/pkg/ocp/client.go +++ b/pkg/ocp/client.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/ocp/opaconfig.go b/pkg/ocp/opaconfig.go index 2b228691..366f5d12 100644 --- a/pkg/ocp/opaconfig.go +++ b/pkg/ocp/opaconfig.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ limitations under the License. package ocp import ( - configv2alpha2 "github.com/bankdata/styra-controller/api/config/v2alpha2" + configv2alpha3 "github.com/bankdata/styra-controller/api/config/v2alpha3" ) // OPAConfig stores the information going into the ConfigMap for the OPA @@ -27,7 +27,7 @@ type OPAConfig struct { UniqueName string Namespace string BundleResource string - DecisionLogReporting configv2alpha2.DecisionLogReporting + DecisionLogReporting configv2alpha3.DecisionLogReporting } // OPAServiceConfig defines a services added to the OPAs' config files. diff --git a/pkg/ocp/sources.go b/pkg/ocp/sources.go index 351cfcdc..a79c511e 100644 --- a/pkg/ocp/sources.go +++ b/pkg/ocp/sources.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import ( "io" "net/http" + configv2alpha3 "github.com/bankdata/styra-controller/api/config/v2alpha3" "github.com/bankdata/styra-controller/pkg/httperror" "github.com/pkg/errors" ) @@ -109,27 +110,40 @@ type Secret struct { // Requirement represents a requirement for a bundle and a source. type Requirement struct { - Source string `json:"source,omitempty" yaml:"source,omitempty"` - Git GitRequirement `json:"git,omitempty" yaml:"git,omitempty"` + Source string + RequirementType RequirementType } -// GitRequirement represents Git requirement. -type GitRequirement struct { - Commit *string `json:"commit,omitempty" yaml:"commit,omitempty"` -} +// RequirementType defines the different types of requirements +type RequirementType string + +const ( + // RequirementTypeGit means that the requirement is a git source + RequirementTypeGit RequirementType = "git" + + // RequirementTypeData means that the requirement is a data source + RequirementTypeData RequirementType = "data" + + // RequirementTypeGitAndData means that the requirement is both a git and a data source + RequirementTypeGitAndData RequirementType = "git_and_data" + + // RequirementTypeUnknown means that the requirement type is unknown + RequirementTypeUnknown RequirementType = "unknown" +) // NewRequirement creates a new Requirement for a bundle. -func NewRequirement(source string) Requirement { +func NewRequirement(source string, sourceType RequirementType) Requirement { return Requirement{ - Source: source, + Source: source, + RequirementType: sourceType, } } -// ToRequirements converts a list of sources to a list of Requirements. -func ToRequirements(sources []string) []Requirement { +// ToRequirements converts the default requirements to a list of bundle Requirements. +func ToRequirements(sources []configv2alpha3.DefaultRequirement) []Requirement { requirements := make([]Requirement, len(sources)) for i, source := range sources { - requirements[i] = NewRequirement(source) + requirements[i] = NewRequirement(source.Name, RequirementType(source.RequirementType)) } return requirements } diff --git a/pkg/ptr/ptr.go b/pkg/ptr/ptr.go index 62998a2a..4b645d77 100644 --- a/pkg/ptr/ptr.go +++ b/pkg/ptr/ptr.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/ptr/ptr_test.go b/pkg/ptr/ptr_test.go index d7aa60c6..6fb621cb 100644 --- a/pkg/ptr/ptr_test.go +++ b/pkg/ptr/ptr_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/ptr/suite_test.go b/pkg/ptr/suite_test.go index 932186bf..a1ec509e 100644 --- a/pkg/ptr/suite_test.go +++ b/pkg/ptr/suite_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/s3/client.go b/pkg/s3/client.go index 4c750820..4ae3a2a6 100644 --- a/pkg/s3/client.go +++ b/pkg/s3/client.go @@ -4,11 +4,11 @@ package s3 import ( "strings" - configv2alpha2 "github.com/bankdata/styra-controller/api/config/v2alpha2" + configv2alpha3 "github.com/bankdata/styra-controller/api/config/v2alpha3" ) // NewClient creates a new S3Client for MinIO -func NewClient(s3Handler configv2alpha2.S3Handler) (Client, error) { +func NewClient(s3Handler configv2alpha3.S3Handler) (Client, error) { config := Config{ AccessKeyID: s3Handler.AccessKeyID, SecretAccessKey: s3Handler.SecretAccessKey, diff --git a/pkg/styra/authz.go b/pkg/styra/authz.go index 837cf2f5..3c1bce16 100644 --- a/pkg/styra/authz.go +++ b/pkg/styra/authz.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/authz_test.go b/pkg/styra/authz_test.go index 73035169..7496e831 100644 --- a/pkg/styra/authz_test.go +++ b/pkg/styra/authz_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/client.go b/pkg/styra/client.go index d424f224..ebed269f 100644 --- a/pkg/styra/client.go +++ b/pkg/styra/client.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/client_test.go b/pkg/styra/client_test.go index 0f91c10b..dd4bf19d 100644 --- a/pkg/styra/client_test.go +++ b/pkg/styra/client_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/datasources.go b/pkg/styra/datasources.go index ae19c6b1..0fb0329e 100644 --- a/pkg/styra/datasources.go +++ b/pkg/styra/datasources.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/datasources_test.go b/pkg/styra/datasources_test.go index 7037b694..00634a06 100644 --- a/pkg/styra/datasources_test.go +++ b/pkg/styra/datasources_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/invitations.go b/pkg/styra/invitations.go index 47be1f30..2c54e47d 100644 --- a/pkg/styra/invitations.go +++ b/pkg/styra/invitations.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/invitations_test.go b/pkg/styra/invitations_test.go index b0a03f87..a0c99222 100644 --- a/pkg/styra/invitations_test.go +++ b/pkg/styra/invitations_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/library.go b/pkg/styra/library.go index 60c4cb18..87648184 100644 --- a/pkg/styra/library.go +++ b/pkg/styra/library.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/library_test.go b/pkg/styra/library_test.go index 52cbaff3..6d5c1039 100644 --- a/pkg/styra/library_test.go +++ b/pkg/styra/library_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/opaconfig.go b/pkg/styra/opaconfig.go index ba6e1f62..83c439af 100644 --- a/pkg/styra/opaconfig.go +++ b/pkg/styra/opaconfig.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/opaconfig_test.go b/pkg/styra/opaconfig_test.go index 675a750c..73dbe4e6 100644 --- a/pkg/styra/opaconfig_test.go +++ b/pkg/styra/opaconfig_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/secrets.go b/pkg/styra/secrets.go index b12c4fd1..03efb2ee 100644 --- a/pkg/styra/secrets.go +++ b/pkg/styra/secrets.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/secrets_test.go b/pkg/styra/secrets_test.go index e84233fa..7b7992a9 100644 --- a/pkg/styra/secrets_test.go +++ b/pkg/styra/secrets_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/suite_test.go b/pkg/styra/suite_test.go index 66bf88cc..0e13e7da 100644 --- a/pkg/styra/suite_test.go +++ b/pkg/styra/suite_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/systems.go b/pkg/styra/systems.go index db8ccbdb..27675f34 100644 --- a/pkg/styra/systems.go +++ b/pkg/styra/systems.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/systems_test.go b/pkg/styra/systems_test.go index 5dd4df1f..564e71e1 100644 --- a/pkg/styra/systems_test.go +++ b/pkg/styra/systems_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/users.go b/pkg/styra/users.go index ebafd9eb..2d113c07 100644 --- a/pkg/styra/users.go +++ b/pkg/styra/users.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/users_test.go b/pkg/styra/users_test.go index 80b5d432..da927ce7 100644 --- a/pkg/styra/users_test.go +++ b/pkg/styra/users_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/workspace.go b/pkg/styra/workspace.go index 980dd403..3e3cf6c6 100644 --- a/pkg/styra/workspace.go +++ b/pkg/styra/workspace.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/styra/workspace_test.go b/pkg/styra/workspace_test.go index 561398c4..596d8310 100644 --- a/pkg/styra/workspace_test.go +++ b/pkg/styra/workspace_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -119,4 +119,5 @@ var _ = ginkgo.Describe("UpdateWorkspace", func() { expectStyraErr: true, }), ) + }) diff --git a/scripts/gen-api-docs/gen-api-docs.sh b/scripts/gen-api-docs/gen-api-docs.sh index 2a575ad5..d4e35cda 100755 --- a/scripts/gen-api-docs/gen-api-docs.sh +++ b/scripts/gen-api-docs/gen-api-docs.sh @@ -1,4 +1,4 @@ -# Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +# Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/test/integration/controller/controller_suite_test.go b/test/integration/controller/controller_suite_test.go index 7ed9900f..11094425 100644 --- a/test/integration/controller/controller_suite_test.go +++ b/test/integration/controller/controller_suite_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - configv2alpha2 "github.com/bankdata/styra-controller/api/config/v2alpha2" + configv2alpha3 "github.com/bankdata/styra-controller/api/config/v2alpha3" styrav1alpha1 "github.com/bankdata/styra-controller/api/styra/v1alpha1" styrav1beta1 "github.com/bankdata/styra-controller/api/styra/v1beta1" styractrls "github.com/bankdata/styra-controller/internal/controller/styra" @@ -128,9 +128,9 @@ var _ = ginkgo.BeforeSuite(func() { S3: s3ClientMock, WebhookClient: webhookMock, Recorder: k8sManager.GetEventRecorderFor("system-controller"), - Config: &configv2alpha2.ProjectConfig{ + Config: &configv2alpha3.ProjectConfig{ SystemUserRoles: []string{string(styra.RoleSystemViewer)}, - SSO: &configv2alpha2.SSOConfig{ + SSO: &configv2alpha3.SSOConfig{ IdentityProvider: "AzureAD Bankdata", JWTGroupsClaim: "groups", }, @@ -139,33 +139,38 @@ var _ = ginkgo.BeforeSuite(func() { EnableDeltaBundlesDefault: ptr.Bool(false), EnableStyraReconciliation: true, EnableOPAControlPlaneReconciliation: true, - OPAControlPlaneConfig: &configv2alpha2.OPAControlPlaneConfig{ + OPAControlPlaneConfig: &configv2alpha3.OPAControlPlaneConfig{ Address: "ocp-url", Token: "ocp-token", - GitCredentials: []*configv2alpha2.GitCredentials{&configv2alpha2.GitCredentials{ + GitCredentials: []*configv2alpha3.GitCredentials{&configv2alpha3.GitCredentials{ ID: "github-credentials", RepoPrefix: "https://github", }}, - DefaultRequirements: []string{"library1"}, - BundleObjectStorage: &configv2alpha2.BundleObjectStorage{ - S3: &configv2alpha2.S3ObjectStorage{ + DefaultRequirements: []configv2alpha3.DefaultRequirement{ + { + Name: "library1", + RequirementType: configv2alpha3.RequirementTypeGitAndData, + }, + }, + BundleObjectStorage: &configv2alpha3.BundleObjectStorage{ + S3: &configv2alpha3.S3ObjectStorage{ Bucket: "test-bucket", Region: "eu-west-1", URL: "s3-url", OCPConfigSecretName: "s3-credentials", }, }, - DecisionAPIConfig: &configv2alpha2.DecisionAPIConfig{ + DecisionAPIConfig: &configv2alpha3.DecisionAPIConfig{ ServiceURL: "log-api-url", - Reporting: configv2alpha2.DecisionLogReporting{ + Reporting: configv2alpha3.DecisionLogReporting{ MaxDelaySeconds: 60, MinDelaySeconds: 5, UploadSizeLimitBytes: 1024, }, }, }, - UserCredentialHandler: &configv2alpha2.UserCredentialHandler{ - S3: &configv2alpha2.S3Handler{ + UserCredentialHandler: &configv2alpha3.UserCredentialHandler{ + S3: &configv2alpha3.S3Handler{ Bucket: "test-bucket", Region: "eu-west-1", URL: "s3-url", @@ -173,8 +178,8 @@ var _ = ginkgo.BeforeSuite(func() { SecretAccessKey: "secret-access-key", }, }, - OPA: configv2alpha2.OPAConfig{ - BundleServer: &configv2alpha2.OPABundleServer{ + OPA: configv2alpha3.OPAConfig{ + BundleServer: &configv2alpha3.OPABundleServer{ URL: "https://s3-url2", Path: "/test-bucket", }, @@ -210,13 +215,13 @@ var _ = ginkgo.BeforeSuite(func() { gomega.Expect(err).NotTo(gomega.HaveOccurred()) libraryReconciler := &styractrls.LibraryReconciler{ - Config: &configv2alpha2.ProjectConfig{ - SSO: &configv2alpha2.SSOConfig{ + Config: &configv2alpha3.ProjectConfig{ + SSO: &configv2alpha3.SSOConfig{ IdentityProvider: "AzureAD Bankdata", JWTGroupsClaim: "groups", }, DatasourceIgnorePatterns: []string{"^.*/ignore$"}, - GitCredentials: []*configv2alpha2.GitCredential{ + GitCredentials: []*configv2alpha3.GitCredential{ {User: "test-user", Password: "test-secret"}, }, EnableStyraReconciliation: true, @@ -257,18 +262,18 @@ var _ = ginkgo.BeforeSuite(func() { OCP: ocpClientMock, WebhookClient: webhookMock, Recorder: k8sManagerPodRestart.GetEventRecorderFor("system-controller"), - Config: &configv2alpha2.ProjectConfig{ + Config: &configv2alpha3.ProjectConfig{ ControllerClass: "styra-controller-pod-restart", SystemUserRoles: []string{string(styra.RoleSystemViewer)}, - SSO: &configv2alpha2.SSOConfig{ + SSO: &configv2alpha3.SSOConfig{ IdentityProvider: "AzureAD Bankdata", JWTGroupsClaim: "groups", }, DatasourceIgnorePatterns: []string{"^.*/ignore$"}, ReadOnly: true, EnableDeltaBundlesDefault: ptr.Bool(false), - PodRestart: &configv2alpha2.PodRestartConfig{ - SLPRestart: &configv2alpha2.SLPRestartConfig{ + PodRestart: &configv2alpha3.PodRestartConfig{ + SLPRestart: &configv2alpha3.SLPRestartConfig{ Enabled: true, DeploymentType: "statefulset", }, diff --git a/test/integration/controller/library_controller_test.go b/test/integration/controller/library_controller_test.go index 9a5631c0..7529b1fa 100644 --- a/test/integration/controller/library_controller_test.go +++ b/test/integration/controller/library_controller_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/test/integration/controller/system_controller_test.go b/test/integration/controller/system_controller_test.go index da9e66fd..60ffa2d2 100644 --- a/test/integration/controller/system_controller_test.go +++ b/test/integration/controller/system_controller_test.go @@ -1,5 +1,5 @@ /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -2620,15 +2620,22 @@ var _ = ginkgo.Describe("SystemReconciler.ReconcileOCPSystem", ginkgo.Label("int }, Requirements: []ocp.Requirement{ { - Source: "library1", + Source: "library1", + RequirementType: ocp.RequirementTypeGitAndData, }, { - Source: "path-to-datasource", + Source: "path-to-datasource", + RequirementType: ocp.RequirementTypeData, }, { - Source: "default-ocp-system", + Source: "default-ocp-system", + RequirementType: ocp.RequirementTypeGit, }, }, + Revision: "$\"library1:commit:{input.sources[\"library1\"].git.commit}" + + "-data:{input.sources[\"library1\"].sql.hash}" + + ",path-to-datasource:data:{input.sources[\"path-to-datasource\"].sql.hash}" + + ",default-ocp-system:commit:{input.sources[\"default-ocp-system\"].git.commit}\"", }).Return(nil).Once() // Called in reconcileS3Credentials @@ -2679,15 +2686,22 @@ var _ = ginkgo.Describe("SystemReconciler.ReconcileOCPSystem", ginkgo.Label("int }, Requirements: []ocp.Requirement{ { - Source: "library1", + Source: "library1", + RequirementType: ocp.RequirementTypeGitAndData, }, { - Source: "path-to-datasource", + Source: "path-to-datasource", + RequirementType: ocp.RequirementTypeData, }, { - Source: "default-ocp-system", + Source: "default-ocp-system", + RequirementType: ocp.RequirementTypeGit, }, }, + Revision: "$\"library1:commit:{input.sources[\"library1\"].git.commit}" + + "-data:{input.sources[\"library1\"].sql.hash}" + + ",path-to-datasource:data:{input.sources[\"path-to-datasource\"].sql.hash}" + + ",default-ocp-system:commit:{input.sources[\"default-ocp-system\"].git.commit}\"", }).Return(nil).Once() // Called in reconcileS3Credentials @@ -2732,15 +2746,22 @@ var _ = ginkgo.Describe("SystemReconciler.ReconcileOCPSystem", ginkgo.Label("int }, Requirements: []ocp.Requirement{ { - Source: "library1", + Source: "library1", + RequirementType: ocp.RequirementTypeGitAndData, }, { - Source: "path-to-datasource", + Source: "path-to-datasource", + RequirementType: ocp.RequirementTypeData, }, { - Source: "default-ocp-system", + Source: "default-ocp-system", + RequirementType: ocp.RequirementTypeGit, }, }, + Revision: "$\"library1:commit:{input.sources[\"library1\"].git.commit}" + + "-data:{input.sources[\"library1\"].sql.hash}" + + ",path-to-datasource:data:{input.sources[\"path-to-datasource\"].sql.hash}" + + ",default-ocp-system:commit:{input.sources[\"default-ocp-system\"].git.commit}\"", }).Return(nil).Once() // Called in reconcileS3Credentials diff --git a/tools.go b/tools.go index d3cfbf35..90c7a3da 100644 --- a/tools.go +++ b/tools.go @@ -2,7 +2,7 @@ // +build tools /* -Copyright (C) 2025 Bankdata (bankdata@bankdata.dk) +Copyright (C) 2026 Bankdata (bankdata@bankdata.dk) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.