diff --git a/e2e/main_test.go b/e2e/main_test.go index e18e64b9..d6c7108b 100644 --- a/e2e/main_test.go +++ b/e2e/main_test.go @@ -39,6 +39,7 @@ var ( testRepoName = "ocm-controller-test" testRepoSignedName = "ocm-controller-signed-test" testRepoHelmName = "ocm-controller-helm-test" + testRepoSameName = "ocm-controller-same-test" testHelmChartBasedResource = "testHelmChartResource" testOCMControllerPath = "testOCMController" testSignedComponentsPath = "testSignedOCIRegistryComponents" diff --git a/e2e/same_resource_test.go b/e2e/same_resource_test.go new file mode 100644 index 00000000..9438fef4 --- /dev/null +++ b/e2e/same_resource_test.go @@ -0,0 +1,91 @@ +//go:build e2e + +package e2e + +import ( + "os" + "path/filepath" + "testing" + + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + "github.com/open-component-model/ocm-controller/api/v1alpha1" + "github.com/open-component-model/ocm-e2e-framework/shared" + "sigs.k8s.io/e2e-framework/pkg/features" + + "github.com/open-component-model/ocm-e2e-framework/shared/steps/setup" +) + +func TestSameResource(t *testing.T) { + management := features.New("Configure Management Repository"). + Setup(setup.AddScheme(v1alpha1.AddToScheme)). + Setup(setup.AddScheme(sourcev1.AddToScheme)). + Setup(setup.AddScheme(kustomizev1.AddToScheme)). + Setup(setup.AddGitRepository(testRepoSameName)). + Setup(setup.AddFluxSyncForRepo(testRepoSameName, destinationPrefix, ocmNamespace)) + + configContent, err := os.ReadFile(filepath.Join("testdata", "testOCMControllerMultipleSameResources", "config.yaml")) + if err != nil { + t.Fatal("failed to read config file: %w", err) + } + + manifestContent, err := os.ReadFile(filepath.Join("testdata", "testOCMControllerMultipleSameResources", "manifests.tar")) + if err != nil { + t.Fatal("failed to read config file: %w", err) + } + + component := setup.Component{ + Component: shared.Component{ + Name: "component.name.resources/same", + Version: "v1.0.0", + }, + ComponentVersionModifications: []shared.ComponentModification{ + shared.BlobResource(shared.Resource{ + Name: "same", + Data: string(configContent), + Type: "configdata.ocm.software", + Version: "1.0.0", + ExtraIdentity: map[string]string{ + "type": "config", + }, + }), + shared.BlobResource(shared.Resource{ + Name: "same", + Data: string(manifestContent), + Type: "kustomize.ocm.fluxcd.io", + Version: "1.0.0", + ExtraIdentity: map[string]string{ + "type": "manifest", + }, + }), + }, + } + + gitRepositoryName := "ocm-controller-test" + testName := "testOCMControllerMultipleSameResources" + + setupComponentFeature := features.New("Setup Component").Setup(setup.AddComponentVersions(component)) + componentVersionFeature := features.New("Create Manifests"). + Setup(setup.AddFilesToGitRepository(setup.File{ + RepoName: gitRepositoryName, + SourceFilepath: filepath.Join(testName, "component_version.yaml"), + DestFilepath: destinationPrefix + testName + "component_version.yaml", + }, setup.File{ + RepoName: gitRepositoryName, + SourceFilepath: filepath.Join(testName, "resource1.yaml"), + DestFilepath: destinationPrefix + testName + "resource1.yaml", + }, setup.File{ + RepoName: gitRepositoryName, + SourceFilepath: filepath.Join(testName, "resource2.yaml"), + DestFilepath: destinationPrefix + testName + "resource2.yaml", + })).Assess("check that component version component_version.yaml is ready and valid", checkIsComponentVersionReady("same-resource-component", ocmNamespace)) + + resourceAssertFeatures := features.New("Validate Resources").Setup(checkIsResourceReady("resource-1")).Setup(checkIsResourceReady("resource-2")) + + testEnv.Test(t, + setupComponentFeature.Feature(), + management.Feature(), + componentVersionFeature.Feature(), + resourceAssertFeatures.Feature(), + ) +} diff --git a/e2e/suite_test.go b/e2e/suite_test.go index 0243127c..dd258da8 100644 --- a/e2e/suite_test.go +++ b/e2e/suite_test.go @@ -16,7 +16,6 @@ import ( var ( testEnv env.Environment - kindClusterName string ocmNamespace string registryPort = 5000 gitRepositoryPort = 3000 @@ -32,14 +31,12 @@ func TestMain(m *testing.M) { path := conf.ResolveKubeConfigFile() cfg := envconf.NewWithKubeConfig(path) testEnv = env.NewWithConfig(cfg) - kindClusterName = envconf.RandomName("ocm-ctrl-e2e", 32) ocmNamespace = "ocm-system" stopChannelRegistry := make(chan struct{}, 1) stopChannelGitea := make(chan struct{}, 1) testEnv.Setup( - //envfuncs.CreateKindCluster(kindClusterName), envfuncs.CreateNamespace(ocmNamespace), shared.StartGitServer(ocmNamespace), shared.InstallFlux("latest"), @@ -53,7 +50,6 @@ func TestMain(m *testing.M) { shared.ShutdownPortForward(stopChannelRegistry), shared.ShutdownPortForward(stopChannelGitea), envfuncs.DeleteNamespace(ocmNamespace), - //envfuncs.DestroyKindCluster(kindClusterName), ) os.Exit(testEnv.Run(m)) diff --git a/e2e/testdata/testOCMControllerMultipleSameResources/component_version.yaml b/e2e/testdata/testOCMControllerMultipleSameResources/component_version.yaml new file mode 100644 index 00000000..a8eb05ef --- /dev/null +++ b/e2e/testdata/testOCMControllerMultipleSameResources/component_version.yaml @@ -0,0 +1,12 @@ +apiVersion: delivery.ocm.software/v1alpha1 +kind: ComponentVersion +metadata: + name: same-resource-component + namespace: ocm-system +spec: + component: component.name.resources/same + interval: 5s + repository: + url: registry.ocm-system.svc.cluster.local:5000 + version: + semver: ">=v1.0.0" diff --git a/e2e/testdata/testOCMControllerMultipleSameResources/config.yaml b/e2e/testdata/testOCMControllerMultipleSameResources/config.yaml new file mode 100644 index 00000000..1e129445 --- /dev/null +++ b/e2e/testdata/testOCMControllerMultipleSameResources/config.yaml @@ -0,0 +1,36 @@ +apiVersion: config.ocm.software/v1alpha1 +kind: ConfigData +metadata: + name: ocm-config-pipeline-backend + labels: + env: test +configuration: + defaults: + replicas: 1 + cacheAddr: tcp://redis:6379 + message: Hello, world! + schema: + type: object + additionalProperties: false + properties: + replicas: + type: integer + cacheAddr: + type: string + message: + type: string + rules: + - value: (( replicas )) + file: manifests/deploy.yaml + path: spec.replicas + - value: (( cacheAddr )) + file: manifests/configmap.yaml + path: data.PODINFO_CACHE_SERVER + - value: (( message )) + file: manifests/configmap.yaml + path: data.PODINFO_UI_MESSAGE +localization: + - resource: + name: image + file: manifests/deploy.yaml + image: spec.template.spec.containers[0].image diff --git a/e2e/testdata/testOCMControllerMultipleSameResources/manifests.tar b/e2e/testdata/testOCMControllerMultipleSameResources/manifests.tar new file mode 100644 index 00000000..d4d9d4ae Binary files /dev/null and b/e2e/testdata/testOCMControllerMultipleSameResources/manifests.tar differ diff --git a/e2e/testdata/testOCMControllerMultipleSameResources/resource1.yaml b/e2e/testdata/testOCMControllerMultipleSameResources/resource1.yaml new file mode 100644 index 00000000..8c2f51d8 --- /dev/null +++ b/e2e/testdata/testOCMControllerMultipleSameResources/resource1.yaml @@ -0,0 +1,15 @@ +apiVersion: delivery.ocm.software/v1alpha1 +kind: Resource +metadata: + name: resource-1 + namespace: ocm-system +spec: + interval: 5s + sourceRef: + kind: ComponentVersion + name: same-resource-component + resourceRef: + name: same + version: 1.0.0 + extraIdentity: + type: manifest diff --git a/e2e/testdata/testOCMControllerMultipleSameResources/resource2.yaml b/e2e/testdata/testOCMControllerMultipleSameResources/resource2.yaml new file mode 100644 index 00000000..89e8896c --- /dev/null +++ b/e2e/testdata/testOCMControllerMultipleSameResources/resource2.yaml @@ -0,0 +1,15 @@ +apiVersion: delivery.ocm.software/v1alpha1 +kind: Resource +metadata: + name: resource-2 + namespace: ocm-system +spec: + interval: 5s + sourceRef: + kind: ComponentVersion + name: same-resource-component + resourceRef: + name: same + version: 1.0.0 + extraIdentity: + type: config diff --git a/go.mod b/go.mod index 45e582e1..efdc3afc 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/mitchellh/hashstructure v1.1.0 github.com/mitchellh/hashstructure/v2 v2.0.2 github.com/onsi/gomega v1.37.0 - github.com/open-component-model/ocm-e2e-framework v0.11.0 + github.com/open-component-model/ocm-e2e-framework v0.11.1 github.com/open-component-model/pkg/metrics v0.0.0-20240402143848-8961dae2122b github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.1 @@ -58,10 +58,10 @@ require ( cloud.google.com/go/auth v0.15.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.6.0 // indirect - code.gitea.io/sdk/gitea v0.20.0 // indirect + code.gitea.io/sdk/gitea v0.21.0 // indirect dario.cat/mergo v1.0.1 // indirect filippo.io/edwards25519 v1.1.0 // indirect - github.com/42wim/httpsig v1.2.1 // indirect + github.com/42wim/httpsig v1.2.2 // indirect github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/provider v0.15.2 // indirect github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect @@ -151,6 +151,7 @@ require ( github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker v28.0.4+incompatible // indirect github.com/docker/docker-credential-helpers v0.9.3 // indirect + github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect github.com/docker/go-metrics v0.0.1 // indirect @@ -173,8 +174,8 @@ require ( github.com/fluxcd/pkg/apis/kustomize v1.10.0 // indirect github.com/fluxcd/pkg/envsubst v1.4.0 // indirect github.com/fluxcd/pkg/sourceignore v0.12.0 // indirect - github.com/fluxcd/pkg/ssa v0.45.1 // indirect - github.com/fluxcd/pkg/version v0.6.0 // indirect + github.com/fluxcd/pkg/ssa v0.46.0 // indirect + github.com/fluxcd/pkg/version v0.7.0 // indirect github.com/fvbommel/sortorder v1.1.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect diff --git a/go.sum b/go.sum index 011d2211..c9d8d8dc 100644 --- a/go.sum +++ b/go.sum @@ -13,8 +13,8 @@ cloud.google.com/go/kms v1.21.1 h1:r1Auo+jlfJSf8B7mUnVw5K0fI7jWyoUy65bV53VjKyk= cloud.google.com/go/kms v1.21.1/go.mod h1:s0wCyByc9LjTdCjG88toVs70U9W+cc6RKFc8zAqX7nE= cloud.google.com/go/longrunning v0.6.5 h1:sD+t8DO8j4HKW4QfouCklg7ZC1qC4uzVZt8iz3uTW+Q= cloud.google.com/go/longrunning v0.6.5/go.mod h1:Et04XK+0TTLKa5IPYryKf5DkpwImy6TluQ1QTLwlKmY= -code.gitea.io/sdk/gitea v0.20.0 h1:Zm/QDwwZK1awoM4AxdjeAQbxolzx2rIP8dDfmKu+KoU= -code.gitea.io/sdk/gitea v0.20.0/go.mod h1:faouBHC/zyx5wLgjmRKR62ydyvMzwWf3QnU0bH7Cw6U= +code.gitea.io/sdk/gitea v0.21.0 h1:69n6oz6kEVHRo1+APQQyizkhrZrLsTLXey9142pfkD4= +code.gitea.io/sdk/gitea v0.21.0/go.mod h1:tnBjVhuKJCn8ibdyyhvUyxrR1Ca2KHEoTWoukNhXQPA= cuelabs.dev/go/oci/ociregistry v0.0.0-20241125120445-2c00c104c6e1 h1:mRwydyTyhtRX2wXS3mqYWzR2qlv6KsmoKXmlz5vInjg= cuelabs.dev/go/oci/ociregistry v0.0.0-20241125120445-2c00c104c6e1/go.mod h1:5A4xfTzHTXfeVJBU6RAUf+QrlfTCW+017q/QiW+sMLg= cuelang.org/go v0.12.1 h1:5I+zxmXim9MmiN2tqRapIqowQxABv2NKTgbOspud1Eo= @@ -23,8 +23,8 @@ dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/42wim/httpsig v1.2.1 h1:oLBxptMe9U4ZmSGtkosT8Dlfg31P3VQnAGq6psXv82Y= -github.com/42wim/httpsig v1.2.1/go.mod h1:P/UYo7ytNBFwc+dg35IubuAUIs8zj5zzFIgUCEl55WY= +github.com/42wim/httpsig v1.2.2 h1:ofAYoHUNs/MJOLqQ8hIxeyz2QxOz8qdSVvp3PX/oPgA= +github.com/42wim/httpsig v1.2.2/go.mod h1:P/UYo7ytNBFwc+dg35IubuAUIs8zj5zzFIgUCEl55WY= github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk= github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/AdamKorcz/go-fuzz-headers-1 v0.0.0-20230919221257-8b5d3ce2d11d h1:zjqpY4C7H15HjRPEenkS4SAn3Jy2eRRjkjZbGR30TOg= @@ -397,14 +397,14 @@ github.com/fluxcd/pkg/runtime v0.59.0 h1:3OrFkMJB39NcQ2vhhoxqls59sQVSn8U+thhyLbs github.com/fluxcd/pkg/runtime v0.59.0/go.mod h1:MFbfyNyyoYRgPxpdwC9/dCOkzo7Yxhu/cQ9NKyhvqc0= github.com/fluxcd/pkg/sourceignore v0.12.0 h1:jCIe6d50rQ3wdXPF0+PhhqN0XrTRIq3upMomPelI8Mw= github.com/fluxcd/pkg/sourceignore v0.12.0/go.mod h1:dc0zvkuXM5OgL/b3IkrVuwvPjj1zJn4NBUMH45uJ4Y0= -github.com/fluxcd/pkg/ssa v0.45.1 h1:ISl84TJwRP/GuZXrKiR9Tf8JOnG5XFgtjcYoR4XQYf4= -github.com/fluxcd/pkg/ssa v0.45.1/go.mod h1:8Anf7XVZ0zxOve7HXbDaW1s0gfmP95ksJBlKfDYinhQ= +github.com/fluxcd/pkg/ssa v0.46.0 h1:TGomtbA6zTfZrHF0TDn3mIGKH+bbX45zdWSkdYrwS8g= +github.com/fluxcd/pkg/ssa v0.46.0/go.mod h1:qCek0b8tKumh9iNZLmga1mjeXOlZPlZpc6xip/hLMJM= github.com/fluxcd/pkg/tar v0.12.0 h1:og6F+ivnWNRbNJSq0ukCTVs7YrGIlzjxSVZU+E8NprM= github.com/fluxcd/pkg/tar v0.12.0/go.mod h1:Ra5Cj++MD5iCy7bZGKJJX3GpOeMPv+ZDkPO9bBwpDeU= github.com/fluxcd/pkg/testserver v0.11.0 h1:a/kxpFqv7XQxZjwVPP3voooRmSd/3ipLVolK0xUIxXQ= github.com/fluxcd/pkg/testserver v0.11.0/go.mod h1:E8LAH1jW9uClFjTRN27Y/gCCSrzNVx1/w/0NxKuNcas= -github.com/fluxcd/pkg/version v0.6.0 h1:tYRWpV7RvBOO5ahD525TiDhWXmhnvBM0RAIY1MCRe9s= -github.com/fluxcd/pkg/version v0.6.0/go.mod h1:ZCl5BkIvXmMm3C4q4fz4aMi5LQHvcXNSEaL2puXIZo8= +github.com/fluxcd/pkg/version v0.7.0 h1:jZT5I6WFy1KlM40nHCSqlHmjC1VT1/DfmbAdOkIVVJc= +github.com/fluxcd/pkg/version v0.7.0/go.mod h1:3BjQDJXIZJmeJLXnfa2yG/sNAT1t5oeLAPfnSjOHNuA= github.com/fluxcd/source-controller/api v1.5.0 h1:caSR+u/r2Vh0jq/0pNR0r1zLxyvgatWuGSV2mxgTB/I= github.com/fluxcd/source-controller/api v1.5.0/go.mod h1:OZPuHMlLH2E2mnj6Q5DLkWfUOmJ20zA1LIvUVfNsYl8= github.com/foxcpp/go-mockdns v1.1.0 h1:jI0rD8M0wuYAxL7r/ynTrCQQq0BVqfB99Vgk7DlmewI= @@ -608,8 +608,8 @@ github.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGN github.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= -github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/vault-client-go v0.4.3 h1:zG7STGVgn/VK6rnZc0k8PGbfv2x/sJExRKHSUg3ljWc= github.com/hashicorp/vault-client-go v0.4.3/go.mod h1:4tDw7Uhq5XOxS1fO+oMtotHL7j4sB9cp0T7U6m4FzDY= github.com/hashicorp/vault/api v1.16.0 h1:nbEYGJiAPGzT9U4oWgaaB0g+Rj8E59QuHKyA5LhwQN4= @@ -777,8 +777,8 @@ github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAl github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y= github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= -github.com/open-component-model/ocm-e2e-framework v0.11.0 h1:CMTbuKExNv6C+OBw9SeMyTHO9mFykS7iMyCht49Z+Og= -github.com/open-component-model/ocm-e2e-framework v0.11.0/go.mod h1:l+zQDj5NA89vEQlHwCCRqE+KANXxDaDuGSor4vvtw2s= +github.com/open-component-model/ocm-e2e-framework v0.11.1 h1:dXVN/23K/KgJ3QOzzcKj0j+PbbcUADmzv+Pjb2zGHl4= +github.com/open-component-model/ocm-e2e-framework v0.11.1/go.mod h1:kugoRHM8cpgOPyUZssRiareAiztRmtB0hHpnGS65y+c= github.com/open-component-model/pkg/metrics v0.0.0-20240402143848-8961dae2122b h1:Z95/2zF9f7xeTmtIWNB9oDq9jiQlkRzuOUzMNSeU1qQ= github.com/open-component-model/pkg/metrics v0.0.0-20240402143848-8961dae2122b/go.mod h1:frQj/b3+bzniEC/qUbSNUYm+pHZbjd6l0ofAsPgmEF0= github.com/opencontainers/go-digest v1.0.1-0.20220411205349-bde1400a84be h1:f2PlhC9pm5sqpBZFvnAoKj+KzXRzbjFMA+TqXfJdgho= diff --git a/pkg/fakes/ocm.go b/pkg/fakes/ocm.go index 83b8fc7a..0686d4e3 100644 --- a/pkg/fakes/ocm.go +++ b/pkg/fakes/ocm.go @@ -51,6 +51,7 @@ type Resource[M any] struct { // AccessOptions to modify the access of the resource. AccessOptions []AccessOptionFunc + ExtraIdentity ocmmetav1.Identity } // Sign defines the two needed values to perform a component signing. @@ -389,8 +390,15 @@ func (c *Component) GetResources() []ocm.ResourceAccess { func (c *Component) GetResource(meta ocmmetav1.Identity) (ocm.ResourceAccess, error) { for _, r := range c.Resources { - // && r.Version == meta["version"] --> add this at some point if r.Name == meta["name"] { + if r.ExtraIdentity != nil { + if r.ExtraIdentity.Equals(meta.ExtraIdentity()) { + return r, nil + } + + continue + } + return r, nil } } @@ -413,9 +421,10 @@ var _ ocm.ResourceAccess = &Resource[*ocm.ResourceMeta]{} func (r *Resource[M]) Meta() *ocm.ResourceMeta { return &ocm.ResourceMeta{ ElementMeta: compdesc.ElementMeta{ - Name: r.Name, - Version: r.Version, - Labels: r.Labels, + Name: r.Name, + Version: r.Version, + Labels: r.Labels, + ExtraIdentity: r.ExtraIdentity, }, Type: r.Type, Relation: r.Relation, diff --git a/pkg/ocm/credentials.go b/pkg/ocm/credentials.go index 60e60296..dbca3d44 100644 --- a/pkg/ocm/credentials.go +++ b/pkg/ocm/credentials.go @@ -5,16 +5,17 @@ import ( "fmt" "net/url" - "github.com/open-component-model/ocm-controller/api/v1alpha1" corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + "ocm.software/ocm/api/credentials" credconfig "ocm.software/ocm/api/credentials/config" "ocm.software/ocm/api/credentials/extensions/repositories/dockerconfig" "ocm.software/ocm/api/ocm" common "ocm.software/ocm/api/utils/misc" - "ocm.software/ocm/api/utils/runtime" - "sigs.k8s.io/controller-runtime/pkg/client" + + "github.com/open-component-model/ocm-controller/api/v1alpha1" ) // ConfigureCredentials takes a repository url and secret ref and configures access to an OCI repository. diff --git a/pkg/ocm/ocm.go b/pkg/ocm/ocm.go index f98afac8..bc36a125 100644 --- a/pkg/ocm/ocm.go +++ b/pkg/ocm/ocm.go @@ -235,9 +235,15 @@ func (c *Client) GetResource( var identities []ocmmetav1.Identity identities = append(identities, resource.ReferencePath...) + var extras []string + for k, v := range resource.ExtraIdentity { + extras = append(extras, k, v) + } + + // NewIdentity creates name based identity, and extra identity is added as a key value pair. res, _, err := resourcerefs.ResolveResourceReference( cva, - ocmmetav1.NewNestedResourceRef(ocmmetav1.NewIdentity(resource.Name), identities), + ocmmetav1.NewNestedResourceRef(ocmmetav1.NewIdentity(resource.Name, extras...), identities), cva.Repository(), ) if err != nil { diff --git a/pkg/ocm/ocm_test.go b/pkg/ocm/ocm_test.go index 460f76f6..3b964062 100644 --- a/pkg/ocm/ocm_test.go +++ b/pkg/ocm/ocm_test.go @@ -1036,3 +1036,115 @@ func TestClient_VerifyComponentDifferentPublicKey(t *testing.T) { require.Error(t, err) assert.False(t, verified, "verified should have been false, but it did not") } + +func TestResourceLookupWithVersionAndExtraIdentity(t *testing.T) { + // Create Two resources, identical in name but differs in extraIdentity. + // It should find the right resource. + component := "ocm.software/ocm-demo-index" + resource := "remote-controller-demo" + resourceVersion := "v0.0.1" + data1 := "testdata1" + data2 := "testdata2" + + octx := fakeocm.NewFakeOCMContext() + + comp := &fakeocm.Component{ + Name: component, + Version: "v0.0.1", + } + res1 := &fakeocm.Resource[*ocm.ResourceMeta]{ + ExtraIdentity: map[string]string{ + "type": "chart", + }, + Name: resource, + Version: resourceVersion, + Data: []byte(data1), + Component: comp, + Kind: "localBlob", + Type: "ociBlob", + } + res2 := &fakeocm.Resource[*ocm.ResourceMeta]{ + ExtraIdentity: map[string]string{ + "type": "config", + }, + Name: resource, + Version: resourceVersion, + Data: []byte(data2), + Component: comp, + Kind: "localBlob", + Type: "ociBlob", + } + comp.Resources = append(comp.Resources, res1, res2) + + _ = octx.AddComponent(comp) + + cd := &v1alpha1.ComponentDescriptor{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "github.com-open-component-model-ocm-demo-index-v0.0.1-12345", + }, + Spec: v1alpha1.ComponentDescriptorSpec{ + Version: "v0.0.1", + }, + } + + fakeKubeClient := env.FakeKubeClient(WithObjects(cd)) + cache := &fakes.FakeCache{} + cache.IsCachedReturns(false, nil) + cache.FetchDataByDigestReturns(io.NopCloser(strings.NewReader("mockdata")), nil) + cache.PushDataReturns("sha256:8fa155245ea8d3f2ea3add7d090d42dfb0e22799018fded6aae24f0c1a1c3f38", nil) + + ocmClient := NewClient(fakeKubeClient, cache) + + cv := &v1alpha1.ComponentVersion{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-name", + Namespace: "default", + }, + Spec: v1alpha1.ComponentVersionSpec{ + Component: component, + Version: v1alpha1.Version{ + Semver: "v0.0.1", + }, + Repository: v1alpha1.Repository{ + URL: "localhost", + }, + }, + Status: v1alpha1.ComponentVersionStatus{ + ReconciledVersion: "v0.0.1", + ComponentDescriptor: v1alpha1.Reference{ + Name: component, + Version: "v0.0.1", + ComponentDescriptorRef: meta.NamespacedObjectReference{ + Name: "github.com-open-component-model-ocm-demo-index-v0.0.1-12345", + Namespace: "default", + }, + }, + }, + } + + resourceRef := &v1alpha1.ResourceReference{ + ElementMeta: v1alpha1.ElementMeta{ + Name: "remote-controller-demo", + Version: "v0.0.1", + ExtraIdentity: map[string]string{ + "type": "config", + }, + }, + } + + reader, digest, _, err := ocmClient.GetResource(context.Background(), octx, cv, resourceRef) + require.NoError(t, err) + content, err := io.ReadAll(reader) + require.NoError(t, err) + require.Equal(t, "mockdata", string(content)) + require.Equal(t, "sha256:8fa155245ea8d3f2ea3add7d090d42dfb0e22799018fded6aae24f0c1a1c3f38", digest) + + // verify that the cache has been called with the right resource data to cache. + args := cache.PushDataCallingArgumentsOnCall(0) + + require.Equal(t, data2, args.Content) + + require.Equal(t, "sha-17579917197306559277", args.Name, "pushed name did not match constructed name from identity of the resource") + require.Equal(t, resourceRef.Version, args.Version) +}