mirror of
https://github.com/FairwindsOps/polaris.git
synced 2026-08-23 22:26:34 +00:00
expose Polaris.PodSpec for PodSpec targeted checks (#793)
* Add a template `Polaris` variable, expose `Polaris.PodSpec` for checks of `target: PodSpec`. Polaris checks that are `target: PodSpec` have reflected the original resource (such as a pod-controller) in the Go template, instead of reflecting the pod `spec` field. This update makes the PodSpec available in a new template variable `Polaris.PodSpec`.
This commit is contained in:
@@ -134,6 +134,8 @@ schema:
|
||||
const: "{{ .metadata.name }}"
|
||||
```
|
||||
|
||||
Note that the object available via the template is the full object, and not the object implied by the `target`. A check that specifies `target: PodSpec` can directly access the pod specification via the built-in template variable `.Polaris.PodSpec`.
|
||||
|
||||
You can also use the full [Go template syntax](https://golang.org/pkg/text/template/), though
|
||||
you may need to specify your schema as a string in order to use concepts like `range`. E.g.
|
||||
this check ensures that at least one of the object's labels is present in `matchLabels`:
|
||||
|
||||
@@ -17,6 +17,7 @@ package kube
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@@ -475,3 +476,17 @@ func (resources *ResourceProvider) addResourceFromString(contents string) error
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// SerializePod converts a typed PodSpec into a map[string]interface{}
|
||||
func SerializePod(pod *corev1.PodSpec) (map[string]interface{}, error) {
|
||||
podJSON, err := json.Marshal(pod)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
podMap := make(map[string]interface{})
|
||||
err = json.Unmarshal(podJSON, &podMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return podMap, nil
|
||||
}
|
||||
|
||||
+27
-1
@@ -27,6 +27,7 @@ import (
|
||||
"gomodules.xyz/jsonpatch/v2"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
"github.com/fairwindsops/polaris/pkg/config"
|
||||
"github.com/fairwindsops/polaris/pkg/kube"
|
||||
@@ -64,13 +65,38 @@ func resolveCheck(conf *config.Configuration, checkID string, test schemaTestCas
|
||||
if !check.IsActionable(test.Target, test.Resource.Kind, test.IsInitContianer) {
|
||||
return nil, nil
|
||||
}
|
||||
checkPtr, err := check.TemplateForResource(test.Resource.Resource.Object)
|
||||
templateInput, err := getTemplateInput(test)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
checkPtr, err := check.TemplateForResource(templateInput)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return checkPtr, nil
|
||||
}
|
||||
|
||||
// getTemplateInput augments a schemaTestCase.Resource.Resource.Object with
|
||||
// Polaris built-in variables. The result can be used as input for
|
||||
// CheckSchema.TemplateForResource().
|
||||
func getTemplateInput(test schemaTestCase) (map[string]interface{}, error) {
|
||||
templateInput := test.Resource.Resource.Object
|
||||
if templateInput == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if test.Target == config.TargetPodSpec {
|
||||
podSpecMap, err := kube.SerializePod(test.Resource.PodSpec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = unstructured.SetNestedMap(templateInput, podSpecMap, "Polaris", "PodSpec")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return templateInput, nil
|
||||
}
|
||||
|
||||
func makeResult(conf *config.Configuration, check *config.SchemaCheck, passes bool, issues []jsonschema.ValError) ResultMessage {
|
||||
details := []string{}
|
||||
for _, issue := range issues {
|
||||
|
||||
Reference in New Issue
Block a user