Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor!: #388 update types to use pointers #410

Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
87db28e
refactor!(common): #388 update common/types (and all references) to u…
mike-winberry May 7, 2024
32e2e90
refactor!(common): #388 update Domain struct to use pointers
mike-winberry May 7, 2024
fd5f78e
refactor!(common): #388 update Provider struct to use pointers
mike-winberry May 7, 2024
1d74a87
Merge branch 'main' into 388-discussion-should-we-move-our-types-to-p…
mike-winberry May 8, 2024
a09dffd
refactor!(evaluate): #388 EvaluateResults now uses pointers
mike-winberry May 10, 2024
2ef4c3e
Merge branch 'main' into 388-discussion-should-we-move-our-types-to-p…
mike-winberry May 10, 2024
b94f17c
refactor!(resource-store): #388 changed AddFromLink params to use poi…
mike-winberry May 10, 2024
389d46d
refactor!(assessment-results): #388 NewAssessmentResults now returns …
mike-winberry May 10, 2024
2c193eb
Merge branch 'main' into 388-discussion-should-we-move-our-types-to-p…
mike-winberry May 10, 2024
d7431b3
refactor!(catalog): now runs validation rather than requiring the sou…
mike-winberry May 10, 2024
7e36b90
refactor!(component): #388 NewOscalComponentDefinition no longer uses…
mike-winberry May 12, 2024
96c3dfa
refactor!(common): #388 moved WriteOscalModel to the oscal package (c…
mike-winberry May 12, 2024
8a5ecf3
feat(oscal): create the multiModelValidate method for use in oscal co…
mike-winberry May 13, 2024
741357e
refactor!(component): #388 update mergeComponents and ComponentFromCa…
mike-winberry May 14, 2024
c218459
refactor(component): pointer refactor
mike-winberry May 15, 2024
cd7ec9f
Merge branch 'main' into 388-discussion-should-we-move-our-types-to-p…
mike-winberry May 15, 2024
c75aaf8
fix(component): failing e2e
mike-winberry May 15, 2024
bd2c288
refactor(component): ControlToImplementRequirement now takes pointer …
mike-winberry May 15, 2024
28eb1e7
fix(common): add omitempty to the marshalling for Validation
mike-winberry May 15, 2024
1200f08
refactor!(domains/kubernetes): #388 KubernetesSpec.Wait and Resource.…
mike-winberry May 16, 2024
13d384a
refactor!(domains/kubernetes): #388 ResourceRule.Field is now a point…
mike-winberry May 16, 2024
2d2e30e
refactor!(providers/kyverno): #388 KyvernoSpec is now a pointer
mike-winberry May 16, 2024
6cbb6df
refactor!(providers/opa): #388 OpaSpec is now a pointer
mike-winberry May 16, 2024
cfae566
refactor(providers): add omitempty to Kyverno and opa spec tags
mike-winberry May 16, 2024
5d07ded
refactor!(providers): update output fields to be pointers
mike-winberry May 17, 2024
9e90930
refactor!(domains): update api and k8s domain specs to be pointers
mike-winberry May 17, 2024
940633e
refactor!(types): #388 update LulaValidation provider, domain, domain…
mike-winberry May 17, 2024
dd7430a
Merge branch 'main' into 388-discussion-should-we-move-our-types-to-p…
mike-winberry May 17, 2024
4debf03
Merge branch 'main' into 388-discussion-should-we-move-our-types-to-p…
mike-winberry May 18, 2024
0eecd82
Merge branch 'main' into 388-discussion-should-we-move-our-types-to-p…
mike-winberry May 20, 2024
d84adfd
fix(evaluate): add nil check on thresholdResult and newResult to top …
mike-winberry May 20, 2024
b63a50a
Merge branch 'main' into 388-discussion-should-we-move-our-types-to-p…
mike-winberry May 20, 2024
4b8b250
chore(validate): add TODO to remove WriteReport as it is unused (ques…
mike-winberry May 20, 2024
9df47ba
fix: graceful exit conditions, empty result pointer
meganwolf0 May 21, 2024
7f43e86
Merge branch 'main' into 388-discussion-should-we-move-our-types-to-p…
mike-winberry May 22, 2024
812c684
Merge branch 'main' into 388-discussion-should-we-move-our-types-to-p…
mike-winberry May 23, 2024
f20329a
Merge branch 'main' into 388-discussion-should-we-move-our-types-to-p…
mike-winberry May 23, 2024
2587c79
Merge branch 'main' into 388-discussion-should-we-move-our-types-to-p…
mike-winberry May 23, 2024
a2e35b2
Merge branch 'main' into 388-discussion-should-we-move-our-types-to-p…
mike-winberry May 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions src/cmd/evaluate/evaluate.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package evaluate
import (
"fmt"

"github.com/defenseunicorns/go-oscal/src/pkg/utils"
oscalTypes_1_1_2 "github.com/defenseunicorns/go-oscal/src/types/oscal-1-1-2"
"github.com/defenseunicorns/lula/src/pkg/common"
"github.com/defenseunicorns/lula/src/pkg/common/oscal"
Expand Down Expand Up @@ -50,11 +51,21 @@ func EvaluateCommand() *cobra.Command {
func EvaluateAssessmentResults(files []string) error {
var status bool
var findings map[string][]oscalTypes_1_1_2.Finding

// Read in files - establish the results to
if len(files) == 0 {
// TODO: Determine if we will handle a default location/name for assessment files
return fmt.Errorf("No files provided for evaluation")
} else if len(files) == 1 {
}

for _, f := range files {
err := utils.IsJsonOrYaml(f)
if err != nil {
return fmt.Errorf("invalid file extension: %s, requires .json or .yaml", f)
}
}

if len(files) == 1 {
data, err := common.ReadFileToBytes(files[0])
if err != nil {
return err
Expand All @@ -68,7 +79,7 @@ func EvaluateAssessmentResults(files []string) error {
}
// We write results to the assessment-results report in newest -> oldest
// Older being our threshold here
status, findings, err = EvaluateResults(assessment.Results[1], assessment.Results[0])
status, findings, err = EvaluateResults(&assessment.Results[1], &assessment.Results[0])
if err != nil {
return err
}
Expand All @@ -94,7 +105,7 @@ func EvaluateAssessmentResults(files []string) error {
// Consider parsing the timestamps for comparison
// Older timestamp being the threshold

status, findings, err = EvaluateResults(assessmentOne.Results[0], assessmentTwo.Results[0])
status, findings, err = EvaluateResults(&assessmentOne.Results[0], &assessmentTwo.Results[0])
if err != nil {
return err
}
Expand All @@ -120,7 +131,7 @@ func EvaluateAssessmentResults(files []string) error {
}
}

func EvaluateResults(thresholdResult oscalTypes_1_1_2.Result, newResult oscalTypes_1_1_2.Result) (bool, map[string][]oscalTypes_1_1_2.Finding, error) {
func EvaluateResults(thresholdResult *oscalTypes_1_1_2.Result, newResult *oscalTypes_1_1_2.Result) (bool, map[string][]oscalTypes_1_1_2.Finding, error) {
spinner := message.NewProgressSpinner("Evaluating Assessment Results %s against %s", newResult.UUID, thresholdResult.UUID)
defer spinner.Stop()

Expand Down
10 changes: 5 additions & 5 deletions src/cmd/evaluate/evaluate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestEvaluateResultsPassing(t *testing.T) {
},
}

status, _, err := EvaluateResults(mockThresholdResult, mockEvaluationResult)
status, _, err := EvaluateResults(&mockThresholdResult, &mockEvaluationResult)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -77,7 +77,7 @@ func TestEvaluateResultsFailed(t *testing.T) {
},
}

status, findings, err := EvaluateResults(mockThresholdResult, mockEvaluationResult)
status, findings, err := EvaluateResults(&mockThresholdResult, &mockEvaluationResult)
if err != nil {
t.Fatal(err)
}
Expand All @@ -103,7 +103,7 @@ func TestEvaluateResultsNoFindings(t *testing.T) {
Findings: &[]oscalTypes_1_1_2.Finding{},
}

status, _, err := EvaluateResults(mockThresholdResult, mockEvaluationResult)
status, _, err := EvaluateResults(&mockThresholdResult, &mockEvaluationResult)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -132,7 +132,7 @@ func TestEvaluateResultsNoThreshold(t *testing.T) {
},
}

_, _, err := EvaluateResults(mockThresholdResult, mockEvaluationResult)
_, _, err := EvaluateResults(&mockThresholdResult, &mockEvaluationResult)
if err == nil {
t.Fatal("error - expected error, got nil")
}
Expand Down Expand Up @@ -182,7 +182,7 @@ func TestEvaluateResultsNewFindings(t *testing.T) {
},
}

status, findings, err := EvaluateResults(mockThresholdResult, mockEvaluationResult)
status, findings, err := EvaluateResults(&mockThresholdResult, &mockEvaluationResult)
if err != nil {
t.Fatal(err)
}
Expand Down
5 changes: 2 additions & 3 deletions src/cmd/generate/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"

oscalTypes_1_1_2 "github.com/defenseunicorns/go-oscal/src/types/oscal-1-1-2"
"github.com/defenseunicorns/lula/src/pkg/common"
"github.com/defenseunicorns/lula/src/pkg/common/network"
"github.com/defenseunicorns/lula/src/pkg/common/oscal"
"github.com/defenseunicorns/lula/src/pkg/message"
Expand Down Expand Up @@ -90,7 +89,7 @@ var generateComponentCmd = &cobra.Command{
}

// Create new catalog object
catalog, err := oscal.NewCatalog(source, data)
catalog, err := oscal.NewCatalog(data)
if err != nil {
message.Fatalf(fmt.Errorf("error creating catalog"), "error creating catalog")
}
Expand All @@ -106,7 +105,7 @@ var generateComponentCmd = &cobra.Command{
}

// Write the component definition to file
err = common.WriteFile(componentOpts.OutputFile, &model)
err = oscal.WriteOscalModel(componentOpts.OutputFile, &model)
if err != nil {
message.Fatalf(err, "error writing component to file")
}
Expand Down
20 changes: 13 additions & 7 deletions src/cmd/validate/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"path/filepath"
"time"

"github.com/defenseunicorns/go-oscal/src/pkg/utils"
"github.com/defenseunicorns/go-oscal/src/pkg/uuid"
oscalTypes_1_1_2 "github.com/defenseunicorns/go-oscal/src/types/oscal-1-1-2"
"github.com/defenseunicorns/lula/src/pkg/common"
Expand Down Expand Up @@ -44,6 +45,11 @@ var validateCmd = &cobra.Command{
message.Fatal(errors.New("flag input-file is not set"),
"Please specify an input file with the -f flag")
}

if err := utils.IsJsonOrYaml(opts.InputFile); err != nil {
message.Fatalf(err, "Invalid file extension: %s, requires .json or .yaml", opts.InputFile)
}

// Primary expected path for validation of OSCAL documents
findings, observations, err := ValidateOnPath(opts.InputFile)
if err != nil {
Expand All @@ -60,7 +66,7 @@ var validateCmd = &cobra.Command{
}

// Write the component definition to file
err = common.WriteFile(opts.OutputFile, &model)
err = oscal.WriteOscalModel(opts.OutputFile, &model)
if err != nil {
message.Fatalf(err, "error writing component to file")
}
Expand Down Expand Up @@ -121,7 +127,7 @@ func ValidateOnPath(path string) (findingMap map[string]oscalTypes_1_1_2.Finding
}
defer resetCwd()

compDef, err := oscal.NewOscalComponentDefinition(path, data)
compDef, err := oscal.NewOscalComponentDefinition(data)
if err != nil {
return findingMap, observations, err
}
Expand Down Expand Up @@ -282,7 +288,7 @@ func ValidateOnCompDef(compDef *oscalTypes_1_1_2.ComponentDefinition) (map[strin
func WriteReport(report oscalTypes_1_1_2.AssessmentResults, assessmentFilePath string) error {

var fileName string
var tempAssessment oscalTypes_1_1_2.AssessmentResults
var tempAssessment *oscalTypes_1_1_2.AssessmentResults

if assessmentFilePath != "" {

Expand All @@ -308,23 +314,23 @@ func WriteReport(report oscalTypes_1_1_2.AssessmentResults, assessmentFilePath s

} else if os.IsNotExist(err) {
// File does not exist
tempAssessment = report
tempAssessment = &report
fileName = assessmentFilePath
} else {
// Some other error occurred (permission issues, etc.)
return err
}

} else {
tempAssessment = report
tempAssessment = &report
currentTime := time.Now()
fileName = "assessment-results-" + currentTime.Format("01-02-2006-15:04:05") + ".yaml"
fileName = "assessment-results-" + currentTime.Format("01-02-206-15:04:05") + ".yaml"
}

var b bytes.Buffer

var sar = oscalTypes_1_1_2.OscalModels{
AssessmentResults: &tempAssessment,
AssessmentResults: tempAssessment,
}

yamlEncoder := yaml.NewEncoder(&b)
Expand Down
65 changes: 12 additions & 53 deletions src/pkg/common/common.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
package common

import (
"bytes"
"context"
"fmt"
"os"
"path/filepath"
"strings"

"github.com/defenseunicorns/go-oscal/src/pkg/utils"
oscalTypes_1_1_2 "github.com/defenseunicorns/go-oscal/src/types/oscal-1-1-2"
"github.com/defenseunicorns/lula/src/pkg/common/oscal"
"github.com/defenseunicorns/lula/src/pkg/domains/api"
kube "github.com/defenseunicorns/lula/src/pkg/domains/kubernetes"
"github.com/defenseunicorns/lula/src/pkg/message"
"github.com/defenseunicorns/lula/src/pkg/providers/kyverno"
"github.com/defenseunicorns/lula/src/pkg/providers/opa"
"github.com/defenseunicorns/lula/src/types"
goversion "github.com/hashicorp/go-version"
"gopkg.in/yaml.v3"
)

const (
Expand Down Expand Up @@ -58,49 +54,6 @@ func ReadFileToBytes(path string) ([]byte, error) {
return data, nil
}

// WriteFile takes a path and writes content to a file while performing checks for existing content
func WriteFile(filePath string, model *oscalTypes_1_1_2.OscalModels) error {

// if no path or directory add default filename
if filepath.Ext(filePath) == "" {
filePath = filepath.Join(filePath, "oscal.yaml")
}

if _, err := os.Stat(filePath); err == nil {
// If the file exists - read the data into the model
existingFileBytes, err := os.ReadFile(filePath)
if err != nil {
return err
}
existingModel, err := oscal.NewOscalModel(existingFileBytes)
if err != nil {
return err
}
// Merge the existing model with the new model
// re-assign to perform common operations below
model, err = oscal.MergeOscalModels(existingModel, model)
if err != nil {
return err
}
}

var b bytes.Buffer

yamlEncoder := yaml.NewEncoder(&b)
yamlEncoder.SetIndent(2)
yamlEncoder.Encode(model)

err := utils.WriteOutput(b.Bytes(), filePath)
if err != nil {
return err
}

message.Infof("OSCAL artifact written to: %s", filePath)

return nil

}

// Returns version validity
func IsVersionValid(versionConstraint string, version string) (bool, error) {
if version == "unset" {
Expand Down Expand Up @@ -164,33 +117,39 @@ func SetCwdToFileDir(dirPath string) (resetFunc func(), err error) {
}

// Get the domain and providers
func GetDomain(domain Domain, ctx context.Context) types.Domain {
func GetDomain(domain *Domain, ctx context.Context) types.Domain {
if domain == nil {
return nil
}
switch domain.Type {
case "kubernetes":
return kube.KubernetesDomain{
Context: ctx,
Spec: domain.KubernetesSpec,
Spec: *domain.KubernetesSpec,
}
case "api":
return api.ApiDomain{
Spec: domain.ApiSpec,
Spec: *domain.ApiSpec,
}
default:
return nil
}
}

func GetProvider(provider Provider, ctx context.Context) types.Provider {
func GetProvider(provider *Provider, ctx context.Context) types.Provider {
if provider == nil {
return nil
}
switch provider.Type {
case "opa":
return opa.OpaProvider{
Context: ctx,
Spec: provider.OpaSpec,
Spec: *provider.OpaSpec,
}
case "kyverno":
return kyverno.KyvernoProvider{
Context: ctx,
Spec: provider.KyvernoSpec,
Spec: *provider.KyvernoSpec,
}
default:
return nil
Expand Down
Loading