more progress

This commit is contained in:
Robert Brennan
2021-03-12 17:26:11 +00:00
parent d858b3f32a
commit 2929c7c42e
3 changed files with 51 additions and 38 deletions

View File

@@ -4,13 +4,16 @@ import (
"bytes"
"encoding/json"
"fmt"
"io"
"strings"
"text/template"
"github.com/qri-io/jsonschema"
"github.com/thoas/go-funk"
"gopkg.in/yaml.v3"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
k8sYaml "k8s.io/apimachinery/pkg/util/yaml"
)
// TargetKind represents the part of the config to be validated
@@ -49,6 +52,25 @@ type SchemaCheck struct {
type resourceMinimum string
type resourceMaximum string
func ParseCheck(rawBytes []byte) (SchemaCheck, error) {
fmt.Println("parse", string(rawBytes))
reader := bytes.NewReader(rawBytes)
check := SchemaCheck{}
d := k8sYaml.NewYAMLOrJSONDecoder(reader, 4096)
for {
if err := d.Decode(&check); err != nil {
if err == io.EOF {
return check, nil
}
return check, fmt.Errorf("Decoding schema check failed: %v", err)
}
}
}
func (check *SchemaCheck) MarshalYAML() (interface{}, error) {
return nil
}
func init() {
jsonschema.RegisterValidator("resourceMinimum", newResourceMinimum)
jsonschema.RegisterValidator("resourceMaximum", newResourceMaximum)
@@ -127,7 +149,6 @@ func validateRange(path string, limit interface{}, data interface{}, isMinimum b
// Initialize sets up the schema
func (check *SchemaCheck) Initialize(id string) error {
fmt.Println("init", id, check.JSONSchema, check.Schema)
check.ID = id
if check.JSONSchema != "" {
if err := json.Unmarshal([]byte(check.JSONSchema), &check.Schema); err != nil {
@@ -137,29 +158,34 @@ func (check *SchemaCheck) Initialize(id string) error {
return nil
}
func (check SchemaCheck) TemplateForResource(res interface{}) (SchemaCheck, error) {
newCheck := check
var tmpl *template.Template
var err error
tmpl = template.New(check.ID)
yaml, err := yaml.Marshal()
fmt.Println("json sch", check.JSONSchema)
tmpl, err = tmpl.Parse(check.JSONSchema)
func (check SchemaCheck) TemplateForResource(res interface{}) (*SchemaCheck, error) {
yamlBytes, err := yaml.Marshal(check.Schema)
if err != nil {
return newCheck, err
return nil, err
}
tmpl := template.New(check.ID)
tmpl, err = tmpl.Parse(string(yamlBytes))
if err != nil {
return nil, err
}
w := bytes.Buffer{}
err = tmpl.Execute(&w, res)
if err != nil {
return newCheck, err
return nil, err
}
newCheck, err := ParseCheck(w.Bytes())
fmt.Println("parse check")
if err != nil {
fmt.Println("err", err)
return nil, err
}
fmt.Println("templated", w.String())
newCheck.JSONSchema = w.String()
err = newCheck.Initialize(check.ID)
if err != nil {
return newCheck, err
return nil, err
}
return newCheck, nil
return &newCheck, nil
}
// CheckPod checks a pod spec against the schema

View File

@@ -1,16 +1,13 @@
package validator
import (
"bytes"
"fmt"
"io"
"sort"
"strings"
"github.com/gobuffalo/packr/v2"
corev1 "k8s.io/api/core/v1"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/yaml"
"github.com/fairwindsops/polaris/pkg/config"
"github.com/fairwindsops/polaris/pkg/kube"
@@ -66,29 +63,15 @@ func init() {
if err != nil {
panic(err)
}
check, err := parseCheck(contents)
check, err := config.ParseCheck(contents)
if err != nil {
panic(err)
}
check.ID = checkID
check.Initialize(checkID)
builtInChecks[checkID] = check
}
}
func parseCheck(rawBytes []byte) (config.SchemaCheck, error) {
reader := bytes.NewReader(rawBytes)
check := config.SchemaCheck{}
d := yaml.NewYAMLOrJSONDecoder(reader, 4096)
for {
if err := d.Decode(&check); err != nil {
if err == io.EOF {
return check, nil
}
return check, fmt.Errorf("Decoding schema check failed: %v", err)
}
}
}
func resolveCheck(conf *config.Configuration, checkID string, test schemaTestCase) (*config.SchemaCheck, error) {
if !conf.DisallowExemptions && hasExemptionAnnotation(test.Resource.ObjectMeta, checkID) {
return nil, nil
@@ -111,11 +94,11 @@ func resolveCheck(conf *config.Configuration, checkID string, test schemaTestCas
if !check.IsActionable(test.Target, test.Resource.Kind, test.IsInitContianer) {
return nil, nil
}
check, err := check.TemplateForResource(test.Resource.Resource.Object)
checkPtr, err := check.TemplateForResource(test.Resource.Resource.Object)
if err != nil {
return nil, err
}
return &check, nil
return checkPtr, nil
}
func makeResult(conf *config.Configuration, check *config.SchemaCheck, passes bool) ResultMessage {

View File

@@ -61,9 +61,13 @@ func TestChecks(t *testing.T) {
panic(err)
}
c, err := config.Parse([]byte("checks:\n " + tc.check + ": danger"))
assert.NoError(t, err)
if err != nil {
panic(err)
}
result, err := validator.ApplyAllSchemaChecks(&c, res)
assert.NoError(t, err)
if err != nil {
panic(err)
}
summary := result.GetSummary()
total := summary.Successes + summary.Dangers
msg := fmt.Sprintf("Check %s ran %d times instead of 1", tc.check, total)