diff --git a/internal/controller/styra/system_controller.go b/internal/controller/styra/system_controller.go index e6634fda..6be49041 100644 --- a/internal/controller/styra/system_controller.go +++ b/internal/controller/styra/system_controller.go @@ -821,6 +821,7 @@ func (r *SystemReconciler) reconcileSystemBundle( Name: uniqueName, ObjectStorage: objectStorage, Requirements: requirements, + Revision: bundleRevision(), } err := r.OCP.PutBundle(ctx, bundle) @@ -830,6 +831,14 @@ func (r *SystemReconciler) reconcileSystemBundle( return ctrl.Result{}, nil } +// bundleRevision produces a string containing the commit sha for each git requirement +// and the sha256 hash of the concatenated hashes of all datasources, +// for example "data:sha256,gitsource1:commitsha1,requirement1:commitsha2" +func bundleRevision() string { + return `$"data:{crypto.sha256(concat("", {x | x := input.sources[_].sql.hash}))},` + + `{concat(",", {sprintf("%s:%s", [y, x]) | some y; x := input.sources[y].git.commit})}"` +} + func (r *SystemReconciler) reconcileSystemSource( ctx context.Context, log logr.Logger, diff --git a/pkg/ocp/bundles.go b/pkg/ocp/bundles.go index 4e3b1e0e..1ae6d8b5 100644 --- a/pkg/ocp/bundles.go +++ b/pkg/ocp/bundles.go @@ -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/test/integration/controller/system_controller_test.go b/test/integration/controller/system_controller_test.go index da9e66fd..b44ce293 100644 --- a/test/integration/controller/system_controller_test.go +++ b/test/integration/controller/system_controller_test.go @@ -2629,6 +2629,8 @@ var _ = ginkgo.Describe("SystemReconciler.ReconcileOCPSystem", ginkgo.Label("int Source: "default-ocp-system", }, }, + Revision: `$"data:{crypto.sha256(concat("", {x | x := input.sources[_].sql.hash}))},` + + `{concat(",", {sprintf("%s:%s", [y, x]) | some y; x := input.sources[y].git.commit})}"`, }).Return(nil).Once() // Called in reconcileS3Credentials @@ -2688,6 +2690,8 @@ var _ = ginkgo.Describe("SystemReconciler.ReconcileOCPSystem", ginkgo.Label("int Source: "default-ocp-system", }, }, + Revision: `$"data:{crypto.sha256(concat("", {x | x := input.sources[_].sql.hash}))},` + + `{concat(",", {sprintf("%s:%s", [y, x]) | some y; x := input.sources[y].git.commit})}"`, }).Return(nil).Once() // Called in reconcileS3Credentials @@ -2741,6 +2745,8 @@ var _ = ginkgo.Describe("SystemReconciler.ReconcileOCPSystem", ginkgo.Label("int Source: "default-ocp-system", }, }, + Revision: `$"data:{crypto.sha256(concat("", {x | x := input.sources[_].sql.hash}))},` + + `{concat(",", {sprintf("%s:%s", [y, x]) | some y; x := input.sources[y].git.commit})}"`, }).Return(nil).Once() // Called in reconcileS3Credentials