From 6c807ea272dd1e815c4d2692dade6a1d8c2e20bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 May 2025 18:21:18 +0000 Subject: [PATCH] build(deps): bump github.com/coreos/butane from 0.23.0 to 0.24.0 Bumps [github.com/coreos/butane](https://github.com/coreos/butane) from 0.23.0 to 0.24.0. - [Release notes](https://github.com/coreos/butane/releases) - [Changelog](https://github.com/coreos/butane/blob/main/docs/release-notes.md) - [Commits](https://github.com/coreos/butane/compare/v0.23.0...v0.24.0) --- updated-dependencies: - dependency-name: github.com/coreos/butane dependency-version: 0.24.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 +- .../coreos/butane/base/v0_2/translate.go | 9 + .../coreos/butane/base/v0_2/util.go | 33 ++ .../coreos/butane/base/v0_2/validate.go | 13 + .../coreos/butane/base/v0_3/translate.go | 9 + .../coreos/butane/base/v0_3/util.go | 33 ++ .../coreos/butane/base/v0_3/validate.go | 13 + .../coreos/butane/base/v0_4/translate.go | 9 + .../coreos/butane/base/v0_4/util.go | 33 ++ .../coreos/butane/base/v0_4/validate.go | 13 + .../coreos/butane/base/v0_5/translate.go | 9 + .../coreos/butane/base/v0_5/util.go | 33 ++ .../coreos/butane/base/v0_5/validate.go | 14 + .../coreos/butane/base/v0_6/translate.go | 9 + .../coreos/butane/base/v0_6/util.go | 33 ++ .../coreos/butane/base/v0_6/validate.go | 13 + .../coreos/butane/base/v0_7_exp/translate.go | 10 + .../coreos/butane/base/v0_7_exp/util.go | 33 ++ .../coreos/butane/base/v0_7_exp/validate.go | 14 + .../coreos/butane/config/common/errors.go | 35 +- .../github.com/coreos/butane/config/config.go | 6 +- .../butane/config/fcos/v1_7_exp/validate.go | 21 ++ .../config/openshift/v4_19/result/schema.go | 48 +++ .../butane/config/openshift/v4_19/schema.go | 39 +++ .../config/openshift/v4_19/translate.go | 303 ++++++++++++++++++ .../{v4_19_exp => v4_19}/validate.go | 27 +- .../{v4_19_exp => v4_20_exp}/result/schema.go | 0 .../{v4_19_exp => v4_20_exp}/schema.go | 2 +- .../{v4_19_exp => v4_20_exp}/translate.go | 20 +- .../config/openshift/v4_20_exp/validate.go | 68 ++++ vendor/modules.txt | 8 +- 32 files changed, 881 insertions(+), 35 deletions(-) create mode 100644 vendor/github.com/coreos/butane/config/openshift/v4_19/result/schema.go create mode 100644 vendor/github.com/coreos/butane/config/openshift/v4_19/schema.go create mode 100644 vendor/github.com/coreos/butane/config/openshift/v4_19/translate.go rename vendor/github.com/coreos/butane/config/openshift/{v4_19_exp => v4_19}/validate.go (54%) rename vendor/github.com/coreos/butane/config/openshift/{v4_19_exp => v4_20_exp}/result/schema.go (100%) rename vendor/github.com/coreos/butane/config/openshift/{v4_19_exp => v4_20_exp}/schema.go (98%) rename vendor/github.com/coreos/butane/config/openshift/{v4_19_exp => v4_20_exp}/translate.go (95%) create mode 100644 vendor/github.com/coreos/butane/config/openshift/v4_20_exp/validate.go diff --git a/go.mod b/go.mod index 4c1b74a7e6..07289c02c0 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/aliyun/alibaba-cloud-sdk-go v1.63.101 github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible github.com/aws/aws-sdk-go v1.55.6 - github.com/coreos/butane v0.23.0 + github.com/coreos/butane v0.24.0 github.com/coreos/go-semver v0.3.1 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e github.com/coreos/go-systemd/v22 v22.5.0 diff --git a/go.sum b/go.sum index 34b54d3728..226e14e407 100644 --- a/go.sum +++ b/go.sum @@ -63,8 +63,8 @@ github.com/containers/image/v5 v5.34.2 h1:3r1etun4uJYq5197tcymUcI1h6+zyzKS9PtRtB github.com/containers/image/v5 v5.34.2/go.mod h1:MG++slvQSZVq5ejAcLdu4APGsKGMb0YHHnAo7X28fdE= github.com/containers/storage v1.57.2 h1:2roCtTyE9pzIaBDHibK72DTnYkPmwWaq5uXxZdaWK4U= github.com/containers/storage v1.57.2/go.mod h1:i/Hb4lu7YgFr9G0K6BMjqW0BLJO1sFsnWQwj2UoWCUM= -github.com/coreos/butane v0.23.0 h1:C/005CtsUGilgoPDrODUkPbCbZ8OJDuS3c1ANUSZXro= -github.com/coreos/butane v0.23.0/go.mod h1:Oeoy3s0qNcJxyMa8kUYpxpJfnNPpAgxEbihwPtQNE1g= +github.com/coreos/butane v0.24.0 h1:sput//CnGz1ZUNT3TaSpbgjAjlefGC+/Ikiiwl5wO9Q= +github.com/coreos/butane v0.24.0/go.mod h1:mLu58/AgW6lC116Rf/9N5b+ixj/zdhRtABBZjADHWFo= github.com/coreos/go-json v0.0.0-20231102161613-e49c8866685a h1:QimUZQ6Au5wFKKkPMmdoXen+CNR66lXt/76AQLBltS0= github.com/coreos/go-json v0.0.0-20231102161613-e49c8866685a/go.mod h1:rcFZM3uxVvdyNmsAV2jopgPD1cs5SPWJWU5dOz2LUnw= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= diff --git a/vendor/github.com/coreos/butane/base/v0_2/translate.go b/vendor/github.com/coreos/butane/base/v0_2/translate.go index 0433092f76..9dacb85da8 100644 --- a/vendor/github.com/coreos/butane/base/v0_2/translate.go +++ b/vendor/github.com/coreos/butane/base/v0_2/translate.go @@ -123,6 +123,15 @@ func translateResource(from Resource, options common.TranslateOptions) (to types r.AddOnError(c, err) return } + // Validating the contents of the local file from here since there is no way to + // get both the filename and filedirectory in the Validate context + if strings.HasPrefix(c.String(), "$.ignition.config") { + rp, err := ValidateIgnitionConfig(c, contents) + r.Merge(rp) + if err != nil { + return + } + } src, compression, err := baseutil.MakeDataURL(contents, to.Compression, !options.NoResourceAutoCompression) if err != nil { r.AddOnError(c, err) diff --git a/vendor/github.com/coreos/butane/base/v0_2/util.go b/vendor/github.com/coreos/butane/base/v0_2/util.go index 4478255305..7612dbc549 100644 --- a/vendor/github.com/coreos/butane/base/v0_2/util.go +++ b/vendor/github.com/coreos/butane/base/v0_2/util.go @@ -15,7 +15,14 @@ package v0_2 import ( + common "github.com/coreos/butane/config/common" + "github.com/coreos/ignition/v2/config/shared/errors" + "github.com/coreos/ignition/v2/config/util" "github.com/coreos/ignition/v2/config/v3_1/types" + "github.com/coreos/ignition/v2/config/validate" + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" + vvalidate "github.com/coreos/vcontext/validate" ) type nodeTracker struct { @@ -123,3 +130,29 @@ func (t *nodeTracker) AddLink(l types.Link) (int, *types.Link) { t.linkMap[l.Path] = i return i, &(*t.links)[i] } + +func ValidateIgnitionConfig(c path.ContextPath, rawConfig []byte) (report.Report, error) { + r := report.Report{} + var config types.Config + rp, err := util.HandleParseErrors(rawConfig, &config) + if err != nil { + return rp, err + } + vrep := vvalidate.Validate(config.Ignition, "json") + skipValidate := false + if vrep.IsFatal() { + for _, e := range vrep.Entries { + // warn user with ErrUnknownVersion when version is unkown and skip the validation. + if e.Message == errors.ErrUnknownVersion.Error() { + skipValidate = true + r.AddOnWarn(c.Append("version"), common.ErrUnkownIgnitionVersion) + break + } + } + } + if !skipValidate { + report := validate.ValidateWithContext(config, rawConfig) + r.Merge(report) + } + return r, nil +} diff --git a/vendor/github.com/coreos/butane/base/v0_2/validate.go b/vendor/github.com/coreos/butane/base/v0_2/validate.go index 01de4a8e10..8822315e0b 100644 --- a/vendor/github.com/coreos/butane/base/v0_2/validate.go +++ b/vendor/github.com/coreos/butane/base/v0_2/validate.go @@ -17,6 +17,7 @@ package v0_2 import ( baseutil "github.com/coreos/butane/base/util" "github.com/coreos/butane/config/common" + "strings" "github.com/coreos/ignition/v2/config/util" "github.com/coreos/vcontext/path" @@ -26,6 +27,7 @@ import ( func (rs Resource) Validate(c path.ContextPath) (r report.Report) { var field string sources := 0 + // Local files are validated in the translateResource function if rs.Local != nil { sources++ field = "local" @@ -40,6 +42,17 @@ func (rs Resource) Validate(c path.ContextPath) (r report.Report) { } if sources > 1 { r.AddOnError(c.Append(field), common.ErrTooManyResourceSources) + return + } + if strings.HasPrefix(c.String(), "$.ignition.config") { + if field == "inline" { + rp, err := ValidateIgnitionConfig(c, []byte(*rs.Inline)) + r.Merge(rp) + if err != nil { + r.AddOnError(c.Append(field), err) + return + } + } } return } diff --git a/vendor/github.com/coreos/butane/base/v0_3/translate.go b/vendor/github.com/coreos/butane/base/v0_3/translate.go index 66469a6a9c..7bd03c2f7c 100644 --- a/vendor/github.com/coreos/butane/base/v0_3/translate.go +++ b/vendor/github.com/coreos/butane/base/v0_3/translate.go @@ -130,6 +130,15 @@ func translateResource(from Resource, options common.TranslateOptions) (to types r.AddOnError(c, err) return } + // Validating the contents of the local file from here since there is no way to + // get both the filename and filedirectory in the Validate context + if strings.HasPrefix(c.String(), "$.ignition.config") { + rp, err := ValidateIgnitionConfig(c, contents) + r.Merge(rp) + if err != nil { + return + } + } src, compression, err := baseutil.MakeDataURL(contents, to.Compression, !options.NoResourceAutoCompression) if err != nil { r.AddOnError(c, err) diff --git a/vendor/github.com/coreos/butane/base/v0_3/util.go b/vendor/github.com/coreos/butane/base/v0_3/util.go index 5d11df31d5..fc693edafe 100644 --- a/vendor/github.com/coreos/butane/base/v0_3/util.go +++ b/vendor/github.com/coreos/butane/base/v0_3/util.go @@ -15,7 +15,14 @@ package v0_3 import ( + common "github.com/coreos/butane/config/common" + "github.com/coreos/ignition/v2/config/shared/errors" + "github.com/coreos/ignition/v2/config/util" "github.com/coreos/ignition/v2/config/v3_2/types" + "github.com/coreos/ignition/v2/config/validate" + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" + vvalidate "github.com/coreos/vcontext/validate" ) type nodeTracker struct { @@ -123,3 +130,29 @@ func (t *nodeTracker) AddLink(l types.Link) (int, *types.Link) { t.linkMap[l.Path] = i return i, &(*t.links)[i] } + +func ValidateIgnitionConfig(c path.ContextPath, rawConfig []byte) (report.Report, error) { + r := report.Report{} + var config types.Config + rp, err := util.HandleParseErrors(rawConfig, &config) + if err != nil { + return rp, err + } + vrep := vvalidate.Validate(config.Ignition, "json") + skipValidate := false + if vrep.IsFatal() { + for _, e := range vrep.Entries { + // warn user with ErrUnknownVersion when version is unkown and skip the validation. + if e.Message == errors.ErrUnknownVersion.Error() { + skipValidate = true + r.AddOnWarn(c.Append("version"), common.ErrUnkownIgnitionVersion) + break + } + } + } + if !skipValidate { + report := validate.ValidateWithContext(config, rawConfig) + r.Merge(report) + } + return r, nil +} diff --git a/vendor/github.com/coreos/butane/base/v0_3/validate.go b/vendor/github.com/coreos/butane/base/v0_3/validate.go index 9a00c354bf..5a761c58fd 100644 --- a/vendor/github.com/coreos/butane/base/v0_3/validate.go +++ b/vendor/github.com/coreos/butane/base/v0_3/validate.go @@ -17,6 +17,7 @@ package v0_3 import ( baseutil "github.com/coreos/butane/base/util" "github.com/coreos/butane/config/common" + "strings" "github.com/coreos/ignition/v2/config/util" "github.com/coreos/vcontext/path" @@ -26,6 +27,7 @@ import ( func (rs Resource) Validate(c path.ContextPath) (r report.Report) { var field string sources := 0 + // Local files are validated in the translateResource function if rs.Local != nil { sources++ field = "local" @@ -40,6 +42,17 @@ func (rs Resource) Validate(c path.ContextPath) (r report.Report) { } if sources > 1 { r.AddOnError(c.Append(field), common.ErrTooManyResourceSources) + return + } + if strings.HasPrefix(c.String(), "$.ignition.config") { + if field == "inline" { + rp, err := ValidateIgnitionConfig(c, []byte(*rs.Inline)) + r.Merge(rp) + if err != nil { + r.AddOnError(c.Append(field), err) + return + } + } } return } diff --git a/vendor/github.com/coreos/butane/base/v0_4/translate.go b/vendor/github.com/coreos/butane/base/v0_4/translate.go index dabb5546be..56cfff2037 100644 --- a/vendor/github.com/coreos/butane/base/v0_4/translate.go +++ b/vendor/github.com/coreos/butane/base/v0_4/translate.go @@ -145,6 +145,15 @@ func translateResource(from Resource, options common.TranslateOptions) (to types r.AddOnError(c, err) return } + // Validating the contents of the local file from here since there is no way to + // get both the filename and filedirectory in the Validate context + if strings.HasPrefix(c.String(), "$.ignition.config") { + rp, err := ValidateIgnitionConfig(c, contents) + r.Merge(rp) + if err != nil { + return + } + } src, compression, err := baseutil.MakeDataURL(contents, to.Compression, !options.NoResourceAutoCompression) if err != nil { r.AddOnError(c, err) diff --git a/vendor/github.com/coreos/butane/base/v0_4/util.go b/vendor/github.com/coreos/butane/base/v0_4/util.go index d5f855d79b..ff3c36481b 100644 --- a/vendor/github.com/coreos/butane/base/v0_4/util.go +++ b/vendor/github.com/coreos/butane/base/v0_4/util.go @@ -15,7 +15,14 @@ package v0_4 import ( + common "github.com/coreos/butane/config/common" + "github.com/coreos/ignition/v2/config/shared/errors" + "github.com/coreos/ignition/v2/config/util" "github.com/coreos/ignition/v2/config/v3_3/types" + "github.com/coreos/ignition/v2/config/validate" + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" + vvalidate "github.com/coreos/vcontext/validate" ) type nodeTracker struct { @@ -123,3 +130,29 @@ func (t *nodeTracker) AddLink(l types.Link) (int, *types.Link) { t.linkMap[l.Path] = i return i, &(*t.links)[i] } + +func ValidateIgnitionConfig(c path.ContextPath, rawConfig []byte) (report.Report, error) { + r := report.Report{} + var config types.Config + rp, err := util.HandleParseErrors(rawConfig, &config) + if err != nil { + return rp, err + } + vrep := vvalidate.Validate(config.Ignition, "json") + skipValidate := false + if vrep.IsFatal() { + for _, e := range vrep.Entries { + // warn user with ErrUnknownVersion when version is unkown and skip the validation. + if e.Message == errors.ErrUnknownVersion.Error() { + skipValidate = true + r.AddOnWarn(c.Append("version"), common.ErrUnkownIgnitionVersion) + break + } + } + } + if !skipValidate { + report := validate.ValidateWithContext(config, rawConfig) + r.Merge(report) + } + return r, nil +} diff --git a/vendor/github.com/coreos/butane/base/v0_4/validate.go b/vendor/github.com/coreos/butane/base/v0_4/validate.go index 35e072df97..f63d257a1b 100644 --- a/vendor/github.com/coreos/butane/base/v0_4/validate.go +++ b/vendor/github.com/coreos/butane/base/v0_4/validate.go @@ -17,6 +17,7 @@ package v0_4 import ( baseutil "github.com/coreos/butane/base/util" "github.com/coreos/butane/config/common" + "strings" "github.com/coreos/ignition/v2/config/util" "github.com/coreos/vcontext/path" @@ -26,6 +27,7 @@ import ( func (rs Resource) Validate(c path.ContextPath) (r report.Report) { var field string sources := 0 + // Local files are validated in the translateResource function if rs.Local != nil { sources++ field = "local" @@ -40,6 +42,17 @@ func (rs Resource) Validate(c path.ContextPath) (r report.Report) { } if sources > 1 { r.AddOnError(c.Append(field), common.ErrTooManyResourceSources) + return + } + if strings.HasPrefix(c.String(), "$.ignition.config") { + if field == "inline" { + rp, err := ValidateIgnitionConfig(c, []byte(*rs.Inline)) + r.Merge(rp) + if err != nil { + r.AddOnError(c.Append(field), err) + return + } + } } return } diff --git a/vendor/github.com/coreos/butane/base/v0_5/translate.go b/vendor/github.com/coreos/butane/base/v0_5/translate.go index 00fa581b01..d214d6080b 100644 --- a/vendor/github.com/coreos/butane/base/v0_5/translate.go +++ b/vendor/github.com/coreos/butane/base/v0_5/translate.go @@ -148,6 +148,15 @@ func translateResource(from Resource, options common.TranslateOptions) (to types r.AddOnError(c, err) return } + // Validating the contents of the local file from here since there is no way to + // get both the filename and filedirectory in the Validate context + if strings.HasPrefix(c.String(), "$.ignition.config") { + rp, err := ValidateIgnitionConfig(c, contents) + r.Merge(rp) + if err != nil { + return + } + } src, compression, err := baseutil.MakeDataURL(contents, to.Compression, !options.NoResourceAutoCompression) if err != nil { r.AddOnError(c, err) diff --git a/vendor/github.com/coreos/butane/base/v0_5/util.go b/vendor/github.com/coreos/butane/base/v0_5/util.go index 048d7c8263..53a027e3eb 100644 --- a/vendor/github.com/coreos/butane/base/v0_5/util.go +++ b/vendor/github.com/coreos/butane/base/v0_5/util.go @@ -15,7 +15,14 @@ package v0_5 import ( + common "github.com/coreos/butane/config/common" + "github.com/coreos/ignition/v2/config/shared/errors" + "github.com/coreos/ignition/v2/config/util" "github.com/coreos/ignition/v2/config/v3_4/types" + "github.com/coreos/ignition/v2/config/validate" + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" + vvalidate "github.com/coreos/vcontext/validate" ) type nodeTracker struct { @@ -123,3 +130,29 @@ func (t *nodeTracker) AddLink(l types.Link) (int, *types.Link) { t.linkMap[l.Path] = i return i, &(*t.links)[i] } + +func ValidateIgnitionConfig(c path.ContextPath, rawConfig []byte) (report.Report, error) { + r := report.Report{} + var config types.Config + rp, err := util.HandleParseErrors(rawConfig, &config) + if err != nil { + return rp, err + } + vrep := vvalidate.Validate(config.Ignition, "json") + skipValidate := false + if vrep.IsFatal() { + for _, e := range vrep.Entries { + // warn user with ErrUnknownVersion when version is unkown and skip the validation. + if e.Message == errors.ErrUnknownVersion.Error() { + skipValidate = true + r.AddOnWarn(c.Append("version"), common.ErrUnkownIgnitionVersion) + break + } + } + } + if !skipValidate { + report := validate.ValidateWithContext(config, rawConfig) + r.Merge(report) + } + return r, nil +} diff --git a/vendor/github.com/coreos/butane/base/v0_5/validate.go b/vendor/github.com/coreos/butane/base/v0_5/validate.go index 32572e644b..49de857491 100644 --- a/vendor/github.com/coreos/butane/base/v0_5/validate.go +++ b/vendor/github.com/coreos/butane/base/v0_5/validate.go @@ -15,6 +15,8 @@ package v0_5 import ( + "strings" + baseutil "github.com/coreos/butane/base/util" "github.com/coreos/butane/config/common" @@ -26,6 +28,7 @@ import ( func (rs Resource) Validate(c path.ContextPath) (r report.Report) { var field string sources := 0 + // Local files are validated in the translateResource function if rs.Local != nil { sources++ field = "local" @@ -40,6 +43,17 @@ func (rs Resource) Validate(c path.ContextPath) (r report.Report) { } if sources > 1 { r.AddOnError(c.Append(field), common.ErrTooManyResourceSources) + return + } + if strings.HasPrefix(c.String(), "$.ignition.config") { + if field == "inline" { + rp, err := ValidateIgnitionConfig(c, []byte(*rs.Inline)) + r.Merge(rp) + if err != nil { + r.AddOnError(c.Append(field), err) + return + } + } } return } diff --git a/vendor/github.com/coreos/butane/base/v0_6/translate.go b/vendor/github.com/coreos/butane/base/v0_6/translate.go index 7692168455..0b5d306d43 100644 --- a/vendor/github.com/coreos/butane/base/v0_6/translate.go +++ b/vendor/github.com/coreos/butane/base/v0_6/translate.go @@ -148,6 +148,15 @@ func translateResource(from Resource, options common.TranslateOptions) (to types r.AddOnError(c, err) return } + // Validating the contents of the local file from here since there is no way to + // get both the filename and filedirectory in the Validate context + if strings.HasPrefix(c.String(), "$.ignition.config") { + rp, err := ValidateIgnitionConfig(c, contents) + r.Merge(rp) + if err != nil { + return + } + } src, compression, err := baseutil.MakeDataURL(contents, to.Compression, !options.NoResourceAutoCompression) if err != nil { r.AddOnError(c, err) diff --git a/vendor/github.com/coreos/butane/base/v0_6/util.go b/vendor/github.com/coreos/butane/base/v0_6/util.go index fc0ce33e56..4098db2766 100644 --- a/vendor/github.com/coreos/butane/base/v0_6/util.go +++ b/vendor/github.com/coreos/butane/base/v0_6/util.go @@ -15,7 +15,14 @@ package v0_6 import ( + common "github.com/coreos/butane/config/common" + "github.com/coreos/ignition/v2/config/shared/errors" + "github.com/coreos/ignition/v2/config/util" "github.com/coreos/ignition/v2/config/v3_5/types" + "github.com/coreos/ignition/v2/config/validate" + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" + vvalidate "github.com/coreos/vcontext/validate" ) type nodeTracker struct { @@ -123,3 +130,29 @@ func (t *nodeTracker) AddLink(l types.Link) (int, *types.Link) { t.linkMap[l.Path] = i return i, &(*t.links)[i] } + +func ValidateIgnitionConfig(c path.ContextPath, rawConfig []byte) (report.Report, error) { + r := report.Report{} + var config types.Config + rp, err := util.HandleParseErrors(rawConfig, &config) + if err != nil { + return rp, err + } + vrep := vvalidate.Validate(config.Ignition, "json") + skipValidate := false + if vrep.IsFatal() { + for _, e := range vrep.Entries { + // warn user with ErrUnknownVersion when version is unkown and skip the validation. + if e.Message == errors.ErrUnknownVersion.Error() { + skipValidate = true + r.AddOnWarn(c.Append("version"), common.ErrUnkownIgnitionVersion) + break + } + } + } + if !skipValidate { + report := validate.ValidateWithContext(config, rawConfig) + r.Merge(report) + } + return r, nil +} diff --git a/vendor/github.com/coreos/butane/base/v0_6/validate.go b/vendor/github.com/coreos/butane/base/v0_6/validate.go index 9c0d796aa1..88b57ede85 100644 --- a/vendor/github.com/coreos/butane/base/v0_6/validate.go +++ b/vendor/github.com/coreos/butane/base/v0_6/validate.go @@ -17,6 +17,7 @@ package v0_6 import ( baseutil "github.com/coreos/butane/base/util" "github.com/coreos/butane/config/common" + "strings" "github.com/coreos/ignition/v2/config/util" "github.com/coreos/vcontext/path" @@ -26,6 +27,7 @@ import ( func (rs Resource) Validate(c path.ContextPath) (r report.Report) { var field string sources := 0 + // Local files are validated in the translateResource function if rs.Local != nil { sources++ field = "local" @@ -40,6 +42,17 @@ func (rs Resource) Validate(c path.ContextPath) (r report.Report) { } if sources > 1 { r.AddOnError(c.Append(field), common.ErrTooManyResourceSources) + return + } + if strings.HasPrefix(c.String(), "$.ignition.config") { + if field == "inline" { + rp, err := ValidateIgnitionConfig(c, []byte(*rs.Inline)) + r.Merge(rp) + if err != nil { + r.AddOnError(c.Append(field), err) + return + } + } } return } diff --git a/vendor/github.com/coreos/butane/base/v0_7_exp/translate.go b/vendor/github.com/coreos/butane/base/v0_7_exp/translate.go index 6d4f65f21d..fd95720d4d 100644 --- a/vendor/github.com/coreos/butane/base/v0_7_exp/translate.go +++ b/vendor/github.com/coreos/butane/base/v0_7_exp/translate.go @@ -148,6 +148,16 @@ func translateResource(from Resource, options common.TranslateOptions) (to types r.AddOnError(c, err) return } + // Validating the contents of the local file from here since there is no way to + // get both the filename and filedirectory in the Validate context + if strings.HasPrefix(c.String(), "$.ignition.config") { + rp, err := ValidateIgnitionConfig(c, contents) + r.Merge(rp) + if err != nil { + return + } + } + src, compression, err := baseutil.MakeDataURL(contents, to.Compression, !options.NoResourceAutoCompression) if err != nil { r.AddOnError(c, err) diff --git a/vendor/github.com/coreos/butane/base/v0_7_exp/util.go b/vendor/github.com/coreos/butane/base/v0_7_exp/util.go index dbbd7d292c..356c96734c 100644 --- a/vendor/github.com/coreos/butane/base/v0_7_exp/util.go +++ b/vendor/github.com/coreos/butane/base/v0_7_exp/util.go @@ -15,7 +15,14 @@ package v0_7_exp import ( + common "github.com/coreos/butane/config/common" + "github.com/coreos/ignition/v2/config/shared/errors" + "github.com/coreos/ignition/v2/config/util" "github.com/coreos/ignition/v2/config/v3_6_experimental/types" + "github.com/coreos/ignition/v2/config/validate" + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" + vvalidate "github.com/coreos/vcontext/validate" ) type nodeTracker struct { @@ -123,3 +130,29 @@ func (t *nodeTracker) AddLink(l types.Link) (int, *types.Link) { t.linkMap[l.Path] = i return i, &(*t.links)[i] } + +func ValidateIgnitionConfig(c path.ContextPath, rawConfig []byte) (report.Report, error) { + r := report.Report{} + var config types.Config + rp, err := util.HandleParseErrors(rawConfig, &config) + if err != nil { + return rp, err + } + vrep := vvalidate.Validate(config.Ignition, "json") + skipValidate := false + if vrep.IsFatal() { + for _, e := range vrep.Entries { + // warn user with ErrUnknownVersion when version is unkown and skip the validation. + if e.Message == errors.ErrUnknownVersion.Error() { + skipValidate = true + r.AddOnWarn(c.Append("version"), common.ErrUnkownIgnitionVersion) + break + } + } + } + if !skipValidate { + report := validate.ValidateWithContext(config, rawConfig) + r.Merge(report) + } + return r, nil +} diff --git a/vendor/github.com/coreos/butane/base/v0_7_exp/validate.go b/vendor/github.com/coreos/butane/base/v0_7_exp/validate.go index 2d7c69e6c3..ca89e08bda 100644 --- a/vendor/github.com/coreos/butane/base/v0_7_exp/validate.go +++ b/vendor/github.com/coreos/butane/base/v0_7_exp/validate.go @@ -15,6 +15,8 @@ package v0_7_exp import ( + "strings" + baseutil "github.com/coreos/butane/base/util" "github.com/coreos/butane/config/common" @@ -26,6 +28,7 @@ import ( func (rs Resource) Validate(c path.ContextPath) (r report.Report) { var field string sources := 0 + // Local files are validated in the translateResource function if rs.Local != nil { sources++ field = "local" @@ -40,6 +43,17 @@ func (rs Resource) Validate(c path.ContextPath) (r report.Report) { } if sources > 1 { r.AddOnError(c.Append(field), common.ErrTooManyResourceSources) + return + } + if strings.HasPrefix(c.String(), "$.ignition.config") { + if field == "inline" { + rp, err := ValidateIgnitionConfig(c, []byte(*rs.Inline)) + r.Merge(rp) + if err != nil { + r.AddOnError(c.Append(field), err) + return + } + } } return } diff --git a/vendor/github.com/coreos/butane/config/common/errors.go b/vendor/github.com/coreos/butane/config/common/errors.go index 71f3c0d223..f653815ec0 100644 --- a/vendor/github.com/coreos/butane/config/common/errors.go +++ b/vendor/github.com/coreos/butane/config/common/errors.go @@ -61,27 +61,29 @@ var ( ErrLuksBootDeviceBadName = errors.New("device name must start with /dev/dasd on s390x-eckd layout or /dev/sd on s390x-zfcp layout") ErrCexArchitectureMismatch = errors.New("when using cex the targeted architecture must match s390x") ErrCexNotSupported = errors.New("cex is not currently supported on the target platform") + ErrNoLuksMethodSpecified = errors.New("no method specified for luks") // partition ErrReuseByLabel = errors.New("partitions cannot be reused by label; number must be specified except on boot disk (/dev/disk/by-id/coreos-boot-disk) or when wipe_table is true") ErrWrongPartitionNumber = errors.New("incorrect partition number; a new partition will be created using reserved label") // MachineConfigs - ErrFieldElided = errors.New("field ignored in raw mode") - ErrNameRequired = errors.New("metadata.name is required") - ErrRoleRequired = errors.New("machineconfiguration.openshift.io/role label is required") - ErrInvalidKernelType = errors.New("must be empty, \"default\", or \"realtime\"") - ErrBtrfsSupport = errors.New("btrfs is not supported in this spec version") - ErrFilesystemNoneSupport = errors.New("format \"none\" is not supported in this spec version") - ErrFileSchemeSupport = errors.New("file contents source must be data URL in this spec version") - ErrFileAppendSupport = errors.New("appending to files is not supported in this spec version") - ErrFileCompressionSupport = errors.New("file compression is not supported in this spec version") - ErrFileHeaderSupport = errors.New("file HTTP headers are not supported in this spec version") - ErrFileSpecialModeSupport = errors.New("special mode bits are not supported in this spec version") - ErrGroupSupport = errors.New("groups are not supported in this spec version") - ErrUserFieldSupport = errors.New("fields other than \"name\", \"ssh_authorized_keys\", and \"password_hash\" (4.13.0+) are not supported in this spec version") - ErrUserNameSupport = errors.New("users other than \"core\" are not supported in this spec version") - ErrKernelArgumentSupport = errors.New("this section cannot be used for kernel arguments in this spec version; use openshift.kernel_arguments instead") + ErrFieldElided = errors.New("field ignored in raw mode") + ErrNameRequired = errors.New("metadata.name is required") + ErrRoleRequired = errors.New("machineconfiguration.openshift.io/role label is required") + ErrInvalidKernelType = errors.New("must be empty, \"default\", or \"realtime\"") + ErrBtrfsSupport = errors.New("btrfs is not supported in this spec version") + ErrFilesystemNoneSupport = errors.New("format \"none\" is not supported in this spec version") + ErrFileSchemeSupport = errors.New("file contents source must be data URL in this spec version") + ErrFileAppendSupport = errors.New("appending to files is not supported in this spec version") + ErrFileCompressionSupport = errors.New("file compression is not supported in this spec version") + ErrFileHeaderSupport = errors.New("file HTTP headers are not supported in this spec version") + ErrFileSpecialModeSupport = errors.New("special mode bits are not supported in this spec version") + ErrGroupSupport = errors.New("groups are not supported in this spec version") + ErrUserFieldSupport = errors.New("fields other than \"name\", \"ssh_authorized_keys\", and \"password_hash\" (4.13.0+) are not supported in this spec version") + ErrUserNameSupport = errors.New("users other than \"core\" are not supported in this spec version") + ErrKernelArgumentSupport = errors.New("this section cannot be used for kernel arguments in this spec version; use openshift.kernel_arguments instead") + ErrMissingKernelArgumentCex = errors.New("'rd.luks.key=/etc/luks/cex.key' must be set as kernel argument when CEX is enabled for the boot device") // Storage ErrClevisSupport = errors.New("clevis is not supported in this spec version") @@ -98,6 +100,9 @@ var ( // Kernel arguments ErrGeneralKernelArgumentSupport = errors.New("kernel argument customization is not supported in this spec version") + + // Unkown ignition version + ErrUnkownIgnitionVersion = errors.New("skipping validation for the merge/replace ignition config due to an unkown version") ) type ErrUnmarshal struct { diff --git a/vendor/github.com/coreos/butane/config/config.go b/vendor/github.com/coreos/butane/config/config.go index 93aa2a0321..ac69167d68 100644 --- a/vendor/github.com/coreos/butane/config/config.go +++ b/vendor/github.com/coreos/butane/config/config.go @@ -40,7 +40,8 @@ import ( openshift4_16 "github.com/coreos/butane/config/openshift/v4_16" openshift4_17 "github.com/coreos/butane/config/openshift/v4_17" openshift4_18 "github.com/coreos/butane/config/openshift/v4_18" - openshift4_19_exp "github.com/coreos/butane/config/openshift/v4_19_exp" + openshift4_19 "github.com/coreos/butane/config/openshift/v4_19" + openshift4_20_exp "github.com/coreos/butane/config/openshift/v4_20_exp" openshift4_8 "github.com/coreos/butane/config/openshift/v4_8" openshift4_9 "github.com/coreos/butane/config/openshift/v4_9" r4e1_0 "github.com/coreos/butane/config/r4e/v1_0" @@ -85,7 +86,8 @@ func init() { RegisterTranslator("openshift", "4.16.0", openshift4_16.ToConfigBytes) RegisterTranslator("openshift", "4.17.0", openshift4_17.ToConfigBytes) RegisterTranslator("openshift", "4.18.0", openshift4_18.ToConfigBytes) - RegisterTranslator("openshift", "4.19.0-experimental", openshift4_19_exp.ToConfigBytes) + RegisterTranslator("openshift", "4.19.0", openshift4_19.ToConfigBytes) + RegisterTranslator("openshift", "4.20.0-experimental", openshift4_20_exp.ToConfigBytes) RegisterTranslator("r4e", "1.0.0", r4e1_0.ToIgn3_3Bytes) RegisterTranslator("r4e", "1.1.0", r4e1_1.ToIgn3_4Bytes) RegisterTranslator("r4e", "1.2.0-experimental", r4e1_2_exp.ToIgn3_6Bytes) diff --git a/vendor/github.com/coreos/butane/config/fcos/v1_7_exp/validate.go b/vendor/github.com/coreos/butane/config/fcos/v1_7_exp/validate.go index e84ed1e644..c49da8dc98 100644 --- a/vendor/github.com/coreos/butane/config/fcos/v1_7_exp/validate.go +++ b/vendor/github.com/coreos/butane/config/fcos/v1_7_exp/validate.go @@ -18,6 +18,7 @@ import ( "regexp" "strings" + base "github.com/coreos/butane/base/v0_7_exp" "github.com/coreos/butane/config/common" "github.com/coreos/ignition/v2/config/shared/errors" "github.com/coreos/ignition/v2/config/util" @@ -96,6 +97,26 @@ func (d BootDevice) Validate(c path.ContextPath) (r report.Report) { return } +func (l BootDeviceLuks) Validate(c path.ContextPath) (r report.Report) { + if util.NotEmpty(l.Device) { + valid := false + for _, t := range l.Tang { + if t != (base.Tang{}) { + valid = true + } + } + if util.IsTrue(l.Tpm2) { + valid = true + } else if util.IsTrue(l.Cex.Enabled) { + valid = true + } + if !valid { + r.AddOnError(c.Append("luks"), common.ErrNoLuksMethodSpecified) + } + } + return +} + func (m BootDeviceMirror) Validate(c path.ContextPath) (r report.Report) { if len(m.Devices) == 1 { r.AddOnError(c.Append("devices"), common.ErrTooFewMirrorDevices) diff --git a/vendor/github.com/coreos/butane/config/openshift/v4_19/result/schema.go b/vendor/github.com/coreos/butane/config/openshift/v4_19/result/schema.go new file mode 100644 index 0000000000..62bc2054e2 --- /dev/null +++ b/vendor/github.com/coreos/butane/config/openshift/v4_19/result/schema.go @@ -0,0 +1,48 @@ +// Copyright 2021 Red Hat, Inc +// +// 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 result + +import ( + "github.com/coreos/ignition/v2/config/v3_5/types" +) + +const ( + MC_API_VERSION = "machineconfiguration.openshift.io/v1" + MC_KIND = "MachineConfig" +) + +// We round-trip through JSON because Ignition uses `json` struct tags, +// so all struct tags need to be `json` even though we're ultimately +// writing YAML. + +type MachineConfig struct { + ApiVersion string `json:"apiVersion"` + Kind string `json:"kind"` + Metadata Metadata `json:"metadata"` + Spec Spec `json:"spec"` +} + +type Metadata struct { + Name string `json:"name"` + Labels map[string]string `json:"labels,omitempty"` +} + +type Spec struct { + Config types.Config `json:"config"` + KernelArguments []string `json:"kernelArguments,omitempty"` + Extensions []string `json:"extensions,omitempty"` + FIPS *bool `json:"fips,omitempty"` + KernelType *string `json:"kernelType,omitempty"` +} diff --git a/vendor/github.com/coreos/butane/config/openshift/v4_19/schema.go b/vendor/github.com/coreos/butane/config/openshift/v4_19/schema.go new file mode 100644 index 0000000000..6154a0a3e4 --- /dev/null +++ b/vendor/github.com/coreos/butane/config/openshift/v4_19/schema.go @@ -0,0 +1,39 @@ +// Copyright 2020 Red Hat, Inc +// +// 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 v4_19 + +import ( + fcos "github.com/coreos/butane/config/fcos/v1_6" +) + +const ROLE_LABEL_KEY = "machineconfiguration.openshift.io/role" + +type Config struct { + fcos.Config `yaml:",inline"` + Metadata Metadata `yaml:"metadata"` + OpenShift OpenShift `yaml:"openshift"` +} + +type Metadata struct { + Name string `yaml:"name"` + Labels map[string]string `yaml:"labels,omitempty"` +} + +type OpenShift struct { + KernelArguments []string `yaml:"kernel_arguments"` + Extensions []string `yaml:"extensions"` + FIPS *bool `yaml:"fips"` + KernelType *string `yaml:"kernel_type"` +} diff --git a/vendor/github.com/coreos/butane/config/openshift/v4_19/translate.go b/vendor/github.com/coreos/butane/config/openshift/v4_19/translate.go new file mode 100644 index 0000000000..ac0807b08a --- /dev/null +++ b/vendor/github.com/coreos/butane/config/openshift/v4_19/translate.go @@ -0,0 +1,303 @@ +// Copyright 2020 Red Hat, Inc +// +// 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 v4_19 + +import ( + "net/url" + "strings" + + "github.com/coreos/butane/config/common" + "github.com/coreos/butane/config/openshift/v4_19/result" + cutil "github.com/coreos/butane/config/util" + "github.com/coreos/butane/translate" + + "github.com/coreos/ignition/v2/config/util" + "github.com/coreos/ignition/v2/config/v3_5/types" + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +// Error classes: +// +// UNPARSABLE - Cannot be rendered into a config by the MCC. If present in +// MC, MCC will mark the pool degraded. We reject these. +// +// FORBIDDEN - Not supported by the MCD. If present in MC, MCD will mark +// the node degraded. We reject these. +// +// REDUNDANT - Feature is also provided by a MachineConfig-specific field +// with different semantics. To reduce confusion, disable this +// implementation. +// +// IMMUTABLE - Permitted in MC, passed through to Ignition, but not +// supported by the MCD. MCD will mark the node degraded if the field +// changes after the node is provisioned. We reject these outright to +// discourage their use. +// +// TRIPWIRE - A subset of fields in the containing struct are supported by +// the MCD. If the struct contents change after the node is provisioned, +// and the struct contains unsupported fields, MCD will mark the node +// degraded, even if the change only affects supported fields. We reject +// these. + +const ( + // FIPS 140-2 doesn't allow the default XTS mode + fipsCipherOption = types.LuksOption("--cipher") + fipsCipherShortOption = types.LuksOption("-c") + fipsCipherArgument = types.LuksOption("aes-cbc-essiv:sha256") +) + +var ( + // See also validateRHCOSSupport() and validateMCOSupport() + fieldFilters = cutil.NewFilters(result.MachineConfig{}, cutil.FilterMap{ + // UNPARSABLE, REDUNDANT + "spec.config.kernelArguments": common.ErrKernelArgumentSupport, + // IMMUTABLE + "spec.config.passwd.groups": common.ErrGroupSupport, + // TRIPWIRE + "spec.config.passwd.users.gecos": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.groups": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.homeDir": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.noCreateHome": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.noLogInit": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.noUserGroup": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.primaryGroup": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.shell": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.shouldExist": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.system": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.uid": common.ErrUserFieldSupport, + // IMMUTABLE + "spec.config.storage.directories": common.ErrDirectorySupport, + // FORBIDDEN + "spec.config.storage.files.append": common.ErrFileAppendSupport, + // redundant with a check from Ignition validation, but ensures we + // exclude the section from docs + "spec.config.storage.files.contents.httpHeaders": common.ErrFileHeaderSupport, + // IMMUTABLE + // If you change this to be less restrictive without adding + // link support in the MCO, consider what should happen if + // the user specifies a storage.tree that includes symlinks. + "spec.config.storage.links": common.ErrLinkSupport, + }) +) + +// Return FieldFilters for this spec. +func (c Config) FieldFilters() *cutil.FieldFilters { + return &fieldFilters +} + +// ToMachineConfig4_19Unvalidated translates the config to a MachineConfig. It also +// returns the set of translations it did so paths in the resultant config +// can be tracked back to their source in the source config. No config +// validation is performed on input or output. +func (c Config) ToMachineConfig4_19Unvalidated(options common.TranslateOptions) (result.MachineConfig, translate.TranslationSet, report.Report) { + cfg, ts, r := c.Config.ToIgn3_5Unvalidated(options) + if r.IsFatal() { + return result.MachineConfig{}, ts, r + } + + // wrap + ts = ts.PrefixPaths(path.New("yaml"), path.New("json", "spec", "config")) + mc := result.MachineConfig{ + ApiVersion: result.MC_API_VERSION, + Kind: result.MC_KIND, + Metadata: result.Metadata{ + Name: c.Metadata.Name, + Labels: make(map[string]string), + }, + Spec: result.Spec{ + Config: cfg, + }, + } + ts.AddTranslation(path.New("yaml", "version"), path.New("json", "apiVersion")) + ts.AddTranslation(path.New("yaml", "version"), path.New("json", "kind")) + ts.AddTranslation(path.New("yaml", "metadata"), path.New("json", "metadata")) + ts.AddTranslation(path.New("yaml", "metadata", "name"), path.New("json", "metadata", "name")) + ts.AddTranslation(path.New("yaml", "metadata", "labels"), path.New("json", "metadata", "labels")) + ts.AddTranslation(path.New("yaml", "version"), path.New("json", "spec")) + ts.AddTranslation(path.New("yaml"), path.New("json", "spec", "config")) + for k, v := range c.Metadata.Labels { + mc.Metadata.Labels[k] = v + ts.AddTranslation(path.New("yaml", "metadata", "labels", k), path.New("json", "metadata", "labels", k)) + } + + // translate OpenShift fields + tr := translate.NewTranslator("yaml", "json", options) + from := &c.OpenShift + to := &mc.Spec + ts2, r2 := translate.Prefixed(tr, "extensions", &from.Extensions, &to.Extensions) + translate.MergeP(tr, ts2, &r2, "fips", &from.FIPS, &to.FIPS) + translate.MergeP2(tr, ts2, &r2, "kernel_arguments", &from.KernelArguments, "kernelArguments", &to.KernelArguments) + translate.MergeP2(tr, ts2, &r2, "kernel_type", &from.KernelType, "kernelType", &to.KernelType) + ts.MergeP2("openshift", "spec", ts2) + r.Merge(r2) + + // apply FIPS options to LUKS volumes + ts.Merge(addLuksFipsOptions(&mc)) + + // finally, check the fully desugared config for RHCOS and MCO support + r.Merge(validateRHCOSSupport(mc)) + r.Merge(validateMCOSupport(mc)) + + return mc, ts, r +} + +// ToMachineConfig4_19 translates the config to a MachineConfig. It returns a +// report of any errors or warnings in the source and resultant config. If +// the report has fatal errors or it encounters other problems translating, +// an error is returned. +func (c Config) ToMachineConfig4_19(options common.TranslateOptions) (result.MachineConfig, report.Report, error) { + cfg, r, err := cutil.Translate(c, "ToMachineConfig4_19Unvalidated", options) + return cfg.(result.MachineConfig), r, err +} + +// ToIgn3_5Unvalidated translates the config to an Ignition config. It also +// returns the set of translations it did so paths in the resultant config +// can be tracked back to their source in the source config. No config +// validation is performed on input or output. +func (c Config) ToIgn3_5Unvalidated(options common.TranslateOptions) (types.Config, translate.TranslationSet, report.Report) { + mc, ts, r := c.ToMachineConfig4_19Unvalidated(options) + cfg := mc.Spec.Config + + // report warnings if there are any non-empty fields in Spec (other + // than the Ignition config itself) that we're ignoring + mc.Spec.Config = types.Config{} + warnings := translate.PrefixReport(cutil.CheckForElidedFields(mc.Spec), "spec") + // translate from json space into yaml space, since the caller won't + // have enough info to do it + r.Merge(cutil.TranslateReportPaths(warnings, ts)) + + ts = ts.Descend(path.New("json", "spec", "config")) + return cfg, ts, r +} + +// ToIgn3_5 translates the config to an Ignition config. It returns a +// report of any errors or warnings in the source and resultant config. If +// the report has fatal errors or it encounters other problems translating, +// an error is returned. +func (c Config) ToIgn3_5(options common.TranslateOptions) (types.Config, report.Report, error) { + cfg, r, err := cutil.Translate(c, "ToIgn3_5Unvalidated", options) + return cfg.(types.Config), r, err +} + +// ToConfigBytes translates from a v4.19 Butane config to a v4.19 MachineConfig or a v3.5.0 Ignition config. It returns a report of any errors or +// warnings in the source and resultant config. If the report has fatal errors or it encounters other problems +// translating, an error is returned. +func ToConfigBytes(input []byte, options common.TranslateBytesOptions) ([]byte, report.Report, error) { + if options.Raw { + return cutil.TranslateBytes(input, &Config{}, "ToIgn3_5", options) + } else { + return cutil.TranslateBytesYAML(input, &Config{}, "ToMachineConfig4_19", options) + } +} + +func addLuksFipsOptions(mc *result.MachineConfig) translate.TranslationSet { + ts := translate.NewTranslationSet("yaml", "json") + if !util.IsTrue(mc.Spec.FIPS) { + return ts + } + +OUTER: + for i := range mc.Spec.Config.Storage.Luks { + luks := &mc.Spec.Config.Storage.Luks[i] + // Only add options if the user hasn't already specified + // a cipher option. Do this in-place, since config merging + // doesn't support conditional logic. + for _, option := range luks.Options { + if option == fipsCipherOption || + strings.HasPrefix(string(option), string(fipsCipherOption)+"=") || + option == fipsCipherShortOption { + continue OUTER + } + } + for j := 0; j < 2; j++ { + ts.AddTranslation(path.New("yaml", "openshift", "fips"), path.New("json", "spec", "config", "storage", "luks", i, "options", len(luks.Options)+j)) + } + if len(luks.Options) == 0 { + ts.AddTranslation(path.New("yaml", "openshift", "fips"), path.New("json", "spec", "config", "storage", "luks", i, "options")) + } + luks.Options = append(luks.Options, fipsCipherOption, fipsCipherArgument) + } + return ts +} + +// Error on fields that are rejected by RHCOS. +// +// Some of these fields may have been generated by sugar (e.g. +// boot_device.luks), so we work in JSON (output) space and then translate +// paths back to YAML (input) space. That's also the reason we do these +// checks after translation, rather than during validation. +func validateRHCOSSupport(mc result.MachineConfig) report.Report { + var r report.Report + for i, fs := range mc.Spec.Config.Storage.Filesystems { + if fs.Format != nil && *fs.Format == "btrfs" { + // we don't ship mkfs.btrfs + r.AddOnError(path.New("json", "spec", "config", "storage", "filesystems", i, "format"), common.ErrBtrfsSupport) + } + } + return r +} + +// Error on fields that are rejected outright by the MCO, or that are +// unsupported by the MCO and we want to discourage. +// +// https://github.com/openshift/machine-config-operator/blob/d6dabadeca05/MachineConfigDaemon.md#supported-vs-unsupported-ignition-config-changes +// +// Some of these fields may have been generated by sugar (e.g. storage.trees), +// so we work in JSON (output) space and then translate paths back to YAML +// (input) space. That's also the reason we do these checks after +// translation, rather than during validation. +func validateMCOSupport(mc result.MachineConfig) report.Report { + // See also fieldFilters at the top of this file. + + var r report.Report + for i, fs := range mc.Spec.Config.Storage.Filesystems { + if fs.Format != nil && *fs.Format == "none" { + // UNPARSABLE + r.AddOnError(path.New("json", "spec", "config", "storage", "filesystems", i, "format"), common.ErrFilesystemNoneSupport) + } + } + for i, file := range mc.Spec.Config.Storage.Files { + if file.Contents.Source != nil { + fileSource, err := url.Parse(*file.Contents.Source) + // parse errors will be caught by normal config validation + if err == nil && fileSource.Scheme != "data" { + // FORBIDDEN + r.AddOnError(path.New("json", "spec", "config", "storage", "files", i, "contents", "source"), common.ErrFileSchemeSupport) + } + } + if file.Mode != nil && *file.Mode & ^0777 != 0 { + // UNPARSABLE + r.AddOnError(path.New("json", "spec", "config", "storage", "files", i, "mode"), common.ErrFileSpecialModeSupport) + } + } + for i, user := range mc.Spec.Config.Passwd.Users { + if user.Name != "core" { + // TRIPWIRE + r.AddOnError(path.New("json", "spec", "config", "passwd", "users", i, "name"), common.ErrUserNameSupport) + } + } + return r +} diff --git a/vendor/github.com/coreos/butane/config/openshift/v4_19_exp/validate.go b/vendor/github.com/coreos/butane/config/openshift/v4_19/validate.go similarity index 54% rename from vendor/github.com/coreos/butane/config/openshift/v4_19_exp/validate.go rename to vendor/github.com/coreos/butane/config/openshift/v4_19/validate.go index 969bf98d4f..89de23ba67 100644 --- a/vendor/github.com/coreos/butane/config/openshift/v4_19_exp/validate.go +++ b/vendor/github.com/coreos/butane/config/openshift/v4_19/validate.go @@ -12,10 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License.) -package v4_19_exp +package v4_19 import ( + "slices" + "github.com/coreos/butane/config/common" + "github.com/coreos/ignition/v2/config/util" "github.com/coreos/vcontext/path" "github.com/coreos/vcontext/report" @@ -41,3 +44,25 @@ func (os OpenShift) Validate(c path.ContextPath) (r report.Report) { } return } + +// Validate that we have the required kernel argument pointing to the key file +// if we have CEX support enabled. We only do this in the openshift spec as +// this is implemented differently in the fcos one. +// See: https://github.com/coreos/butane/issues/611 +// See: https://github.com/coreos/butane/issues/613 +func (conf Config) Validate(c path.ContextPath) (r report.Report) { + if util.IsTrue(conf.BootDevice.Luks.Cex.Enabled) && !slices.Contains(conf.OpenShift.KernelArguments, "rd.luks.key=/etc/luks/cex.key") { + r.AddOnError(c.Append("openshift", "kernel_arguments"), common.ErrMissingKernelArgumentCex) + } + cex := false + for _, l := range conf.Storage.Luks { + if util.IsTrue(l.Cex.Enabled) && l.Name == "root" { + cex = true + } + } + if cex && !slices.Contains(conf.OpenShift.KernelArguments, "rd.luks.key=/etc/luks/cex.key") { + r.AddOnError(c.Append("openshift", "kernel_arguments"), common.ErrMissingKernelArgumentCex) + } + + return +} diff --git a/vendor/github.com/coreos/butane/config/openshift/v4_19_exp/result/schema.go b/vendor/github.com/coreos/butane/config/openshift/v4_20_exp/result/schema.go similarity index 100% rename from vendor/github.com/coreos/butane/config/openshift/v4_19_exp/result/schema.go rename to vendor/github.com/coreos/butane/config/openshift/v4_20_exp/result/schema.go diff --git a/vendor/github.com/coreos/butane/config/openshift/v4_19_exp/schema.go b/vendor/github.com/coreos/butane/config/openshift/v4_20_exp/schema.go similarity index 98% rename from vendor/github.com/coreos/butane/config/openshift/v4_19_exp/schema.go rename to vendor/github.com/coreos/butane/config/openshift/v4_20_exp/schema.go index 5acdd04a5d..00e1ca1146 100644 --- a/vendor/github.com/coreos/butane/config/openshift/v4_19_exp/schema.go +++ b/vendor/github.com/coreos/butane/config/openshift/v4_20_exp/schema.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License.) -package v4_19_exp +package v4_20_exp import ( fcos "github.com/coreos/butane/config/fcos/v1_7_exp" diff --git a/vendor/github.com/coreos/butane/config/openshift/v4_19_exp/translate.go b/vendor/github.com/coreos/butane/config/openshift/v4_20_exp/translate.go similarity index 95% rename from vendor/github.com/coreos/butane/config/openshift/v4_19_exp/translate.go rename to vendor/github.com/coreos/butane/config/openshift/v4_20_exp/translate.go index e535e61274..c64e507180 100644 --- a/vendor/github.com/coreos/butane/config/openshift/v4_19_exp/translate.go +++ b/vendor/github.com/coreos/butane/config/openshift/v4_20_exp/translate.go @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License.) -package v4_19_exp +package v4_20_exp import ( "net/url" "strings" "github.com/coreos/butane/config/common" - "github.com/coreos/butane/config/openshift/v4_19_exp/result" + "github.com/coreos/butane/config/openshift/v4_20_exp/result" cutil "github.com/coreos/butane/config/util" "github.com/coreos/butane/translate" @@ -108,11 +108,11 @@ func (c Config) FieldFilters() *cutil.FieldFilters { return &fieldFilters } -// ToMachineConfig4_18Unvalidated translates the config to a MachineConfig. It also +// ToMachineConfig4_20Unvalidated translates the config to a MachineConfig. It also // returns the set of translations it did so paths in the resultant config // can be tracked back to their source in the source config. No config // validation is performed on input or output. -func (c Config) ToMachineConfig4_19Unvalidated(options common.TranslateOptions) (result.MachineConfig, translate.TranslationSet, report.Report) { +func (c Config) ToMachineConfig4_20Unvalidated(options common.TranslateOptions) (result.MachineConfig, translate.TranslationSet, report.Report) { cfg, ts, r := c.Config.ToIgn3_6Unvalidated(options) if r.IsFatal() { return result.MachineConfig{}, ts, r @@ -165,12 +165,12 @@ func (c Config) ToMachineConfig4_19Unvalidated(options common.TranslateOptions) return mc, ts, r } -// ToMachineConfig4_18 translates the config to a MachineConfig. It returns a +// ToMachineConfig4_20 translates the config to a MachineConfig. It returns a // report of any errors or warnings in the source and resultant config. If // the report has fatal errors or it encounters other problems translating, // an error is returned. -func (c Config) ToMachineConfig4_19(options common.TranslateOptions) (result.MachineConfig, report.Report, error) { - cfg, r, err := cutil.Translate(c, "ToMachineConfig4_19Unvalidated", options) +func (c Config) ToMachineConfig4_20(options common.TranslateOptions) (result.MachineConfig, report.Report, error) { + cfg, r, err := cutil.Translate(c, "ToMachineConfig4_20Unvalidated", options) return cfg.(result.MachineConfig), r, err } @@ -179,7 +179,7 @@ func (c Config) ToMachineConfig4_19(options common.TranslateOptions) (result.Mac // can be tracked back to their source in the source config. No config // validation is performed on input or output. func (c Config) ToIgn3_6Unvalidated(options common.TranslateOptions) (types.Config, translate.TranslationSet, report.Report) { - mc, ts, r := c.ToMachineConfig4_19Unvalidated(options) + mc, ts, r := c.ToMachineConfig4_20Unvalidated(options) cfg := mc.Spec.Config // report warnings if there are any non-empty fields in Spec (other @@ -203,14 +203,14 @@ func (c Config) ToIgn3_6(options common.TranslateOptions) (types.Config, report. return cfg.(types.Config), r, err } -// ToConfigBytes translates from a v4.17 Butane config to a v4.17 MachineConfig or a v3.6.0-experimental Ignition config. It returns a report of any errors or +// ToConfigBytes translates from a v4.20 Butane config to a v4.20 MachineConfig or a v3.6.0-experimental Ignition config. It returns a report of any errors or // warnings in the source and resultant config. If the report has fatal errors or it encounters other problems // translating, an error is returned. func ToConfigBytes(input []byte, options common.TranslateBytesOptions) ([]byte, report.Report, error) { if options.Raw { return cutil.TranslateBytes(input, &Config{}, "ToIgn3_6", options) } else { - return cutil.TranslateBytesYAML(input, &Config{}, "ToMachineConfig4_19", options) + return cutil.TranslateBytesYAML(input, &Config{}, "ToMachineConfig4_20", options) } } diff --git a/vendor/github.com/coreos/butane/config/openshift/v4_20_exp/validate.go b/vendor/github.com/coreos/butane/config/openshift/v4_20_exp/validate.go new file mode 100644 index 0000000000..537af01fdd --- /dev/null +++ b/vendor/github.com/coreos/butane/config/openshift/v4_20_exp/validate.go @@ -0,0 +1,68 @@ +// Copyright 2021 Red Hat, Inc +// +// 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 v4_20_exp + +import ( + "slices" + + "github.com/coreos/butane/config/common" + "github.com/coreos/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (m Metadata) Validate(c path.ContextPath) (r report.Report) { + if m.Name == "" { + r.AddOnError(c.Append("name"), common.ErrNameRequired) + } + if m.Labels[ROLE_LABEL_KEY] == "" { + r.AddOnError(c.Append("labels"), common.ErrRoleRequired) + } + return +} + +func (os OpenShift) Validate(c path.ContextPath) (r report.Report) { + if os.KernelType != nil { + switch *os.KernelType { + case "", "default", "realtime": + default: + r.AddOnError(c.Append("kernel_type"), common.ErrInvalidKernelType) + } + } + return +} + +// Validate that we have the required kernel argument pointing to the key file +// if we have CEX support enabled. We only do this in the openshift spec as +// this is implemented differently in the fcos one. +// See: https://github.com/coreos/butane/issues/611 +// See: https://github.com/coreos/butane/issues/613 +func (conf Config) Validate(c path.ContextPath) (r report.Report) { + if util.IsTrue(conf.BootDevice.Luks.Cex.Enabled) && !slices.Contains(conf.OpenShift.KernelArguments, "rd.luks.key=/etc/luks/cex.key") { + r.AddOnError(c.Append("openshift", "kernel_arguments"), common.ErrMissingKernelArgumentCex) + } + cex := false + for _, l := range conf.Storage.Luks { + if util.IsTrue(l.Cex.Enabled) && l.Name == "root" { + cex = true + } + } + if cex && !slices.Contains(conf.OpenShift.KernelArguments, "rd.luks.key=/etc/luks/cex.key") { + r.AddOnError(c.Append("openshift", "kernel_arguments"), common.ErrMissingKernelArgumentCex) + } + + return +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 35cadacd63..f80cc8de04 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -258,7 +258,7 @@ github.com/containers/image/v5/docker/reference # github.com/containers/storage v1.57.2 ## explicit; go 1.22.0 github.com/containers/storage/pkg/regexp -# github.com/coreos/butane v0.23.0 +# github.com/coreos/butane v0.24.0 ## explicit; go 1.20 github.com/coreos/butane/base/util github.com/coreos/butane/base/v0_1 @@ -301,8 +301,10 @@ github.com/coreos/butane/config/openshift/v4_17 github.com/coreos/butane/config/openshift/v4_17/result github.com/coreos/butane/config/openshift/v4_18 github.com/coreos/butane/config/openshift/v4_18/result -github.com/coreos/butane/config/openshift/v4_19_exp -github.com/coreos/butane/config/openshift/v4_19_exp/result +github.com/coreos/butane/config/openshift/v4_19 +github.com/coreos/butane/config/openshift/v4_19/result +github.com/coreos/butane/config/openshift/v4_20_exp +github.com/coreos/butane/config/openshift/v4_20_exp/result github.com/coreos/butane/config/openshift/v4_8 github.com/coreos/butane/config/openshift/v4_8/result github.com/coreos/butane/config/openshift/v4_9