From 8306c1a4a0ac34ed88b27241e574939078503125 Mon Sep 17 00:00:00 2001 From: mike-winberry Date: Wed, 6 Mar 2024 08:48:55 -0800 Subject: [PATCH 01/13] deps: update go-oscal --- go.mod | 4 +++- go.sum | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 742aaaea..b99ea1e6 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/defenseunicorns/lula go 1.22.0 require ( - github.com/defenseunicorns/go-oscal v0.2.0 + github.com/defenseunicorns/go-oscal v0.2.2 github.com/mitchellh/mapstructure v1.5.0 github.com/open-policy-agent/opa v0.62.0 github.com/pterm/pterm v0.12.79 @@ -94,6 +94,8 @@ require ( github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/swaggest/jsonschema-go v0.3.67 // indirect + github.com/swaggest/refl v1.3.0 // indirect github.com/tchap/go-patricia/v2 v2.3.1 // indirect github.com/vladimirvivien/gexe v0.2.0 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect diff --git a/go.sum b/go.sum index 29df9144..acf033c5 100644 --- a/go.sum +++ b/go.sum @@ -61,6 +61,8 @@ github.com/daviddengcn/go-colortext v1.0.0 h1:ANqDyC0ys6qCSvuEK7l3g5RaehL/Xck9EX github.com/daviddengcn/go-colortext v1.0.0/go.mod h1:zDqEI5NVUop5QPpVJUxE9UO10hRnmkD5G4Pmri9+m4c= github.com/defenseunicorns/go-oscal v0.2.0 h1:hyRMUoQT2RFk/VIxz19yZKngobjdIuI+si6+k7+OX/M= github.com/defenseunicorns/go-oscal v0.2.0/go.mod h1:4JXNIFmWK1VBHpmXicW/g65MizUEHKUexy3Lb2lH2/I= +github.com/defenseunicorns/go-oscal v0.2.2 h1:JEXhNNRoVseDcH+Tlagf+MM8Y9nv5r7mPEHrAQIW7I0= +github.com/defenseunicorns/go-oscal v0.2.2/go.mod h1:4JXNIFmWK1VBHpmXicW/g65MizUEHKUexy3Lb2lH2/I= github.com/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg= github.com/dgraph-io/badger/v3 v3.2103.5/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= @@ -305,6 +307,10 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/swaggest/jsonschema-go v0.3.67 h1:09tIfjZdeJW5ijK6ahkSpfVZv8Rj7tG3SLi/C/knj4c= +github.com/swaggest/jsonschema-go v0.3.67/go.mod h1:7N43/CwdaWgPUDfYV70K7Qm79tRqe/al7gLSt9YeGIE= +github.com/swaggest/refl v1.3.0 h1:PEUWIku+ZznYfsoyheF97ypSduvMApYyGkYF3nabS0I= +github.com/swaggest/refl v1.3.0/go.mod h1:3Ujvbmh1pfSbDYjC6JGG7nMgPvpG0ehQL4iNonnLNbg= github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes= github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= github.com/vladimirvivien/gexe v0.2.0 h1:nbdAQ6vbZ+ZNsolCgSVb9Fno60kzSuvtzVh6Ytqi/xY= From 68ad63930e346f381d46af0bc0b457d047cd53b3 Mon Sep 17 00:00:00 2001 From: mike-winberry Date: Wed, 6 Mar 2024 12:49:42 -0800 Subject: [PATCH 02/13] #281. Create the basic logic for revision. TODO: write the upgraded output to file. Wait on next go-oscal release for utilities needed to handle more succinctly --- src/cmd/tools/lint.go | 1 + src/cmd/tools/upgrade.go | 63 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/cmd/tools/upgrade.go diff --git a/src/cmd/tools/lint.go b/src/cmd/tools/lint.go index e179d830..25b4f1be 100644 --- a/src/cmd/tools/lint.go +++ b/src/cmd/tools/lint.go @@ -33,6 +33,7 @@ func init() { spinner := message.NewProgressSpinner("Linting %s", opts.InputFile) defer spinner.Stop() + // The ValidateCommand has some logging behavior that is not ideal for lula. validator, err := validate.ValidateCommand(opts.InputFile) if err != nil { fmt.Println(err) diff --git a/src/cmd/tools/upgrade.go b/src/cmd/tools/upgrade.go new file mode 100644 index 00000000..dc0f637f --- /dev/null +++ b/src/cmd/tools/upgrade.go @@ -0,0 +1,63 @@ +package tools + +import ( + "fmt" + + "github.com/defenseunicorns/go-oscal/src/cmd/revise" + "github.com/defenseunicorns/lula/src/config" + "github.com/defenseunicorns/lula/src/pkg/message" + "github.com/spf13/cobra" +) + +var upgradeHelp = ` +To Upgrade an existing OSCAL file: + lula tools upgrade -f -v +` + +type upgradeOptions struct { + revise.ReviseOptions +} + +var upgradeOpts upgradeOptions = upgradeOptions{} + +func init() { + upgradeCmd := &cobra.Command{ + Use: "upgrade", + Short: "Upgrade OSCAL document to a new version if possible", + PersistentPreRun: func(cmd *cobra.Command, args []string) { + config.SkipLogFile = true + }, + Long: "Validate an OSCAL document against the OSCAL schema version specified in the document. If the document is valid, upgrade it to the latest version of OSCAL. Otherwise, return an ValidationError.", + Example: upgradeHelp, + Run: func(cmd *cobra.Command, args []string) { + spinner := message.NewProgressSpinner("Upgrading %s to version %s", upgradeOpts.InputFile, upgradeOpts.Version) + defer spinner.Stop() + + if upgradeOpts.InputFile == "" { + message.Fatalf(nil, "No input file specified") + } + + // If no output file is specified, write to the input file + if upgradeOpts.OutputFile == "" { + upgradeOpts.OutputFile = upgradeOpts.InputFile + } + + // The Revise command has some logging behavior that is not ideal for lula. + revisor, err := revise.Revise(&upgradeOpts.ReviseOptions) + if err != nil { + fmt.Println(err) + message.Fatalf(err, "Failed to upgrade %s", upgradeOpts.InputFile) + } + + message.Infof("Successfully upgraded %s to OSCAL version %s %s\n", upgradeOpts.InputFile, revisor.GetSchemaVersion(), revisor.GetModelType()) + spinner.Success() + }, + } + + toolsCmd.AddCommand(upgradeCmd) + + upgradeCmd.Flags().StringVarP(&upgradeOpts.InputFile, "input-file", "f", "", "the path to a oscal json schema file") + upgradeCmd.Flags().StringVarP(&upgradeOpts.OutputFile, "output-file", "o", "", "the path to write the linted oscal json schema file") + upgradeCmd.Flags().StringVarP(&upgradeOpts.Version, "version", "v", "", "the version of the oscal schema to validate against") + upgradeCmd.Flags().StringVarP(&upgradeOpts.ValidationResult, "validation-result", "r", "", "the path to write the validation result file") +} From f05dc5b69c923663015320a62a4e54cf17dea8e1 Mon Sep 17 00:00:00 2001 From: mike-winberry Date: Wed, 6 Mar 2024 17:28:49 -0800 Subject: [PATCH 03/13] #281. Bump go-oscal to 0.2.3. Update upgrade.go using go-oscal utils to handle upgrading. Update .gitignore to ignore launch.json --- .gitignore | 3 +- go.mod | 4 +- go.sum | 4 ++ src/cmd/tools/upgrade.go | 83 ++++++++++++++++++++++++++++++++++------ 4 files changed, 80 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 2be3d9d6..348d6633 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ compliance_report-* out/ assessment-results-*.yaml .idea -.vscode/settings.json \ No newline at end of file +.vscode/settings.json +.vscode/launch.json \ No newline at end of file diff --git a/go.mod b/go.mod index b99ea1e6..4249dd85 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/defenseunicorns/lula go 1.22.0 require ( - github.com/defenseunicorns/go-oscal v0.2.2 + github.com/defenseunicorns/go-oscal v0.2.3 github.com/mitchellh/mapstructure v1.5.0 github.com/open-policy-agent/opa v0.62.0 github.com/pterm/pterm v0.12.79 @@ -94,7 +94,7 @@ require ( github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/swaggest/jsonschema-go v0.3.67 // indirect + github.com/swaggest/jsonschema-go v0.3.69 // indirect github.com/swaggest/refl v1.3.0 // indirect github.com/tchap/go-patricia/v2 v2.3.1 // indirect github.com/vladimirvivien/gexe v0.2.0 // indirect diff --git a/go.sum b/go.sum index acf033c5..a6f02e7f 100644 --- a/go.sum +++ b/go.sum @@ -63,6 +63,8 @@ github.com/defenseunicorns/go-oscal v0.2.0 h1:hyRMUoQT2RFk/VIxz19yZKngobjdIuI+si github.com/defenseunicorns/go-oscal v0.2.0/go.mod h1:4JXNIFmWK1VBHpmXicW/g65MizUEHKUexy3Lb2lH2/I= github.com/defenseunicorns/go-oscal v0.2.2 h1:JEXhNNRoVseDcH+Tlagf+MM8Y9nv5r7mPEHrAQIW7I0= github.com/defenseunicorns/go-oscal v0.2.2/go.mod h1:4JXNIFmWK1VBHpmXicW/g65MizUEHKUexy3Lb2lH2/I= +github.com/defenseunicorns/go-oscal v0.2.3 h1:3ZaP956g4Eh+SlthopUBAMglFmWKSMPdbkIhHqeoz+s= +github.com/defenseunicorns/go-oscal v0.2.3/go.mod h1:4JXNIFmWK1VBHpmXicW/g65MizUEHKUexy3Lb2lH2/I= github.com/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg= github.com/dgraph-io/badger/v3 v3.2103.5/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= @@ -309,6 +311,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/swaggest/jsonschema-go v0.3.67 h1:09tIfjZdeJW5ijK6ahkSpfVZv8Rj7tG3SLi/C/knj4c= github.com/swaggest/jsonschema-go v0.3.67/go.mod h1:7N43/CwdaWgPUDfYV70K7Qm79tRqe/al7gLSt9YeGIE= +github.com/swaggest/jsonschema-go v0.3.69 h1:BNEajhoQjnEQzxZqPmjD1Pcs1pxnjx/X9L5KWllLHxo= +github.com/swaggest/jsonschema-go v0.3.69/go.mod h1:7N43/CwdaWgPUDfYV70K7Qm79tRqe/al7gLSt9YeGIE= github.com/swaggest/refl v1.3.0 h1:PEUWIku+ZznYfsoyheF97ypSduvMApYyGkYF3nabS0I= github.com/swaggest/refl v1.3.0/go.mod h1:3Ujvbmh1pfSbDYjC6JGG7nMgPvpG0ehQL4iNonnLNbg= github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes= diff --git a/src/cmd/tools/upgrade.go b/src/cmd/tools/upgrade.go index dc0f637f..4d6394f5 100644 --- a/src/cmd/tools/upgrade.go +++ b/src/cmd/tools/upgrade.go @@ -1,9 +1,14 @@ package tools import ( - "fmt" + "os" + "strings" "github.com/defenseunicorns/go-oscal/src/cmd/revise" + "github.com/defenseunicorns/go-oscal/src/pkg/revision" + "github.com/defenseunicorns/go-oscal/src/pkg/utils" + goOscalUtils "github.com/defenseunicorns/go-oscal/src/pkg/utils" + "github.com/defenseunicorns/go-oscal/src/pkg/validation" "github.com/defenseunicorns/lula/src/config" "github.com/defenseunicorns/lula/src/pkg/message" "github.com/spf13/cobra" @@ -30,26 +35,82 @@ func init() { Long: "Validate an OSCAL document against the OSCAL schema version specified in the document. If the document is valid, upgrade it to the latest version of OSCAL. Otherwise, return an ValidationError.", Example: upgradeHelp, Run: func(cmd *cobra.Command, args []string) { - spinner := message.NewProgressSpinner("Upgrading %s to version %s", upgradeOpts.InputFile, upgradeOpts.Version) - defer spinner.Stop() - + // Check if the input file is specified and is a json or yaml file if upgradeOpts.InputFile == "" { message.Fatalf(nil, "No input file specified") + } else if err := goOscalUtils.IsJsonOrYaml(upgradeOpts.InputFile); err != nil { + message.Fatalf(err, "Invalid input file %s", upgradeOpts.InputFile) } // If no output file is specified, write to the input file if upgradeOpts.OutputFile == "" { upgradeOpts.OutputFile = upgradeOpts.InputFile + } else if err := goOscalUtils.IsJsonOrYaml(upgradeOpts.OutputFile); err != nil { + message.Fatalf(err, "Invalid output file %s", upgradeOpts.OutputFile) + } + + // Get the output file extension + split := strings.Split(upgradeOpts.OutputFile, ".") + outputExt := split[len(split)-1] + + // If no version is specified, use the latest supported version + if err := goOscalUtils.IsValidOscalVersion(upgradeOpts.Version); err != nil { + message.Fatalf(err, "Invalid version %s", upgradeOpts.Version) + } + + spinner := message.NewProgressSpinner("Upgrading %s to version %s", upgradeOpts.InputFile, upgradeOpts.Version) + defer spinner.Stop() + + // Read the input file + bytes, err := os.ReadFile(upgradeOpts.InputFile) + if err != nil { + message.Fatalf(err, "Failed to read %s", upgradeOpts.InputFile) + } + + // Create Upgrader + reviser, err := revision.NewReviser(bytes, upgradeOpts.Version) + if err != nil { + message.Fatalf(err, "Failed to create reviser") + } + + // Warn if the version is not the latest + version := reviser.GetSchemaVersion() + warning := utils.VersionWarning(version) + if warning != nil { + message.Warn(warning.Error()) + } + + reviser.SetDocumentPath(upgradeOpts.InputFile) + + // Upgrade the document + revisionError := reviser.Revise() + + // Write the validation result if it was specified and exists before handling the revision error + result, err := reviser.GetValidationResult() + if err == nil && upgradeOpts.ValidationResult != "" { + err = validation.WriteValidationResult(result, upgradeOpts.ValidationResult) + if err != nil { + message.Fatalf(err, "Failed to write the validation result to %s", upgradeOpts.ValidationResult) + } + } + + if revisionError != nil { + message.Fatalf(revisionError, "Failed to upgrade %s to OSCAL version %s", upgradeOpts.InputFile, upgradeOpts.Version) + } + + // Get the upgraded bytes + upgradeBytes, err := reviser.GetRevisedBytes(outputExt) + if err != nil { + message.Fatalf(err, "Failed to marshal the upgraded document") } - // The Revise command has some logging behavior that is not ideal for lula. - revisor, err := revise.Revise(&upgradeOpts.ReviseOptions) + // Write the upgraded document + err = goOscalUtils.WriteOutput(upgradeBytes, upgradeOpts.OutputFile) if err != nil { - fmt.Println(err) - message.Fatalf(err, "Failed to upgrade %s", upgradeOpts.InputFile) + message.Fatalf(err, "Failed to write the upgraded document to %s", upgradeOpts.OutputFile) } - message.Infof("Successfully upgraded %s to OSCAL version %s %s\n", upgradeOpts.InputFile, revisor.GetSchemaVersion(), revisor.GetModelType()) + message.Infof("Successfully upgraded %s to OSCAL version %s %s\n", upgradeOpts.InputFile, reviser.GetSchemaVersion(), reviser.GetModelType()) spinner.Success() }, } @@ -57,7 +118,7 @@ func init() { toolsCmd.AddCommand(upgradeCmd) upgradeCmd.Flags().StringVarP(&upgradeOpts.InputFile, "input-file", "f", "", "the path to a oscal json schema file") - upgradeCmd.Flags().StringVarP(&upgradeOpts.OutputFile, "output-file", "o", "", "the path to write the linted oscal json schema file") - upgradeCmd.Flags().StringVarP(&upgradeOpts.Version, "version", "v", "", "the version of the oscal schema to validate against") + upgradeCmd.Flags().StringVarP(&upgradeOpts.OutputFile, "output-file", "o", "", "the path to write the linted oscal json schema file (default is the input file)") + upgradeCmd.Flags().StringVarP(&upgradeOpts.Version, "version", "v", goOscalUtils.GetLatestSupportedVersion(), "the version of the oscal schema to validate against (default is the latest supported version)") upgradeCmd.Flags().StringVarP(&upgradeOpts.ValidationResult, "validation-result", "r", "", "the path to write the validation result file") } From aac4099b2fb1bff0e2d84dba0eab86f46a56eeb8 Mon Sep 17 00:00:00 2001 From: mike-winberry Date: Wed, 6 Mar 2024 17:33:32 -0800 Subject: [PATCH 04/13] #281. Rrename reviser to upgrader. --- src/cmd/tools/upgrade.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/cmd/tools/upgrade.go b/src/cmd/tools/upgrade.go index 4d6394f5..3c504583 100644 --- a/src/cmd/tools/upgrade.go +++ b/src/cmd/tools/upgrade.go @@ -68,25 +68,25 @@ func init() { } // Create Upgrader - reviser, err := revision.NewReviser(bytes, upgradeOpts.Version) + upgrader, err := revision.NewReviser(bytes, upgradeOpts.Version) if err != nil { message.Fatalf(err, "Failed to create reviser") } // Warn if the version is not the latest - version := reviser.GetSchemaVersion() + version := upgrader.GetSchemaVersion() warning := utils.VersionWarning(version) if warning != nil { message.Warn(warning.Error()) } - reviser.SetDocumentPath(upgradeOpts.InputFile) + upgrader.SetDocumentPath(upgradeOpts.InputFile) // Upgrade the document - revisionError := reviser.Revise() + revisionError := upgrader.Revise() // Write the validation result if it was specified and exists before handling the revision error - result, err := reviser.GetValidationResult() + result, err := upgrader.GetValidationResult() if err == nil && upgradeOpts.ValidationResult != "" { err = validation.WriteValidationResult(result, upgradeOpts.ValidationResult) if err != nil { @@ -94,23 +94,24 @@ func init() { } } + // Handle the revision error if revisionError != nil { message.Fatalf(revisionError, "Failed to upgrade %s to OSCAL version %s", upgradeOpts.InputFile, upgradeOpts.Version) } // Get the upgraded bytes - upgradeBytes, err := reviser.GetRevisedBytes(outputExt) + upgradedBytes, err := upgrader.GetRevisedBytes(outputExt) if err != nil { message.Fatalf(err, "Failed to marshal the upgraded document") } // Write the upgraded document - err = goOscalUtils.WriteOutput(upgradeBytes, upgradeOpts.OutputFile) + err = goOscalUtils.WriteOutput(upgradedBytes, upgradeOpts.OutputFile) if err != nil { message.Fatalf(err, "Failed to write the upgraded document to %s", upgradeOpts.OutputFile) } - message.Infof("Successfully upgraded %s to OSCAL version %s %s\n", upgradeOpts.InputFile, reviser.GetSchemaVersion(), reviser.GetModelType()) + message.Infof("Successfully upgraded %s to OSCAL version %s %s\n", upgradeOpts.InputFile, upgrader.GetSchemaVersion(), upgrader.GetModelType()) spinner.Success() }, } From 2f1471d4a12c47719b84217f7d4656bb22256fab Mon Sep 17 00:00:00 2001 From: mike-winberry Date: Wed, 6 Mar 2024 17:42:23 -0800 Subject: [PATCH 05/13] #281. Update upgrade command long message --- src/cmd/tools/upgrade.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd/tools/upgrade.go b/src/cmd/tools/upgrade.go index 3c504583..f354c558 100644 --- a/src/cmd/tools/upgrade.go +++ b/src/cmd/tools/upgrade.go @@ -32,7 +32,7 @@ func init() { PersistentPreRun: func(cmd *cobra.Command, args []string) { config.SkipLogFile = true }, - Long: "Validate an OSCAL document against the OSCAL schema version specified in the document. If the document is valid, upgrade it to the latest version of OSCAL. Otherwise, return an ValidationError.", + Long: "Validate an OSCAL document against the OSCAL schema version provided. If the document is valid, upgrade it to the provided OSCAL version. Otherwise, return an ValidationError.", Example: upgradeHelp, Run: func(cmd *cobra.Command, args []string) { // Check if the input file is specified and is a json or yaml file From 859b2954aa08e36389dab75de78e7b800d8c2e1b Mon Sep 17 00:00:00 2001 From: mike-winberry Date: Wed, 6 Mar 2024 17:43:06 -0800 Subject: [PATCH 06/13] #281. Update upgrade command long message --- src/cmd/tools/upgrade.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd/tools/upgrade.go b/src/cmd/tools/upgrade.go index f354c558..dc95c540 100644 --- a/src/cmd/tools/upgrade.go +++ b/src/cmd/tools/upgrade.go @@ -32,7 +32,7 @@ func init() { PersistentPreRun: func(cmd *cobra.Command, args []string) { config.SkipLogFile = true }, - Long: "Validate an OSCAL document against the OSCAL schema version provided. If the document is valid, upgrade it to the provided OSCAL version. Otherwise, return an ValidationError.", + Long: "Validate an OSCAL document against the OSCAL schema version provided. If the document is valid, upgrade it to the provided OSCAL version. Otherwise, return or write as ValidationError.", Example: upgradeHelp, Run: func(cmd *cobra.Command, args []string) { // Check if the input file is specified and is a json or yaml file From a338609b75ee10708d88ad116cc4deca64cf001a Mon Sep 17 00:00:00 2001 From: mike-winberry Date: Fri, 8 Mar 2024 17:04:38 -0800 Subject: [PATCH 07/13] #281 Update go-oscal to v0.2.5. Update all references to ValidateCommand to match new return values. Update upgrade command to use the new RevisionCommand from go-oscal --- go.mod | 2 +- go.sum | 2 + src/cmd/tools/lint.go | 6 +-- src/cmd/tools/upgrade.go | 80 ++++------------------------- src/test/e2e/pod_validation_test.go | 6 +-- 5 files changed, 20 insertions(+), 76 deletions(-) diff --git a/go.mod b/go.mod index 4249dd85..08932557 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/defenseunicorns/lula go 1.22.0 require ( - github.com/defenseunicorns/go-oscal v0.2.3 + github.com/defenseunicorns/go-oscal v0.2.5 github.com/mitchellh/mapstructure v1.5.0 github.com/open-policy-agent/opa v0.62.0 github.com/pterm/pterm v0.12.79 diff --git a/go.sum b/go.sum index a6f02e7f..7190589e 100644 --- a/go.sum +++ b/go.sum @@ -65,6 +65,8 @@ github.com/defenseunicorns/go-oscal v0.2.2 h1:JEXhNNRoVseDcH+Tlagf+MM8Y9nv5r7mPE github.com/defenseunicorns/go-oscal v0.2.2/go.mod h1:4JXNIFmWK1VBHpmXicW/g65MizUEHKUexy3Lb2lH2/I= github.com/defenseunicorns/go-oscal v0.2.3 h1:3ZaP956g4Eh+SlthopUBAMglFmWKSMPdbkIhHqeoz+s= github.com/defenseunicorns/go-oscal v0.2.3/go.mod h1:4JXNIFmWK1VBHpmXicW/g65MizUEHKUexy3Lb2lH2/I= +github.com/defenseunicorns/go-oscal v0.2.5 h1:r8A2sXz/VTjVIf4Er/WyDSTyqUteek5AHeKEAT2XzTU= +github.com/defenseunicorns/go-oscal v0.2.5/go.mod h1:4JXNIFmWK1VBHpmXicW/g65MizUEHKUexy3Lb2lH2/I= github.com/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg= github.com/dgraph-io/badger/v3 v3.2103.5/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= diff --git a/src/cmd/tools/lint.go b/src/cmd/tools/lint.go index 25b4f1be..2556883e 100644 --- a/src/cmd/tools/lint.go +++ b/src/cmd/tools/lint.go @@ -3,7 +3,7 @@ package tools import ( "fmt" - "github.com/defenseunicorns/go-oscal/src/cmd/validate" + "github.com/defenseunicorns/go-oscal/src/pkg/validation" "github.com/defenseunicorns/lula/src/config" "github.com/defenseunicorns/lula/src/pkg/message" "github.com/spf13/cobra" @@ -34,12 +34,12 @@ func init() { defer spinner.Stop() // The ValidateCommand has some logging behavior that is not ideal for lula. - validator, err := validate.ValidateCommand(opts.InputFile) + validationResp, err := validation.ValidationCommand(opts.InputFile) if err != nil { fmt.Println(err) message.Fatalf(err, "Failed to lint %s", opts.InputFile) } - message.Infof("Successfully validated %s is valid OSCAL version %s %s\n", opts.InputFile, validator.GetSchemaVersion(), validator.GetModelType()) + message.Infof("Successfully validated %s is valid OSCAL version %s %s\n", opts.InputFile, validationResp.Validator.GetSchemaVersion(), validationResp.Validator.GetModelType()) spinner.Success() }, } diff --git a/src/cmd/tools/upgrade.go b/src/cmd/tools/upgrade.go index dc95c540..8a7ff460 100644 --- a/src/cmd/tools/upgrade.go +++ b/src/cmd/tools/upgrade.go @@ -1,12 +1,7 @@ package tools import ( - "os" - "strings" - - "github.com/defenseunicorns/go-oscal/src/cmd/revise" "github.com/defenseunicorns/go-oscal/src/pkg/revision" - "github.com/defenseunicorns/go-oscal/src/pkg/utils" goOscalUtils "github.com/defenseunicorns/go-oscal/src/pkg/utils" "github.com/defenseunicorns/go-oscal/src/pkg/validation" "github.com/defenseunicorns/lula/src/config" @@ -20,7 +15,7 @@ To Upgrade an existing OSCAL file: ` type upgradeOptions struct { - revise.ReviseOptions + revision.RevisionOptions } var upgradeOpts upgradeOptions = upgradeOptions{} @@ -35,83 +30,30 @@ func init() { Long: "Validate an OSCAL document against the OSCAL schema version provided. If the document is valid, upgrade it to the provided OSCAL version. Otherwise, return or write as ValidationError.", Example: upgradeHelp, Run: func(cmd *cobra.Command, args []string) { - // Check if the input file is specified and is a json or yaml file - if upgradeOpts.InputFile == "" { - message.Fatalf(nil, "No input file specified") - } else if err := goOscalUtils.IsJsonOrYaml(upgradeOpts.InputFile); err != nil { - message.Fatalf(err, "Invalid input file %s", upgradeOpts.InputFile) - } + spinner := message.NewProgressSpinner("Upgrading %s to version %s", upgradeOpts.InputFile, upgradeOpts.Version) + defer spinner.Stop() // If no output file is specified, write to the input file if upgradeOpts.OutputFile == "" { upgradeOpts.OutputFile = upgradeOpts.InputFile - } else if err := goOscalUtils.IsJsonOrYaml(upgradeOpts.OutputFile); err != nil { - message.Fatalf(err, "Invalid output file %s", upgradeOpts.OutputFile) - } - - // Get the output file extension - split := strings.Split(upgradeOpts.OutputFile, ".") - outputExt := split[len(split)-1] - - // If no version is specified, use the latest supported version - if err := goOscalUtils.IsValidOscalVersion(upgradeOpts.Version); err != nil { - message.Fatalf(err, "Invalid version %s", upgradeOpts.Version) } - spinner := message.NewProgressSpinner("Upgrading %s to version %s", upgradeOpts.InputFile, upgradeOpts.Version) - defer spinner.Stop() + revisionResponse, err := revision.RevisionCommand(&upgradeOpts.RevisionOptions) - // Read the input file - bytes, err := os.ReadFile(upgradeOpts.InputFile) - if err != nil { - message.Fatalf(err, "Failed to read %s", upgradeOpts.InputFile) + if upgradeOpts.ValidationResult != "" { + validation.WriteValidationResult(revisionResponse.Result, upgradeOpts.ValidationResult) } - // Create Upgrader - upgrader, err := revision.NewReviser(bytes, upgradeOpts.Version) - if err != nil { - message.Fatalf(err, "Failed to create reviser") - } - - // Warn if the version is not the latest - version := upgrader.GetSchemaVersion() - warning := utils.VersionWarning(version) - if warning != nil { - message.Warn(warning.Error()) - } - - upgrader.SetDocumentPath(upgradeOpts.InputFile) - - // Upgrade the document - revisionError := upgrader.Revise() - - // Write the validation result if it was specified and exists before handling the revision error - result, err := upgrader.GetValidationResult() - if err == nil && upgradeOpts.ValidationResult != "" { - err = validation.WriteValidationResult(result, upgradeOpts.ValidationResult) - if err != nil { - message.Fatalf(err, "Failed to write the validation result to %s", upgradeOpts.ValidationResult) + if len(revisionResponse.Warnings) > 0 { + for _, warning := range revisionResponse.Warnings { + message.Warn(warning) } } - // Handle the revision error - if revisionError != nil { - message.Fatalf(revisionError, "Failed to upgrade %s to OSCAL version %s", upgradeOpts.InputFile, upgradeOpts.Version) - } - - // Get the upgraded bytes - upgradedBytes, err := upgrader.GetRevisedBytes(outputExt) if err != nil { - message.Fatalf(err, "Failed to marshal the upgraded document") + message.Fatalf(err, "Failed to upgrade %s to OSCAL version %s %s", upgradeOpts.InputFile, revisionResponse.Reviser.GetSchemaVersion(), revisionResponse.Reviser.GetModelType()) } - - // Write the upgraded document - err = goOscalUtils.WriteOutput(upgradedBytes, upgradeOpts.OutputFile) - if err != nil { - message.Fatalf(err, "Failed to write the upgraded document to %s", upgradeOpts.OutputFile) - } - - message.Infof("Successfully upgraded %s to OSCAL version %s %s\n", upgradeOpts.InputFile, upgrader.GetSchemaVersion(), upgrader.GetModelType()) + message.Infof("Successfully upgraded %s to OSCAL version %s %s\n", upgradeOpts.InputFile, revisionResponse.Reviser.GetSchemaVersion(), revisionResponse.Reviser.GetModelType()) spinner.Success() }, } diff --git a/src/test/e2e/pod_validation_test.go b/src/test/e2e/pod_validation_test.go index 4157fade..fd56bbe2 100644 --- a/src/test/e2e/pod_validation_test.go +++ b/src/test/e2e/pod_validation_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - validator "github.com/defenseunicorns/go-oscal/src/cmd/validate" + "github.com/defenseunicorns/go-oscal/src/pkg/validation" "github.com/defenseunicorns/lula/src/cmd/validate" "github.com/defenseunicorns/lula/src/pkg/common/oscal" "github.com/defenseunicorns/lula/src/pkg/message" @@ -91,11 +91,11 @@ func TestPodLabelValidation(t *testing.T) { t.Fatal("Failed to append results to existing report") } - validator, err := validator.ValidateCommand("sar-test.yaml") + validatorResponse, err := validation.ValidationCommand("sar-test.yaml") if err != nil { t.Fatal("File failed linting") } - message.Infof("Successfully validated %s is valid OSCAL version %s %s\n", "sar-test.yaml", validator.GetSchemaVersion(), validator.GetModelType()) + message.Infof("Successfully validated %s is valid OSCAL version %s %s\n", "sar-test.yaml", validatorResponse.Validator.GetSchemaVersion(), validatorResponse.Validator.GetModelType()) return ctx }). From d3bb4d4f495e6bb9c8748b054023079797bd3ee8 Mon Sep 17 00:00:00 2001 From: mike-winberry Date: Fri, 8 Mar 2024 17:28:53 -0800 Subject: [PATCH 08/13] #281. Update pod_validation_test w/ upgrade test --- src/test/e2e/pod_validation_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test/e2e/pod_validation_test.go b/src/test/e2e/pod_validation_test.go index fd56bbe2..e22e2b56 100644 --- a/src/test/e2e/pod_validation_test.go +++ b/src/test/e2e/pod_validation_test.go @@ -6,6 +6,7 @@ import ( "testing" "time" + "github.com/defenseunicorns/go-oscal/src/pkg/revision" "github.com/defenseunicorns/go-oscal/src/pkg/validation" "github.com/defenseunicorns/lula/src/cmd/validate" "github.com/defenseunicorns/lula/src/pkg/common/oscal" @@ -91,6 +92,15 @@ func TestPodLabelValidation(t *testing.T) { t.Fatal("Failed to append results to existing report") } + revisionOptions := revision.RevisionOptions{ + InputFile: "sar-test.yaml", + } + revisionResponse, err := revision.RevisionCommand(&revisionOptions) + if err != nil { + t.Fatal("file failed to upgrade") + } + message.Infof("Successfully upgraded %s to OSCAL version %s %s\n", "sar-test.yaml", revisionResponse.Reviser.GetSchemaVersion(), revisionResponse.Reviser.GetModelType()) + validatorResponse, err := validation.ValidationCommand("sar-test.yaml") if err != nil { t.Fatal("File failed linting") From a7813bc4fb0a5126637e716003a146e37af7edf6 Mon Sep 17 00:00:00 2001 From: mike-winberry Date: Sat, 9 Mar 2024 08:19:58 -0800 Subject: [PATCH 09/13] #281. Fix missing fields in pod_validation_test revision --- src/test/e2e/pod_validation_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/test/e2e/pod_validation_test.go b/src/test/e2e/pod_validation_test.go index e22e2b56..7803551c 100644 --- a/src/test/e2e/pod_validation_test.go +++ b/src/test/e2e/pod_validation_test.go @@ -17,6 +17,8 @@ import ( "sigs.k8s.io/e2e-framework/klient/wait/conditions" "sigs.k8s.io/e2e-framework/pkg/envconf" "sigs.k8s.io/e2e-framework/pkg/features" + + gooscalUtils "github.com/defenseunicorns/go-oscal/src/pkg/utils" ) func TestPodLabelValidation(t *testing.T) { @@ -93,7 +95,9 @@ func TestPodLabelValidation(t *testing.T) { } revisionOptions := revision.RevisionOptions{ - InputFile: "sar-test.yaml", + InputFile: "sar-test.yaml", + OutputFile: "sar-test.yaml", + Version: gooscalUtils.GetLatestSupportedVersion(), } revisionResponse, err := revision.RevisionCommand(&revisionOptions) if err != nil { From dbe78f24fbc42ac710821d4b10442eb3cff3e0e9 Mon Sep 17 00:00:00 2001 From: mike-winberry Date: Sat, 9 Mar 2024 08:26:52 -0800 Subject: [PATCH 10/13] #281. Update long message of upgradeCmd to conain disclaimer for yaml formatting visually changing, but maintaining object equality. --- src/cmd/tools/upgrade.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cmd/tools/upgrade.go b/src/cmd/tools/upgrade.go index 8a7ff460..690522bf 100644 --- a/src/cmd/tools/upgrade.go +++ b/src/cmd/tools/upgrade.go @@ -23,11 +23,11 @@ var upgradeOpts upgradeOptions = upgradeOptions{} func init() { upgradeCmd := &cobra.Command{ Use: "upgrade", - Short: "Upgrade OSCAL document to a new version if possible", + Short: "Upgrade OSCAL document to a new version if possible.", PersistentPreRun: func(cmd *cobra.Command, args []string) { config.SkipLogFile = true }, - Long: "Validate an OSCAL document against the OSCAL schema version provided. If the document is valid, upgrade it to the provided OSCAL version. Otherwise, return or write as ValidationError.", + Long: "Validate an OSCAL document against the OSCAL schema version provided. If the document is valid, upgrade it to the provided OSCAL version. Otherwise, return or write as ValidationError. Yaml formatting handled by gopkg/yaml.v3 and while objects will maintain deep equality, visual representation may be different than the input file.", Example: upgradeHelp, Run: func(cmd *cobra.Command, args []string) { spinner := message.NewProgressSpinner("Upgrading %s to version %s", upgradeOpts.InputFile, upgradeOpts.Version) From bc94c9ee4917f82f37c012beba1b0183338768a0 Mon Sep 17 00:00:00 2001 From: mike-winberry Date: Tue, 12 Mar 2024 09:49:43 -0700 Subject: [PATCH 11/13] #281. Update lint to properly output messages and warnings, added the -r ResultFile optional param for the output of the ValidationResult file. Update pod_validation_test to upgrade the component-definition to a temp file and then use that temp file to run the assess tests, updated the associated oscal-component.yaml to pass linting. --- src/cmd/tools/lint.go | 17 +- src/test/e2e/pod_validation_test.go | 31 ++-- .../scenarios/pod-label/oscal-component.yaml | 173 +++++++++--------- 3 files changed, 117 insertions(+), 104 deletions(-) diff --git a/src/cmd/tools/lint.go b/src/cmd/tools/lint.go index 2556883e..740a14c8 100644 --- a/src/cmd/tools/lint.go +++ b/src/cmd/tools/lint.go @@ -1,8 +1,6 @@ package tools import ( - "fmt" - "github.com/defenseunicorns/go-oscal/src/pkg/validation" "github.com/defenseunicorns/lula/src/config" "github.com/defenseunicorns/lula/src/pkg/message" @@ -10,7 +8,8 @@ import ( ) type flags struct { - InputFile string // -f --input-file + InputFile string // -f --input-file + ResultFile string // -r --result-file } var opts = &flags{} @@ -33,10 +32,17 @@ func init() { spinner := message.NewProgressSpinner("Linting %s", opts.InputFile) defer spinner.Stop() - // The ValidateCommand has some logging behavior that is not ideal for lula. validationResp, err := validation.ValidationCommand(opts.InputFile) + + for _, warning := range validationResp.Warnings { + message.Warn(warning) + } + + if opts.ResultFile != "" { + validation.WriteValidationResult(validationResp.Result, opts.ResultFile) + } + if err != nil { - fmt.Println(err) message.Fatalf(err, "Failed to lint %s", opts.InputFile) } message.Infof("Successfully validated %s is valid OSCAL version %s %s\n", opts.InputFile, validationResp.Validator.GetSchemaVersion(), validationResp.Validator.GetModelType()) @@ -47,4 +53,5 @@ func init() { toolsCmd.AddCommand(lintCmd) lintCmd.Flags().StringVarP(&opts.InputFile, "input-file", "f", "", "the path to a oscal json schema file") + lintCmd.Flags().StringVarP(&opts.ResultFile, "result-file", "r", "", "the path to write the validation result") } diff --git a/src/test/e2e/pod_validation_test.go b/src/test/e2e/pod_validation_test.go index 7803551c..32ac9cbc 100644 --- a/src/test/e2e/pod_validation_test.go +++ b/src/test/e2e/pod_validation_test.go @@ -41,7 +41,25 @@ func TestPodLabelValidation(t *testing.T) { oscalPath := "./scenarios/pod-label/oscal-component.yaml" message.NoProgress = true - findingMap, observations, err := validate.ValidateOnPath(oscalPath) + tempDir := t.TempDir() + + // Upgrade the component definition to latest osscal version + revisionOptions := revision.RevisionOptions{ + InputFile: oscalPath, + OutputFile: tempDir + "/oscal-component-upgraded.yaml", + Version: gooscalUtils.GetLatestSupportedVersion(), + } + revisionResponse, err := revision.RevisionCommand(&revisionOptions) + if err != nil { + t.Fatal("Failed to upgrade component definition with: ", err) + } + err = gooscalUtils.WriteOutput(revisionResponse.RevisedBytes, revisionOptions.OutputFile) + if err != nil { + t.Fatal("Failed to write upgraded component definition with: ", err) + } + message.Infof("Successfully upgraded %s to OSCAL version %s %s\n", oscalPath, revisionResponse.Reviser.GetSchemaVersion(), revisionResponse.Reviser.GetModelType()) + + findingMap, observations, err := validate.ValidateOnPath(revisionOptions.OutputFile) if err != nil { t.Fatal(err) } @@ -94,17 +112,6 @@ func TestPodLabelValidation(t *testing.T) { t.Fatal("Failed to append results to existing report") } - revisionOptions := revision.RevisionOptions{ - InputFile: "sar-test.yaml", - OutputFile: "sar-test.yaml", - Version: gooscalUtils.GetLatestSupportedVersion(), - } - revisionResponse, err := revision.RevisionCommand(&revisionOptions) - if err != nil { - t.Fatal("file failed to upgrade") - } - message.Infof("Successfully upgraded %s to OSCAL version %s %s\n", "sar-test.yaml", revisionResponse.Reviser.GetSchemaVersion(), revisionResponse.Reviser.GetModelType()) - validatorResponse, err := validation.ValidationCommand("sar-test.yaml") if err != nil { t.Fatal("File failed linting") diff --git a/src/test/e2e/scenarios/pod-label/oscal-component.yaml b/src/test/e2e/scenarios/pod-label/oscal-component.yaml index 68577219..4a5db6a3 100644 --- a/src/test/e2e/scenarios/pod-label/oscal-component.yaml +++ b/src/test/e2e/scenarios/pod-label/oscal-component.yaml @@ -3,100 +3,99 @@ component-definition: uuid: E6A291A4-2BC8-43A0-B4B2-FD67CAAE1F8F metadata: title: OSCAL Demo Tool - last-modified: '2022-09-13T12:00:00Z' + last-modified: "2022-09-13T12:00:00Z" version: "20220913" oscal-version: 1.1.1 parties: # Should be consistent across all of the packages, but where is ground truth? - - uuid: C18F4A9F-A402-415B-8D13-B51739D689FF - type: organization - name: Defense Unicorns - links: - - href: - rel: website - components: - - uuid: A9D5204C-7E5B-4C43-BD49-34DF759B9F04 - type: software - title: lula - description: | - Defense Unicorns lula - purpose: Validate compliance controls - responsible-roles: - - role-id: provider - party-uuids: - - C18F4A9F-A402-415B-8D13-B51739D689FF # matches parties entry for Defense Unicorns - control-implementations: - - uuid: A584FEDC-8CEA-4B0C-9F07-85C2C4AE751A - source: # Link to generic security document - description: - Validate generic security requirements - implemented-requirements: - - uuid: 42C2FFDC-5F05-44DF-A67F-EEC8660AEFFD - control-id: ID-1 - description: >- - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, - quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum - dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + - uuid: C18F4A9F-A402-415B-8D13-B51739D689FF + type: organization + name: Defense Unicorns links: - - href: '#88AB3470-B96B-4D7C-BC36-02BF9563C46C' - rel: reference - text: Lula Validation - - uuid: 86a0e8d9-0ce0-4304-afe7-4c000001e032 - control-id: ID-2 - description: >- - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, - quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum - dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - links: - - href: '#01e21994-2cfc-45fb-ac84-d00f2e5912b0' - rel: reference - text: Lula Validation - back-matter: + - href: https://github.com/defenseunicorns/lula + rel: website + components: + - uuid: A9D5204C-7E5B-4C43-BD49-34DF759B9F04 + type: software + title: lula + description: | + Defense Unicorns lula + purpose: Validate compliance controls + responsible-roles: + - role-id: provider + party-uuids: + - C18F4A9F-A402-415B-8D13-B51739D689FF # matches parties entry for Defense Unicorns + control-implementations: + - uuid: A584FEDC-8CEA-4B0C-9F07-85C2C4AE751A + source: https://github.com/defenseunicorns/lula # Link to generic security document + description: Validate generic security requirements + implemented-requirements: + - uuid: 42C2FFDC-5F05-44DF-A67F-EEC8660AEFFD + control-id: ID-1 + description: >- + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum + dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + links: + - href: "#88AB3470-B96B-4D7C-BC36-02BF9563C46C" + rel: reference + text: Lula Validation + - uuid: 86a0e8d9-0ce0-4304-afe7-4c000001e032 + control-id: ID-2 + description: >- + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum + dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + links: + - href: "#01e21994-2cfc-45fb-ac84-d00f2e5912b0" + rel: reference + text: Lula Validation + back-matter: resources: - - uuid: 88AB3470-B96B-4D7C-BC36-02BF9563C46C - title: Lula Validation - description: >- - target: - provider: opa - domain: kubernetes - payload: - resources: - - name: podsvt - resourceRule: - Group: - Version: v1 - Resource: pods - Namespaces: [validation-test] - rego: | - package validate + - uuid: 88AB3470-B96B-4D7C-BC36-02BF9563C46C + title: Lula Validation + description: >- + target: + provider: opa + domain: kubernetes + payload: + resources: + - name: podsvt + resourceRule: + Group: + Version: v1 + Resource: pods + Namespaces: [validation-test] + rego: | + package validate - import future.keywords.every + import future.keywords.every - validate { - every pod in input.podsvt { - podLabel := pod.metadata.labels.foo - podLabel == "bar" + validate { + every pod in input.podsvt { + podLabel := pod.metadata.labels.foo + podLabel == "bar" + } } - } - - uuid: 01e21994-2cfc-45fb-ac84-d00f2e5912b0 - title: Lula Validation - description: >- - target: - provider: opa - domain: kubernetes - payload: - resources: - - name: podvt - resourceRule: - Name: test-pod-label - Group: - Version: v1 - Resource: pods - Namespaces: [validation-test] - rego: | - package validate + - uuid: 01e21994-2cfc-45fb-ac84-d00f2e5912b0 + title: Lula Validation + description: >- + target: + provider: opa + domain: kubernetes + payload: + resources: + - name: podvt + resourceRule: + Name: test-pod-label + Group: + Version: v1 + Resource: pods + Namespaces: [validation-test] + rego: | + package validate - validate { - podLabel := input.podvt.metadata.labels.foo - podLabel == "bar" - } \ No newline at end of file + validate { + podLabel := input.podvt.metadata.labels.foo + podLabel == "bar" + } From ff1852bd4e3d551691a9130df481ed7ea803d966 Mon Sep 17 00:00:00 2001 From: mike-winberry Date: Tue, 12 Mar 2024 09:53:52 -0700 Subject: [PATCH 12/13] clean up --- src/test/e2e/pod_validation_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/e2e/pod_validation_test.go b/src/test/e2e/pod_validation_test.go index 32ac9cbc..72dcd9f9 100644 --- a/src/test/e2e/pod_validation_test.go +++ b/src/test/e2e/pod_validation_test.go @@ -53,11 +53,12 @@ func TestPodLabelValidation(t *testing.T) { if err != nil { t.Fatal("Failed to upgrade component definition with: ", err) } + // Write the upgraded component definition to a temp file err = gooscalUtils.WriteOutput(revisionResponse.RevisedBytes, revisionOptions.OutputFile) if err != nil { t.Fatal("Failed to write upgraded component definition with: ", err) } - message.Infof("Successfully upgraded %s to OSCAL version %s %s\n", oscalPath, revisionResponse.Reviser.GetSchemaVersion(), revisionResponse.Reviser.GetModelType()) + message.Infof("Successfully upgraded %s to %s with OSCAL version %s %s\n", oscalPath, revisionOptions.OutputFile, revisionResponse.Reviser.GetSchemaVersion(), revisionResponse.Reviser.GetModelType()) findingMap, observations, err := validate.ValidateOnPath(revisionOptions.OutputFile) if err != nil { From da008b1b8c35b4b1b02c76943c29a4217a849bec Mon Sep 17 00:00:00 2001 From: mike-winberry Date: Tue, 12 Mar 2024 13:27:47 -0700 Subject: [PATCH 13/13] #281. Fix output not being written after upgrade command executes. --- src/cmd/tools/upgrade.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cmd/tools/upgrade.go b/src/cmd/tools/upgrade.go index 690522bf..69109f21 100644 --- a/src/cmd/tools/upgrade.go +++ b/src/cmd/tools/upgrade.go @@ -50,6 +50,11 @@ func init() { } } + err = goOscalUtils.WriteOutput(revisionResponse.RevisedBytes, upgradeOpts.OutputFile) + if err != nil { + message.Fatalf(err, "Failed to write upgraded %s with: %s", upgradeOpts.OutputFile, err) + } + if err != nil { message.Fatalf(err, "Failed to upgrade %s to OSCAL version %s %s", upgradeOpts.InputFile, revisionResponse.Reviser.GetSchemaVersion(), revisionResponse.Reviser.GetModelType()) }