diff --git a/.github/config/golangci.yaml b/.github/config/golangci.yaml index 8352fbc2a3..62a4222f7a 100644 --- a/.github/config/golangci.yaml +++ b/.github/config/golangci.yaml @@ -173,4 +173,18 @@ issues: - path: ignore/.*\.go linters: - dupword + # Deprecated algorithms and fields for extra identity field defaulting + # TODO: To be removed once v1 + v2 are removed. + - path: "cmds/.*|api/.*" + linters: + - staticcheck + text: "SA1019: jsonv1.Algorithm is deprecated" + - path: "cmds/.*|api/.*" + linters: + - staticcheck + text: "SA1019: jsonv2.Algorithm is deprecated" + - path: "cmds/.*|api/.*" + linters: + - staticcheck + text: "SA1019: legacy.DefaultingOfVersionIntoExtraIdentity is deprecated" diff --git a/.github/config/wordlist.txt b/.github/config/wordlist.txt index d38b0d4469..55c8a10bd4 100644 --- a/.github/config/wordlist.txt +++ b/.github/config/wordlist.txt @@ -308,4 +308,5 @@ xml yaml yitsushi yml -yyyy \ No newline at end of file +yyyy +jsonNormalisation \ No newline at end of file diff --git a/api/ocm/compdesc/norm_test.go b/api/ocm/compdesc/norm_test.go index 8d3991f076..786f35ea77 100644 --- a/api/ocm/compdesc/norm_test.go +++ b/api/ocm/compdesc/norm_test.go @@ -171,7 +171,7 @@ var _ = Describe("Normalization", func() { Expect(err).To(Succeed()) }) - It("hashes first", func() { + It("normalizes v1", func() { n, err := compdesc.Normalize(cd1, compdesc.JsonNormalisationV1) Expect(err).To(Succeed()) Expect(string(n)).To(StringEqualTrimmedWithContext("[{\"component\":[{\"componentReferences\":[]},{\"name\":\"github.com/vasu1124/introspect\"},{\"provider\":\"internal\"},{\"resources\":[[{\"digest\":[{\"hashAlgorithm\":\"SHA-256\"},{\"normalisationAlgorithm\":\"ociArtifactDigest/v1\"},{\"value\":\"6a1c7637a528ab5957ab60edf73b5298a0a03de02a96be0313ee89b22544840c\"}]},{\"extraIdentity\":null},{\"labels\":[[{\"name\":\"label2\"},{\"signing\":true},{\"value\":\"bar\"}]]},{\"name\":\"introspect-image\"},{\"relation\":\"local\"},{\"type\":\"ociImage\"},{\"version\":\"1.0.0\"}],[{\"digest\":[{\"hashAlgorithm\":\"SHA-256\"},{\"normalisationAlgorithm\":\"genericBlobDigest/v1\"},{\"value\":\"d1187ac17793b2f5fa26175c21cabb6ce388871ae989e16ff9a38bd6b32507bf\"}]},{\"extraIdentity\":null},{\"name\":\"introspect-blueprint\"},{\"relation\":\"local\"},{\"type\":\"landscaper.gardener.cloud/blueprint\"},{\"version\":\"1.0.0\"}],[{\"digest\":[{\"hashAlgorithm\":\"SHA-256\"},{\"normalisationAlgorithm\":\"ociArtifactDigest/v1\"},{\"value\":\"6229be2be7e328f74ba595d93b814b590b1aa262a1b85e49cc1492795a9e564c\"}]},{\"extraIdentity\":null},{\"name\":\"introspect-helm\"},{\"relation\":\"external\"},{\"type\":\"helm\"},{\"version\":\"0.1.0\"}]]},{\"version\":\"1.0.0\"}]},{\"meta\":[{\"schemaVersion\":\"v2\"}]}]")) @@ -180,13 +180,22 @@ var _ = Describe("Normalization", func() { Expect(o).To(Equal(n)) }) - It("hashes v2", func() { + It("normalizes v2", func() { n, err := compdesc.Normalize(cd1, compdesc.JsonNormalisationV2) Expect(err).To(Succeed()) Expect(string(n)).To(Equal(`{"component":{"componentReferences":[],"name":"github.com/vasu1124/introspect","provider":{"name":"internal"},"resources":[{"digest":{"hashAlgorithm":"SHA-256","normalisationAlgorithm":"ociArtifactDigest/v1","value":"6a1c7637a528ab5957ab60edf73b5298a0a03de02a96be0313ee89b22544840c"},"labels":[{"name":"label2","signing":true,"value":"bar"}],"name":"introspect-image","relation":"local","type":"ociImage","version":"1.0.0"},{"digest":{"hashAlgorithm":"SHA-256","normalisationAlgorithm":"genericBlobDigest/v1","value":"d1187ac17793b2f5fa26175c21cabb6ce388871ae989e16ff9a38bd6b32507bf"},"name":"introspect-blueprint","relation":"local","type":"landscaper.gardener.cloud/blueprint","version":"1.0.0"},{"digest":{"hashAlgorithm":"SHA-256","normalisationAlgorithm":"ociArtifactDigest/v1","value":"6229be2be7e328f74ba595d93b814b590b1aa262a1b85e49cc1492795a9e564c"},"name":"introspect-helm","relation":"external","type":"helm","version":"0.1.0"}],"sources":[{"name":"introspect","type":"git","version":"1.0.0"}],"version":"1.0.0"}}`)) }) - It("hashes v1 with none access", func() { + It("normalises v3", func() { + n, err := compdesc.Normalize(cd1, compdesc.JsonNormalisationV3) + Expect(err).To(Succeed()) + Expect(string(n)).To(Equal(`{"component":{"componentReferences":[],"name":"github.com/vasu1124/introspect","provider":{"name":"internal"},"resources":[{"digest":{"hashAlgorithm":"SHA-256","normalisationAlgorithm":"ociArtifactDigest/v1","value":"6a1c7637a528ab5957ab60edf73b5298a0a03de02a96be0313ee89b22544840c"},"labels":[{"name":"label2","signing":true,"value":"bar"}],"name":"introspect-image","relation":"local","type":"ociImage","version":"1.0.0"},{"digest":{"hashAlgorithm":"SHA-256","normalisationAlgorithm":"genericBlobDigest/v1","value":"d1187ac17793b2f5fa26175c21cabb6ce388871ae989e16ff9a38bd6b32507bf"},"name":"introspect-blueprint","relation":"local","type":"landscaper.gardener.cloud/blueprint","version":"1.0.0"},{"digest":{"hashAlgorithm":"SHA-256","normalisationAlgorithm":"ociArtifactDigest/v1","value":"6229be2be7e328f74ba595d93b814b590b1aa262a1b85e49cc1492795a9e564c"},"name":"introspect-helm","relation":"external","type":"helm","version":"0.1.0"}],"sources":[{"name":"introspect","type":"git","version":"1.0.0"}],"version":"1.0.0"}}`)) + o, err := compdesc.Normalize(cd1, compdesc.JsonNormalisationV2) + Expect(err).To(Succeed()) + Expect(o).To(Equal(n)) + }) + + It("normalizes v1 with none access", func() { cd1.Resources = append(cd1.Resources, compdesc.Resource{ ResourceMeta: compdesc.ResourceMeta{ ElementMeta: compdesc.ElementMeta{ @@ -208,7 +217,7 @@ var _ = Describe("Normalization", func() { Expect(string(n)).To(StringEqualWithContext(`[{"component":[{"componentReferences":[]},{"name":"github.com/vasu1124/introspect"},{"provider":"internal"},{"resources":[[{"digest":[{"hashAlgorithm":"SHA-256"},{"normalisationAlgorithm":"ociArtifactDigest/v1"},{"value":"6a1c7637a528ab5957ab60edf73b5298a0a03de02a96be0313ee89b22544840c"}]},{"extraIdentity":null},{"labels":[[{"name":"label2"},{"signing":true},{"value":"bar"}]]},{"name":"introspect-image"},{"relation":"local"},{"type":"ociImage"},{"version":"1.0.0"}],[{"digest":[{"hashAlgorithm":"SHA-256"},{"normalisationAlgorithm":"genericBlobDigest/v1"},{"value":"d1187ac17793b2f5fa26175c21cabb6ce388871ae989e16ff9a38bd6b32507bf"}]},{"extraIdentity":null},{"name":"introspect-blueprint"},{"relation":"local"},{"type":"landscaper.gardener.cloud/blueprint"},{"version":"1.0.0"}],[{"digest":[{"hashAlgorithm":"SHA-256"},{"normalisationAlgorithm":"ociArtifactDigest/v1"},{"value":"6229be2be7e328f74ba595d93b814b590b1aa262a1b85e49cc1492795a9e564c"}]},{"extraIdentity":null},{"name":"introspect-helm"},{"relation":"external"},{"type":"helm"},{"version":"0.1.0"}],[{"extraIdentity":null},{"name":"none"},{"relation":"local"},{"type":"plainText"},{"version":"v1"}]]},{"version":"1.0.0"}]},{"meta":[{"schemaVersion":"v2"}]}]`)) }) - It("hashes v2 with none access", func() { + It("normalizes v2 with none access", func() { cd1.Resources = append(cd1.Resources, compdesc.Resource{ ResourceMeta: compdesc.ResourceMeta{ ElementMeta: compdesc.ElementMeta{ @@ -230,7 +239,7 @@ var _ = Describe("Normalization", func() { Expect(string(n)).To(Equal(`{"component":{"componentReferences":[],"name":"github.com/vasu1124/introspect","provider":{"name":"internal"},"resources":[{"digest":{"hashAlgorithm":"SHA-256","normalisationAlgorithm":"ociArtifactDigest/v1","value":"6a1c7637a528ab5957ab60edf73b5298a0a03de02a96be0313ee89b22544840c"},"labels":[{"name":"label2","signing":true,"value":"bar"}],"name":"introspect-image","relation":"local","type":"ociImage","version":"1.0.0"},{"digest":{"hashAlgorithm":"SHA-256","normalisationAlgorithm":"genericBlobDigest/v1","value":"d1187ac17793b2f5fa26175c21cabb6ce388871ae989e16ff9a38bd6b32507bf"},"name":"introspect-blueprint","relation":"local","type":"landscaper.gardener.cloud/blueprint","version":"1.0.0"},{"digest":{"hashAlgorithm":"SHA-256","normalisationAlgorithm":"ociArtifactDigest/v1","value":"6229be2be7e328f74ba595d93b814b590b1aa262a1b85e49cc1492795a9e564c"},"name":"introspect-helm","relation":"external","type":"helm","version":"0.1.0"},{"name":"none","relation":"local","type":"plainText","version":"v1"}],"sources":[{"name":"introspect","type":"git","version":"1.0.0"}],"version":"1.0.0"}}`)) }) - It("hashes v2 with complex provider", func() { + It("normalizes v2 with complex provider", func() { cd := cd1.Copy() cd.References = nil cd.Resources = nil @@ -248,7 +257,7 @@ var _ = Describe("Normalization", func() { Expect(string(n)).To(Equal(`{"component":{"componentReferences":[],"labels":[{"name":"non-volatile","signing":true,"value":"comp-value2"}],"name":"github.com/vasu1124/introspect","provider":{"labels":[{"name":"non-volatile","signing":true,"value":"prov-value2"}],"name":"internal"},"resources":[],"sources":[],"version":"1.0.0"}}`)) }) - It("hashes v1 with complex provider for CD/v2", func() { + It("normalizes v1 with complex provider for CD/v2", func() { cd := cd1.Copy() cd.References = nil cd.Resources = nil @@ -266,7 +275,7 @@ var _ = Describe("Normalization", func() { Expect(string(n)).To(StringEqualWithContext(`[{"component":[{"componentReferences":[]},{"labels":[[{"name":"non-volatile"},{"signing":true},{"value":"comp-value2"}]]},{"name":"github.com/vasu1124/introspect"},{"provider":[{"labels":[[{"name":"non-volatile"},{"signing":true},{"value":"prov-value2"}]]},{"name":"internal"}]},{"resources":[]},{"version":"1.0.0"}]},{"meta":[{"schemaVersion":"v2"}]}]`)) }) - It("hashes v1 with complex provider for CD/v3", func() { + It("normalizes v1 with complex provider for CD/v3", func() { cd := cd1.Copy() cd.Metadata.ConfiguredVersion = v3alpha1.SchemaVersion cd.References = nil @@ -284,4 +293,51 @@ var _ = Describe("Normalization", func() { Expect(string(n)).To(StringEqualWithContext(`[{"apiVersion":"ocm.software/v3alpha1"},{"kind":"ComponentVersion"},{"metadata":[{"labels":[[{"name":"non-volatile"},{"signing":true},{"value":"comp-value2"}]]},{"name":"github.com/vasu1124/introspect"},{"provider":[{"labels":[[{"name":"volatile"},{"value":"prov-value1"}],[{"name":"non-volatile"},{"signing":true},{"value":"prov-value2"}]]},{"name":"internal"}]},{"version":"1.0.0"}]},{"spec":[]}]`)) }) + + Context("normalization and legacy extra identity defaulting", func() { + var cd *compdesc.ComponentDescriptor + BeforeEach(func() { + cd = Must(compdesc.Decode([]byte(` + component: + version: 1.0.0 + componentReferences: [] + name: ocm.software/duplicate-resource/test + provider: internal + repositoryContexts: [] + resources: + - name: image + relation: local + type: ociImage + version: 1.0.0 + access: + imageReference: ghcr.io/bla:1.0.0 + type: ociRegistry + - name: image + relation: local + type: ociImage + version: 2.0.0 + access: + imageReference: ghcr.io/bla:2.0.0 + type: ociRegistry + sources: [] + meta: + schemaVersion: v2 +`))) + }) + It("normalizes v1 with extra identity defaulting", func() { + n := Must(compdesc.Normalize(cd, compdesc.JsonNormalisationV1)) + Expect(string(n)).To(StringEqualTrimmedWithContext("[{\"component\":[{\"componentReferences\":[]},{\"name\":\"ocm.software/duplicate-resource/test\"},{\"provider\":\"internal\"},{\"resources\":[[{\"extraIdentity\":[{\"version\":\"1.0.0\"}]},{\"name\":\"image\"},{\"relation\":\"local\"},{\"type\":\"ociImage\"},{\"version\":\"1.0.0\"}],[{\"extraIdentity\":null},{\"name\":\"image\"},{\"relation\":\"local\"},{\"type\":\"ociImage\"},{\"version\":\"2.0.0\"}]]},{\"version\":\"1.0.0\"}]},{\"meta\":[{\"schemaVersion\":\"v2\"}]}]")) + Expect(string(n)).To(ContainSubstring("\"extraIdentity\":[{\"version\":\"1.0.0\"}]"), "extra identity should have been defaulted, see api/ocm/compdesc/normalizations/legacy/DefaultingOfVersionIntoExtraIdentity") + }) + It("normalizes v2 with extra identity defaulting", func() { + n := Must(compdesc.Normalize(cd, compdesc.JsonNormalisationV2)) + Expect(string(n)).To(StringEqualTrimmedWithContext("{\"component\":{\"componentReferences\":[],\"name\":\"ocm.software/duplicate-resource/test\",\"provider\":{\"name\":\"internal\"},\"resources\":[{\"extraIdentity\":{\"version\":\"1.0.0\"},\"name\":\"image\",\"relation\":\"local\",\"type\":\"ociImage\",\"version\":\"1.0.0\"},{\"name\":\"image\",\"relation\":\"local\",\"type\":\"ociImage\",\"version\":\"2.0.0\"}],\"sources\":[],\"version\":\"1.0.0\"}}")) + Expect(string(n)).To(ContainSubstring("{\"extraIdentity\":{\"version\":\"1.0.0\"}"), "extra identity should have been defaulted, see api/ocm/compdesc/normalizations/legacy/DefaultingOfVersionIntoExtraIdentity") + }) + It("normalizes v3 without extra identity defaulting", func() { + n := Must(compdesc.Normalize(cd, compdesc.JsonNormalisationV3)) + Expect(string(n)).To(StringEqualTrimmedWithContext("{\"component\":{\"componentReferences\":[],\"name\":\"ocm.software/duplicate-resource/test\",\"provider\":{\"name\":\"internal\"},\"resources\":[{\"name\":\"image\",\"relation\":\"local\",\"type\":\"ociImage\",\"version\":\"1.0.0\"},{\"name\":\"image\",\"relation\":\"local\",\"type\":\"ociImage\",\"version\":\"2.0.0\"}],\"sources\":[],\"version\":\"1.0.0\"}}")) + Expect(string(n)).ToNot(ContainSubstring("{\"extraIdentity\":{\"version\":\"1.0.0\"}"), "extra identity should not have been defaulted") + }) + }) }) diff --git a/api/ocm/compdesc/normalization.go b/api/ocm/compdesc/normalization.go index 5084f1ca89..6de62c0a0f 100644 --- a/api/ocm/compdesc/normalization.go +++ b/api/ocm/compdesc/normalization.go @@ -13,6 +13,7 @@ type NormalisationAlgorithm = string const ( JsonNormalisationV1 NormalisationAlgorithm = "jsonNormalisation/v1" JsonNormalisationV2 NormalisationAlgorithm = "jsonNormalisation/v2" + JsonNormalisationV3 NormalisationAlgorithm = "jsonNormalisation/v3" ) type Normalization interface { diff --git a/api/ocm/compdesc/normalizations/init.go b/api/ocm/compdesc/normalizations/init.go index 96dab531de..6b4eeefa3e 100644 --- a/api/ocm/compdesc/normalizations/init.go +++ b/api/ocm/compdesc/normalizations/init.go @@ -3,4 +3,5 @@ package normalizations import ( _ "ocm.software/ocm/api/ocm/compdesc/normalizations/jsonv1" _ "ocm.software/ocm/api/ocm/compdesc/normalizations/jsonv2" + _ "ocm.software/ocm/api/ocm/compdesc/normalizations/jsonv3" ) diff --git a/api/ocm/compdesc/normalizations/jsonv1/norm.go b/api/ocm/compdesc/normalizations/jsonv1/norm.go index 5a6f9bf141..ae24494fa2 100644 --- a/api/ocm/compdesc/normalizations/jsonv1/norm.go +++ b/api/ocm/compdesc/normalizations/jsonv1/norm.go @@ -8,9 +8,11 @@ import ( "github.com/mandelsoft/goutils/errors" "ocm.software/ocm/api/ocm/compdesc" + "ocm.software/ocm/api/ocm/compdesc/normalizations/legacy" "ocm.software/ocm/api/utils/errkind" ) +// Deprecated: use compdesc.JsonNormalisationV3 instead const Algorithm = compdesc.JsonNormalisationV1 func init() { @@ -20,11 +22,10 @@ func init() { type normalization struct{} func (m normalization) Normalize(cd *compdesc.ComponentDescriptor) ([]byte, error) { + legacy.DefaultingOfVersionIntoExtraIdentity(cd) cv := compdesc.DefaultSchemes[cd.SchemaVersion()] if cv == nil { - if cv == nil { - return nil, errors.ErrNotSupported(errkind.KIND_SCHEMAVERSION, cd.SchemaVersion()) - } + return nil, errors.ErrNotSupported(errkind.KIND_SCHEMAVERSION, cd.SchemaVersion()) } v, err := cv.ConvertFrom(cd) if err != nil { diff --git a/api/ocm/compdesc/normalizations/jsonv2/norm.go b/api/ocm/compdesc/normalizations/jsonv2/norm.go index 1fcb3a98e8..9fb7b3f284 100644 --- a/api/ocm/compdesc/normalizations/jsonv2/norm.go +++ b/api/ocm/compdesc/normalizations/jsonv2/norm.go @@ -10,11 +10,13 @@ package jsonv2 import ( "ocm.software/ocm/api/ocm/compdesc" + "ocm.software/ocm/api/ocm/compdesc/normalizations/legacy" "ocm.software/ocm/api/ocm/compdesc/normalizations/rules" "ocm.software/ocm/api/tech/signing" "ocm.software/ocm/api/tech/signing/norm/jcs" ) +// Deprecated: use compdesc.JsonNormalisationV3 instead const Algorithm = compdesc.JsonNormalisationV2 func init() { @@ -24,6 +26,7 @@ func init() { type normalization struct{} func (m normalization) Normalize(cd *compdesc.ComponentDescriptor) ([]byte, error) { + legacy.DefaultingOfVersionIntoExtraIdentity(cd) data, err := signing.Normalize(jcs.Type, cd, CDExcludes) return data, err } diff --git a/api/ocm/compdesc/normalizations/jsonv3/norm.go b/api/ocm/compdesc/normalizations/jsonv3/norm.go new file mode 100644 index 0000000000..f8092920b0 --- /dev/null +++ b/api/ocm/compdesc/normalizations/jsonv3/norm.go @@ -0,0 +1,31 @@ +// Package jsonv3 provides a normalization which is completely based on the +// abstract (internal) version of the component descriptor and is therefore +// agnostic of the final serialization format. Signatures using this algorithm +// can be transferred among different schema versions, as long as is able to +// handle the complete information using for the normalization. +// jsonv2 is the predecessor of this version but had internal defaulting logic +// that is no longer included as part of this normalization. Thus v3 should be preferred over v2. +// Note that between v2 and v3 differences can occur mainly if the "extra identity" field is not unique, +// in which case the v2 normalization opinionated on how to differentiate these items. This no longer +// happens in v3, meaning the component descriptor is normalized as is. +package jsonv3 + +import ( + "ocm.software/ocm/api/ocm/compdesc" + "ocm.software/ocm/api/ocm/compdesc/normalizations/jsonv2" + "ocm.software/ocm/api/tech/signing" + "ocm.software/ocm/api/tech/signing/norm/jcs" +) + +const Algorithm = compdesc.JsonNormalisationV3 + +func init() { + compdesc.Normalizations.Register(Algorithm, normalization{}) +} + +type normalization struct{} + +func (m normalization) Normalize(cd *compdesc.ComponentDescriptor) ([]byte, error) { + data, err := signing.Normalize(jcs.Type, cd, jsonv2.CDExcludes) + return data, err +} diff --git a/api/ocm/compdesc/normalizations/legacy/legacy.go b/api/ocm/compdesc/normalizations/legacy/legacy.go new file mode 100644 index 0000000000..e05c982035 --- /dev/null +++ b/api/ocm/compdesc/normalizations/legacy/legacy.go @@ -0,0 +1,57 @@ +package legacy + +import ( + "fmt" + + "ocm.software/ocm/api/ocm/compdesc" + "ocm.software/ocm/api/ocm/selectors/accessors" + "ocm.software/ocm/api/utils/logging" +) + +var ( + REALM = logging.DefineSubRealm("component descriptor legacy normalization defaulting", "compdesc", "normalizations", "legacy") + Logger = logging.DynamicLogger(REALM) +) + +// DefaultingOfVersionIntoExtraIdentity normalizes the extra identity of the resources. +// It sets the version of the resource, reference or source as extra identity field if the combination of name+extra identity +// is the same for multiple items. However, the last item in the list will not be updated as it is unique wihout this. +// +// TODO: To be removed once v1 + v2 are removed. +// +// Deprecated: This is a legacy normalization and should only be used as part of JsonNormalisationV1 and JsonNormalisationV2 +// for backwards compatibility of normalization (for example used for signatures). It was needed because the original +// defaulting was made part of the normalization by accident and is now no longer included by default due to +// https://github.com/open-component-model/ocm/pull/1026 +func DefaultingOfVersionIntoExtraIdentity(cd *compdesc.ComponentDescriptor) { + resources := make([]accessors.ElementMeta, len(cd.Resources)) + for i := range cd.Resources { + resources[i] = &cd.Resources[i] + } + defaultingOfVersionIntoExtraIdentity(resources) +} + +func defaultingOfVersionIntoExtraIdentity(meta []accessors.ElementMeta) { + for i := range meta { + for j := range meta { + // don't match with itself and only match with the same name + if meta[j].GetName() != meta[i].GetName() || i == j { + continue + } + + eid := meta[i].GetExtraIdentity() + // if the extra identity is not the same, then there is not a clash + if !meta[j].GetExtraIdentity().Equals(eid) { + continue + } + + eid.Set(compdesc.SystemIdentityVersion, meta[i].GetVersion()) + meta[i].GetMeta().SetExtraIdentity(eid) + + Logger.Warn(fmt.Sprintf("resource identity duplication was normalized for backwards compatibility, "+ + "to avoid this either specify a unique extra identity per item or switch to %s", compdesc.JsonNormalisationV3), + "name", meta[i].GetName(), "index", i, "extra identity", meta[i].GetExtraIdentity()) + break + } + } +} diff --git a/api/ocm/selectors/accessors/accessors.go b/api/ocm/selectors/accessors/accessors.go index fa8b776487..9fa3c8e00a 100644 --- a/api/ocm/selectors/accessors/accessors.go +++ b/api/ocm/selectors/accessors/accessors.go @@ -27,6 +27,7 @@ type ElementMeta interface { GetMeta() ElementMeta // ElementMeta is again a Meta provider SetLabels(labels []v1.Label) + SetExtraIdentity(identity v1.Identity) } // ElementMetaProvider just provides access to element meta data diff --git a/cmds/ocm/commands/ocmcmds/common/options/hashoption/option.go b/cmds/ocm/commands/ocmcmds/common/options/hashoption/option.go index 4eb900f449..04a755e25e 100644 --- a/cmds/ocm/commands/ocmcmds/common/options/hashoption/option.go +++ b/cmds/ocm/commands/ocmcmds/common/options/hashoption/option.go @@ -7,6 +7,8 @@ import ( clictx "ocm.software/ocm/api/cli" "ocm.software/ocm/api/ocm/compdesc" "ocm.software/ocm/api/ocm/compdesc/normalizations/jsonv1" + "ocm.software/ocm/api/ocm/compdesc/normalizations/jsonv2" + "ocm.software/ocm/api/ocm/compdesc/normalizations/jsonv3" "ocm.software/ocm/api/ocm/extensions/attrs/signingattr" ocmsign "ocm.software/ocm/api/ocm/tools/signing" "ocm.software/ocm/api/tech/signing" @@ -34,13 +36,13 @@ type Option struct { } func (o *Option) AddFlags(fs *pflag.FlagSet) { - fs.StringVarP(&o.NormAlgorithm, "normalization", "N", jsonv1.Algorithm, "normalization algorithm") + fs.StringVarP(&o.NormAlgorithm, "normalization", "N", jsonv3.Algorithm, "normalization algorithm") fs.StringVarP(&o.hashAlgorithm, "hash", "H", sha256.Algorithm, "hash algorithm") } func (o *Option) Configure(ctx clictx.Context) error { if o.NormAlgorithm == "" { - o.NormAlgorithm = jsonv1.Algorithm + o.NormAlgorithm = jsonv3.Algorithm } if o.hashAlgorithm == "" { o.hashAlgorithm = sha256.Algorithm @@ -59,7 +61,18 @@ func (o *Option) Configure(ctx clictx.Context) error { func (o *Option) Usage() string { s := ` The following normalization modes are supported with option --normalization: -` + listformat.FormatList(jsonv1.Algorithm, compdesc.Normalizations.Names()...) +` + listformat.FormatList(jsonv3.Algorithm, compdesc.Normalizations.Names()...) + + s += ` + +Note that the normalization algorithm is important to be equivalent when used for signing and verification, otherwise +the verification can fail. Please always migrate to the latest normalization algorithm whenever possible. +New signature algorithms can be used as soon as they are available in the component version after signing it. + +The algorithms ` + jsonv1.Algorithm + ` and ` + jsonv2.Algorithm + ` are deprecated and should not be used anymore. +Please switch to ` + jsonv3.Algorithm + ` as soon as possible. + +` s += ` diff --git a/cmds/ocm/commands/ocmcmds/common/options/signoption/option.go b/cmds/ocm/commands/ocmcmds/common/options/signoption/option.go index 14723d097a..a0ac7fdb22 100644 --- a/cmds/ocm/commands/ocmcmds/common/options/signoption/option.go +++ b/cmds/ocm/commands/ocmcmds/common/options/signoption/option.go @@ -9,7 +9,7 @@ import ( clictx "ocm.software/ocm/api/cli" "ocm.software/ocm/api/ocm/compdesc" - "ocm.software/ocm/api/ocm/compdesc/normalizations/jsonv1" + "ocm.software/ocm/api/ocm/compdesc/normalizations/jsonv3" "ocm.software/ocm/api/ocm/extensions/attrs/signingattr" ocmsign "ocm.software/ocm/api/ocm/tools/signing" "ocm.software/ocm/api/tech/signing" @@ -151,7 +151,7 @@ The following signing types are supported with option --algorithm: s += ` The following normalization modes are supported with option --normalization: -` + listformat.FormatList(jsonv1.Algorithm, compdesc.Normalizations.Names()...) +` + listformat.FormatList(jsonv3.Algorithm, compdesc.Normalizations.Names()...) s += ` diff --git a/docs/reference/ocm_hash_componentversions.md b/docs/reference/ocm_hash_componentversions.md index 1e49ba07f4..4c5e46bdca 100644 --- a/docs/reference/ocm_hash_componentversions.md +++ b/docs/reference/ocm_hash_componentversions.md @@ -21,7 +21,7 @@ componentversions, componentversion, cv, components, component, comps, comp, c -h, --help help for componentversions --latest restrict component versions to latest --lookup stringArray repository name or spec for closure lookup fallback - -N, --normalization string normalization algorithm (default "jsonNormalisation/v1") + -N, --normalization string normalization algorithm (default "jsonNormalisation/v3") -O, --outfile string Output file for normalized component descriptor (default "-") -o, --output string output mode (JSON, json, norm, wide, yaml) -r, --recursive follow component reference nesting @@ -63,8 +63,18 @@ references. The following normalization modes are supported with option --normalization: - - jsonNormalisation/v1 (default) + - jsonNormalisation/v1 - jsonNormalisation/v2 + - jsonNormalisation/v3 (default) + + +Note that the normalization algorithm is important to be equivalent when used for signing and verification, otherwise +the verification can fail. Please always migrate to the latest normalization algorithm whenever possible. +New signature algorithms can be used as soon as they are available in the component version after signing it. + +The algorithms jsonNormalisation/v1 and jsonNormalisation/v2 are deprecated and should not be used anymore. +Please switch to jsonNormalisation/v3 as soon as possible. + The following hash modes are supported with option --hash: diff --git a/docs/reference/ocm_logging.md b/docs/reference/ocm_logging.md index 9a1c45800b..3e579d5488 100644 --- a/docs/reference/ocm_logging.md +++ b/docs/reference/ocm_logging.md @@ -21,6 +21,7 @@ The following *realms* are used by the command line tool: - ocm/accessmethod/wget: access method for wget - ocm/blobaccess/wget: blob access for wget - ocm/compdesc: component descriptor handling + - ocm/compdesc/normalizations/legacy: component descriptor legacy normalization defaulting - ocm/config: configuration management - ocm/context: context lifecycle - ocm/credentials: Credentials diff --git a/docs/reference/ocm_sign_componentversions.md b/docs/reference/ocm_sign_componentversions.md index b1d3f582bf..85f1e4d340 100644 --- a/docs/reference/ocm_sign_componentversions.md +++ b/docs/reference/ocm_sign_componentversions.md @@ -25,7 +25,7 @@ componentversions, componentversion, cv, components, component, comps, comp, c --keyless use keyless signing --latest restrict component versions to latest --lookup stringArray repository name or spec for closure lookup fallback - -N, --normalization string normalization algorithm (default "jsonNormalisation/v1") + -N, --normalization string normalization algorithm (default "jsonNormalisation/v3") -K, --private-key stringArray private key setting -k, --public-key stringArray public key setting -R, --recursive recursively sign component versions @@ -126,6 +126,7 @@ The following signing types are supported with option --algorithm: The following normalization modes are supported with option --normalization: - jsonNormalisation/v1 (default) - jsonNormalisation/v2 + - jsonNormalisation/v3 The following hash modes are supported with option --hash: