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
: