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

[prepped for merging into main] Adding in the remaining unit tests for constraints, filled out some TODOs #273

Merged
merged 22 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
7b013a9
update badges on readme to follow main branch (#254)
davidgamero Mar 12, 2024
ff01480
Added SDK calls in tenantID function (#258)
Vidya2606 Mar 26, 2024
a1aba8a
Updated the function to retrive the tenantId (#259)
Vidya2606 Mar 27, 2024
38990ef
fix flaky map ordering unit test (#263)
OliverMKing Apr 3, 2024
d64aa38
Adding the client interface and unit tests for getTenantID func (#262)
Vidya2606 Apr 12, 2024
5e45274
enabled all UTs
tbarnes94 Apr 24, 2024
fb27137
CL -> CRL
tbarnes94 Apr 24, 2024
31f1427
update draft to go 1.22 (#271)
davidgamero Apr 25, 2024
7c9284c
Added SDK calls to the getAppObjectId function (#260)
Vidya2606 Apr 25, 2024
9c3c2f2
Fixed TestAllConstraints
tbarnes94 Apr 25, 2024
351cefb
DBPDB UT done
tbarnes94 Apr 26, 2024
66ea035
PEA UT done
tbarnes94 Apr 26, 2024
729466d
RT UT Done
tbarnes94 Apr 26, 2024
f8a678c
Addressing comments.
tbarnes94 Apr 26, 2024
00bc5b8
Merge branch 'staging' of https://github.com/Azure/draft into tbarnes…
tbarnes94 Apr 26, 2024
4d2a709
Renamed safeguards pkg file names, fixed exit codes, fixed double err…
tbarnes94 Apr 29, 2024
9bef1e8
merged from main and resolved conflicts
tbarnes94 Apr 30, 2024
93f67e7
merged from main and resolved conflicts
tbarnes94 Apr 30, 2024
01f4c10
Added ViolationsCount property for testing
tbarnes94 Apr 30, 2024
a77c978
made GetManifestFiles public, getObjectResults -> getObjectViolations
tbarnes94 Apr 30, 2024
db43391
Rehauled test case all to use GetManifestResults/GetManifestFiles dir…
tbarnes94 Apr 30, 2024
fd1c2a3
Merged from staging and resolved conflicts
tbarnes94 Apr 30, 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
4 changes: 2 additions & 2 deletions cmd/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func getManifestFiles(p string) ([]safeguards.ManifestFile, error) {
return manifestFiles, nil
}

// run is our entry point to GetManifestViolations
// run is our entry point to GetManifestResults
func (vc *validateCmd) run(c *cobra.Command) error {
if vc.manifestPath == "" {
return fmt.Errorf("path to the manifests cannot be empty")
Expand Down Expand Up @@ -132,7 +132,7 @@ func (vc *validateCmd) run(c *cobra.Command) error {
}

log.Debugf("validating manifests")
manifestViolations, err := safeguards.GetManifestViolations(ctx, manifestFiles)
manifestViolations, err := safeguards.GetManifestResults(ctx, manifestFiles)
if err != nil {
log.Errorf("validating safeguards: %s", err.Error())
return err
Expand Down
10 changes: 5 additions & 5 deletions cmd/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,35 +62,35 @@ func TestRunValidate(t *testing.T) {
var manifestFiles []safeguards.ManifestFile

// Scenario 1: empty manifest path should error
_, err := safeguards.GetManifestViolations(ctx, manifestFilesEmpty)
_, err := safeguards.GetManifestResults(ctx, manifestFilesEmpty)
assert.NotNil(t, err)

// Scenario 2a: manifest path leads to a directory of manifestFiles - expect success
manifestFiles, err = getManifestFiles(manifestPathDirectorySuccess)
assert.Nil(t, err)
v, err := safeguards.GetManifestViolations(ctx, manifestFiles)
v, err := safeguards.GetManifestResults(ctx, manifestFiles)
assert.Nil(t, err)
numViolations := countTestViolations(v)
assert.Equal(t, numViolations, 0)

// Scenario 2b: manifest path leads to a directory of manifestFiles - expect failure
manifestFiles, err = getManifestFiles(manifestPathDirectoryError)
assert.Nil(t, err)
v, err = safeguards.GetManifestViolations(ctx, manifestFiles)
v, err = safeguards.GetManifestResults(ctx, manifestFiles)
assert.Nil(t, err)
numViolations = countTestViolations(v)
assert.Greater(t, numViolations, 0)

// Scenario 3a: manifest path leads to one manifest file - expect success
manifestFiles, err = getManifestFiles(manifestPathFileSuccess)
v, err = safeguards.GetManifestViolations(ctx, manifestFiles)
v, err = safeguards.GetManifestResults(ctx, manifestFiles)
assert.Nil(t, err)
numViolations = countTestViolations(v)
assert.Equal(t, numViolations, 0)

// Scenario 3b: manifest path leads to one manifest file - expect failure
manifestFiles, err = getManifestFiles(manifestPathFileError)
v, err = safeguards.GetManifestViolations(ctx, manifestFiles)
v, err = safeguards.GetManifestResults(ctx, manifestFiles)
assert.Nil(t, err)
numViolations = countTestViolations(v)
assert.Greater(t, numViolations, 0)
Expand Down
6 changes: 3 additions & 3 deletions cmd/validate_test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package cmd

import "github.com/Azure/draft/pkg/safeguards"

func countTestViolations(violations []safeguards.ManifestViolation) int {
func countTestViolations(results []safeguards.ManifestResult) int {
numViolations := 0
for _, v := range violations {
numViolations += len(v.ObjectViolations)
for _, r := range results {
numViolations += len(r.ObjectViolations)
}

return numViolations
Expand Down
26 changes: 13 additions & 13 deletions pkg/safeguards/safeguards.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,38 +35,38 @@ func init() {
}
}

// GetManifestViolations takes in a list of manifest files and returns a slice of ManifestViolation structs
func GetManifestViolations(ctx context.Context, manifestFiles []ManifestFile) ([]ManifestViolation, error) {
// GetManifestResults takes in a list of manifest files and returns a slice of ManifestViolation structs
func GetManifestResults(ctx context.Context, manifestFiles []ManifestFile) ([]ManifestResult, error) {
if len(manifestFiles) == 0 {
return nil, fmt.Errorf("path cannot be empty")
}

manifestViolations := make([]ManifestViolation, 0)
manifestResults := make([]ManifestResult, 0)

// constraint client instantiation
c, err := getConstraintClient()
if err != nil {
return manifestViolations, err
return manifestResults, err
}

// retrieval of templates, constraints, and deployment
constraintTemplates, err := fc.ReadConstraintTemplates()
if err != nil {
return manifestViolations, err
return manifestResults, err
}
constraints, err := fc.ReadConstraints()
if err != nil {
return manifestViolations, err
return manifestResults, err
}

// loading of templates, constraints into constraint client
err = loadConstraintTemplates(ctx, c, constraintTemplates)
if err != nil {
return manifestViolations, err
return manifestResults, err
}
err = loadConstraints(ctx, c, constraints)
if err != nil {
return manifestViolations, err
return manifestResults, err
}

// organized map of manifest object by file name
Expand All @@ -77,7 +77,7 @@ func GetManifestViolations(ctx context.Context, manifestFiles []ManifestFile) ([
manifestObjects, err := fc.ReadManifests(m.Path) // read all the objects stored in a single file
if err != nil {
log.Errorf("reading objects %s", err.Error())
return manifestViolations, err
return manifestResults, err
}

allManifestObjects = append(allManifestObjects, manifestObjects...)
Expand All @@ -92,16 +92,16 @@ func GetManifestViolations(ctx context.Context, manifestFiles []ManifestFile) ([
var objectViolations map[string][]string

// validation of deployment manifest with constraints, templates loaded
objectViolations, err = getObjectViolations(ctx, c, manifestMap[m.Name])
objectViolations, err = getObjectResults(ctx, c, manifestMap[m.Name])
if err != nil {
log.Errorf("validating objects: %s", err.Error())
return manifestViolations, err
return manifestResults, err
}
manifestViolations = append(manifestViolations, ManifestViolation{
manifestResults = append(manifestResults, ManifestResult{
Name: m.Name,
ObjectViolations: objectViolations,
})
}

return manifestViolations, nil
return manifestResults, nil
}
9 changes: 5 additions & 4 deletions pkg/safeguards/safeguards_constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import (
const (
Constraint_CAI = "container-allowed-images"
Constraint_CEP = "container-enforce-probes"
Constraint_CL = "container-limits"
Constraint_CRL = "container-resource-limits"
Constraint_CRIP = "container-restricted-image-pulls"
Constraint_DBPDB = "disallowed-bad-pod-disruption-budgets"
Constraint_PEA = "pod-enforce-antiaffinity"
Constraint_RT = "restricted-taints"
Constraint_USS = "unique-service-selectors"
Constraint_all = "all"
)

var selectedVersion = "v1.0.0"
Expand All @@ -37,9 +38,9 @@ var safeguards = []Safeguard{
constraintPath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_CEP, constraintFileName),
},
{
name: Constraint_CL,
templatePath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_CL, templateFileName),
constraintPath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_CL, constraintFileName),
name: Constraint_CRL,
templatePath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_CRL, templateFileName),
constraintPath: fmt.Sprintf("lib/%s/%s/%s", selectedVersion, Constraint_CRL, constraintFileName),
},
{
name: Constraint_CRIP,
Expand Down
18 changes: 9 additions & 9 deletions pkg/safeguards/safeguards_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,34 +172,34 @@ func loadManifestObjects(ctx context.Context, c *constraintclient.Client, object
return nil
}

// getObjectViolations executes validation on manifests based on loaded constraint templates and returns a map of manifest name to list of objectViolations
func getObjectViolations(ctx context.Context, c *constraintclient.Client, objects []*unstructured.Unstructured) (map[string][]string, error) {
// getObjectResults executes validation on manifests based on loaded constraint templates and returns a map of manifest name to list of objectResults
func getObjectResults(ctx context.Context, c *constraintclient.Client, objects []*unstructured.Unstructured) (map[string][]string, error) {
// Review makes sure the provided object satisfies all stored constraints.
// On error, the responses return value will still be populated so that
// partial results can be analyzed.

var violations = make(map[string][]string) // map of object name to slice of objectViolations
var results = make(map[string][]string) // map of object name to slice of objectViolations

for _, o := range objects {
objectViolations := []string{}
objectResults := []string{}
log.Debugf("Reviewing %s...", o.GetName())
res, err := c.Review(ctx, o)
if err != nil {
return violations, fmt.Errorf("could not review objects: %w", err)
return results, fmt.Errorf("could not review objects: %w", err)
}

for _, v := range res.ByTarget {
for _, result := range v.Results {
if result.Msg != "" {
objectViolations = append(objectViolations, result.Msg)
objectResults = append(objectResults, result.Msg)
}
}
}

if len(objectViolations) > 0 {
violations[o.GetName()] = objectViolations
if len(objectResults) > 0 {
results[o.GetName()] = objectResults
}
}

return violations, nil
return results, nil
}
Loading
Loading