-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(generate): support for profile model and basic generation (#694)
* feat(generate): support for profile model and basic generation * feat(profile): further refine the profile model abstraction * feat(generate): profile model unit tests * fix(generation): fix complete model tests * fix(profile): working in the mode interface * fix(profile): support for profile instantiation * feat(generate): add testing for generate profile * fix(generate): cleanup and generate cli docs * fix(docs): fix typo in cli generated docs * fix(generate): update comments * fix(generate): cleanup other logic and comments * fix(generation): update docs, cleanup, deduplicate * fix(generate): move profile to separate file * fix(generation): support for merging profiles and replacing imports * feat(generate): support for includeall in the import * fix(generate): update golden test * fix(generate): cover edge case for no specified options * fix(oscal): fix improperly named import type * fix(generation): resolve gosec findings
- Loading branch information
1 parent
41bce03
commit cb4fc6f
Showing
22 changed files
with
951 additions
and
100 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
--- | ||
title: lula generate profile | ||
description: Lula CLI command reference for <code>lula generate profile</code>. | ||
type: docs | ||
--- | ||
## lula generate profile | ||
|
||
Generate a profile OSCAL template | ||
|
||
### Synopsis | ||
|
||
Generation of a Profile OSCAL artifact with controls included or excluded from a source catalog/profile. | ||
|
||
``` | ||
lula generate profile [flags] | ||
``` | ||
|
||
### Examples | ||
|
||
``` | ||
To generate a profile with included controls: | ||
lula generate profile -s <catalog/profile source> -i ac-1,ac-2,ac-3 | ||
To specify the name and filetype of the generated artifact: | ||
lula generate profile -s <catalog/profile source> -i ac-1,ac-2,ac-3 -o my_profile.yaml | ||
To generate a profile that includes all controls except a list specified controls: | ||
lula generate profile -s <catalog/profile source> -e ac-1,ac-2,ac-3 | ||
``` | ||
|
||
### Options | ||
|
||
``` | ||
-a, --all Include all controls from the source catalog/profile | ||
-e, --exclude strings comma delimited list of controls to exclude from the source catalog/profile | ||
-h, --help help for profile | ||
-i, --include strings comma delimited list of controls to include from the source catalog/profile | ||
-o, --output-file string the path to the output file. If not specified, the output file will be directed to stdout | ||
-s, --source string the path to the source catalog/profile | ||
``` | ||
|
||
### Options inherited from parent commands | ||
|
||
``` | ||
-f, --input-file string Path to a manifest file | ||
-l, --log-level string Log level when running Lula. Valid options are: warn, info, debug, trace (default "info") | ||
``` | ||
|
||
### SEE ALSO | ||
|
||
* [lula generate](./lula_generate.md) - Generate a specified compliance artifact template | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Profile | ||
|
||
A [Profile](https://pages.nist.gov/OSCAL/resources/concepts/layer/control/profile/) is an OSCAL model for capturing a baseline of selected controls from one or more catalogs or profiles. In lula, the profile model is available for generation and use as a source to other models that allow for specification of a profile or catalog which represents the source of truth for relevant security controls or other organizational policies. | ||
|
||
## Structure | ||
|
||
The primary structure for the Lula production and operations of the `profile` model for determinism is as follows: | ||
- Imports are sorted by `href` in ascending order | ||
- WithIds are sorted by the associated string id in ascending order | ||
- Back Matter Resources are sorted by `title` in ascending order (Case Sensitive Sorting). | ||
|
||
### Reproducibility | ||
|
||
The `lula generate` commands are meant to be reproducible. The intent for this generation is to make it easy to update a given model with automation and only inject human intervention as needed. | ||
|
||
For profiles, see the metadata props for the `generation` prop. It should look like the following: | ||
```yaml | ||
props: | ||
- name: generation | ||
ns: https://docs.lula.dev/oscal/ns | ||
value: lula generate profile --source catalog.yaml --include ac-1,ac-2,ac-3 | ||
``` | ||
>[!NOTE] | ||
>The controls specified for inclusion or exclusion during the generation command are not currently validated to exist in the source artifact. | ||
## Example | ||
```bash | ||
lula generate profile -s catalog.yaml -i ac-1,ac-2,ac-3 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package generate | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/defenseunicorns/lula/src/pkg/common/oscal" | ||
"github.com/defenseunicorns/lula/src/pkg/message" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
var profileExample = ` | ||
To generate a profile with included controls: | ||
lula generate profile -s <catalog/profile source> -i ac-1,ac-2,ac-3 | ||
To specify the name and filetype of the generated artifact: | ||
lula generate profile -s <catalog/profile source> -i ac-1,ac-2,ac-3 -o my_profile.yaml | ||
To generate a profile that includes all controls except a list specified controls: | ||
lula generate profile -s <catalog/profile source> -e ac-1,ac-2,ac-3 | ||
` | ||
|
||
var profileLong = `Generation of a Profile OSCAL artifact with controls included or excluded from a source catalog/profile.` | ||
|
||
func GenerateProfileCommand() *cobra.Command { | ||
var ( | ||
source string | ||
outputFile string | ||
include []string | ||
exclude []string | ||
all bool | ||
) | ||
|
||
profilecmd := &cobra.Command{ | ||
Use: "profile", | ||
Aliases: []string{"p"}, | ||
Args: cobra.MaximumNArgs(1), | ||
Short: "Generate a profile OSCAL template", | ||
Long: profileLong, | ||
Example: profileExample, | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
message.Info("generate profile executed") | ||
|
||
if outputFile == "" { | ||
outputFile = "profile.yaml" | ||
} | ||
|
||
/// Check if output file contains a valid OSCAL model | ||
_, err := oscal.ValidOSCALModelAtPath(outputFile) | ||
if err != nil { | ||
return fmt.Errorf("invalid OSCAL model at output: %v", err) | ||
} | ||
|
||
command := fmt.Sprintf("%s --source %s", cmd.CommandPath(), source) | ||
|
||
if len(include) > 0 { | ||
command += fmt.Sprintf(" --include %s", strings.Join(include, ",")) | ||
} | ||
|
||
if len(exclude) > 0 { | ||
command += fmt.Sprintf(" --exclude %s", strings.Join(exclude, ",")) | ||
} | ||
|
||
if all { | ||
command += " --all" | ||
} | ||
|
||
profile, err := oscal.GenerateProfile(command, source, include, exclude, all) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Write the component definition to file | ||
err = oscal.WriteOscalModelNew(outputFile, profile) | ||
if err != nil { | ||
message.Fatalf(err, "error writing component to file") | ||
} | ||
|
||
return nil | ||
}, | ||
} | ||
|
||
profilecmd.Flags().StringVarP(&source, "source", "s", "", "the path to the source catalog/profile") | ||
err := profilecmd.MarkFlagRequired("source") | ||
if err != nil { | ||
message.Fatal(err, "error initializing upgrade command flags") | ||
} | ||
profilecmd.Flags().StringVarP(&outputFile, "output-file", "o", "", "the path to the output file. If not specified, the output file will be directed to stdout") | ||
profilecmd.Flags().StringSliceVarP(&include, "include", "i", []string{}, "comma delimited list of controls to include from the source catalog/profile") | ||
profilecmd.Flags().StringSliceVarP(&exclude, "exclude", "e", []string{}, "comma delimited list of controls to exclude from the source catalog/profile") | ||
profilecmd.Flags().BoolVarP(&all, "all", "a", false, "Include all controls from the source catalog/profile") | ||
profilecmd.MarkFlagsMutuallyExclusive("include", "exclude", "all") | ||
profilecmd.MarkFlagsOneRequired("include", "exclude", "all") | ||
|
||
return profilecmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.