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: Remove config checkers config from generic starboard ConfigMap #603

Merged
merged 1 commit into from
May 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 3 additions & 6 deletions deploy/helm/templates/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@ data:
{{- end }}
{{- if .Values.operator.configAuditScannerEnabled }}
configAuditReports.scanner: {{ .Values.operator.configAuditReportsPlugin | quote }}
{{- if eq .Values.operator.configAuditReportsPlugin "Polaris" }}
polaris.imageRef: "{{ .Values.polaris.imageRef }}"
{{- end }}
{{- if eq .Values.operator.configAuditReportsPlugin "Conftest" }}
conftest.imageRef: {{ .Values.conftest.imageRef | quote }}
{{- end }}
{{- end }}
{{- if eq .Values.operator.configAuditReportsPlugin "Conftest" }}
---
Expand All @@ -40,6 +34,8 @@ metadata:
name: starboard-conftest-config
labels:
{{- include "starboard-operator.labels" . | nindent 4 }}
data:
conftest.imageRef: {{ .Values.conftest.imageRef | quote }}
{{- end }}
{{- if eq .Values.operator.configAuditReportsPlugin "Polaris" }}
---
Expand All @@ -50,6 +46,7 @@ metadata:
labels:
{{- include "starboard-operator.labels" . | nindent 4 }}
data:
polaris.imageRef: "{{ .Values.polaris.imageRef }}"
polaris.config.yaml: |
{{- toYaml .Values.polaris.config | nindent 4 }}
{{- end }}
3 changes: 1 addition & 2 deletions deploy/static/05-starboard-operator.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ data:
trivy.imageRef: docker.io/aquasec/trivy:0.16.0
trivy.mode: Standalone
trivy.serverURL: http://trivy-server.trivy-server:4954
polaris.imageRef: quay.io/fairwinds/polaris:3.2
conftest.imageRef: openpolicyagent/conftest:v0.25.0
kube-bench.imageRef: docker.io/aquasec/kube-bench:0.5.0
---
apiVersion: v1
Expand All @@ -21,6 +19,7 @@ metadata:
name: starboard-polaris-config
namespace: starboard-operator
data:
polaris.imageRef: quay.io/fairwinds/polaris:3.2
polaris.config.yaml: |
checks:
# reliability
Expand Down
1 change: 1 addition & 0 deletions docs/integrations/config-checkers/conftest.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ As an example, let's create the `starboard-conftest-config` ConfigMap with [file

```
kubectl create configmap starboard-conftest-config -n <starboard_namespace> \
--from-literal=conftest.imageRef=openpolicyagent/conftest:v0.25.0 \
--from-file=conftest.policy.kubernetes.rego=kubernetes/lib/kubernetes.rego \
--from-file=conftest.policy.utils.rego=kubernetes/lib/utils.rego \
--from-file=conftest.policy.file_system_not_read_only.rego=kubernetes/policies/general/file_system_not_read_only.rego \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ var _ = BeforeSuite(func() {
Name: starboard.GetPluginConfigMapName("Conftest"),
},
Data: map[string]string{
"conftest.imageRef": "docker.io/openpolicyagent/conftest:v0.25.0",

"conftest.policy.runs_as_root.rego": runAsRootPolicy,
},
}
Expand Down
1 change: 1 addition & 0 deletions itest/starboard/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ var (
Namespace: "starboard",
},
Data: map[string]string{
"conftest.imageRef": "docker.io/openpolicyagent/conftest:v0.25.0",
"conftest.policy.runs_as_root.rego": `
package main

Expand Down
2 changes: 1 addition & 1 deletion pkg/configauditreport/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func (p *testPlugin) GetScanJobSpec(ctx starboard.PluginContext, obj client.Obje
return corev1.PodSpec{}, nil, nil
}

func (p *testPlugin) ParseConfigAuditReportData(logsReader io.ReadCloser) (v1alpha1.ConfigAuditResult, error) {
func (p *testPlugin) ParseConfigAuditReportData(ctx starboard.PluginContext, logsReader io.ReadCloser) (v1alpha1.ConfigAuditResult, error) {
return v1alpha1.ConfigAuditResult{}, nil
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/configauditreport/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type Plugin interface {

// ParseConfigAuditReportData is a callback to parse and convert logs of
// the container in a pod controlled by the scan job to v1alpha1.ConfigAuditResult.
ParseConfigAuditReportData(logsReader io.ReadCloser) (v1alpha1.ConfigAuditResult, error)
ParseConfigAuditReportData(ctx starboard.PluginContext, logsReader io.ReadCloser) (v1alpha1.ConfigAuditResult, error)

// GetContainerName returns the name of the container in a pod created by a scan job
// to read logs from.
Expand Down
2 changes: 1 addition & 1 deletion pkg/configauditreport/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func (s *Scanner) Scan(ctx context.Context, workload kube.Object) (v1alpha1.Conf
return v1alpha1.ConfigAuditReport{}, fmt.Errorf("getting logs: %w", err)
}

result, err := s.plugin.ParseConfigAuditReportData(logsStream)
result, err := s.plugin.ParseConfigAuditReportData(s.pluginContext, logsStream)
defer func() {
_ = logsStream.Close()
}()
Expand Down
2 changes: 1 addition & 1 deletion pkg/operator/controller/configauditreport.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ func (r *ConfigAuditReportReconciler) processCompleteScanJob(ctx context.Context
return fmt.Errorf("getting logs: %w", err)
}

result, err := r.Plugin.ParseConfigAuditReportData(logsStream)
result, err := r.Plugin.ParseConfigAuditReportData(r.PluginContext, logsStream)
defer func() {
_ = logsStream.Close()
}()
Expand Down
22 changes: 12 additions & 10 deletions pkg/plugin/conftest/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,17 @@ const (
defaultCheckCategory = "Security"
)

type Config interface {
GetConftestImageRef() (string, error)
}

type plugin struct {
idGenerator ext.IDGenerator
clock ext.Clock
config Config
}

// NewPlugin constructs a new configauditreport.Plugin, which is using
// the upstream Conftest container image to audit K8s workloads.
func NewPlugin(idGenerator ext.IDGenerator, clock ext.Clock, config Config) configauditreport.Plugin {
func NewPlugin(idGenerator ext.IDGenerator, clock ext.Clock) configauditreport.Plugin {
return &plugin{
idGenerator: idGenerator,
clock: clock,
config: config,
}
}

Expand All @@ -55,7 +49,7 @@ func (p *plugin) GetConfigHash(ctx starboard.PluginContext) (string, error) {
}

func (p *plugin) GetScanJobSpec(ctx starboard.PluginContext, obj client.Object) (corev1.PodSpec, []*corev1.Secret, error) {
imageRef, err := p.config.GetConftestImageRef()
imageRef, err := p.getImageRef(ctx)
if err != nil {
return corev1.PodSpec{}, nil, fmt.Errorf("getting image reference: %w", err)
}
Expand Down Expand Up @@ -194,7 +188,7 @@ func (p *plugin) GetContainerName() string {
return conftestContainerName
}

func (p *plugin) ParseConfigAuditReportData(logsReader io.ReadCloser) (v1alpha1.ConfigAuditResult, error) {
func (p *plugin) ParseConfigAuditReportData(ctx starboard.PluginContext, logsReader io.ReadCloser) (v1alpha1.ConfigAuditResult, error) {
var checkResults []CheckResult
err := json.NewDecoder(logsReader).Decode(&checkResults)

Expand Down Expand Up @@ -229,7 +223,7 @@ func (p *plugin) ParseConfigAuditReportData(logsReader io.ReadCloser) (v1alpha1.
}
}

imageRef, err := p.config.GetConftestImageRef()
imageRef, err := p.getImageRef(ctx)
if err != nil {
return v1alpha1.ConfigAuditResult{}, err
}
Expand Down Expand Up @@ -263,3 +257,11 @@ func (p *plugin) getPolicyTitleFromResult(result Result) string {
// Fallback to a unique identifier
return p.idGenerator.GenerateID()
}

func (p *plugin) getImageRef(ctx starboard.PluginContext) (string, error) {
config, err := ctx.GetConfig()
if err != nil {
return "", err
}
return config.GetRequiredData("conftest.imageRef")
}
42 changes: 27 additions & 15 deletions pkg/plugin/conftest/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ var (
func TestPlugin_GetScanJobSpec(t *testing.T) {
g := NewGomegaWithT(t)
sequence := ext.NewSimpleIDGenerator()
config := starboard.ConfigData{
"conftest.imageRef": "openpolicyagent/conftest:v0.23.0",
}
pluginContext := starboard.NewPluginContext().
WithName(string(starboard.Conftest)).
WithNamespace("starboard-ns").
Expand All @@ -41,18 +38,21 @@ func TestPlugin_GetScanJobSpec(t *testing.T) {
Namespace: "starboard-ns",
},
Data: map[string]string{
"conftest.imageRef": "openpolicyagent/conftest:v0.23.0",

"conftest.policy.libkubernetes.rego": "<REGO>",
"conftest.policy.libutil.rego": "<REGO>",
"conftest.policy.access_to_host_pid.rego": "<REGO>",
"conftest.policy.cpu_not_limited.rego": "<REGO>",
"foo": "bar", // This one should be skipped (no conftest.policy. prefix)
"conftest.policy.privileged": "<REGO>", // This one should be skipped (no .rego suffix)

"foo": "bar", // This one should be skipped (no conftest.policy. prefix)
},
}).Build()).Get()

plugin := conftest.NewPlugin(sequence, fixedClock, config)
instance := conftest.NewPlugin(sequence, fixedClock)

jobSpec, secrets, err := plugin.GetScanJobSpec(pluginContext, &corev1.Pod{
jobSpec, secrets, err := instance.GetScanJobSpec(pluginContext, &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "nginx",
Namespace: "default",
Expand Down Expand Up @@ -202,10 +202,7 @@ status: {}

func TestPlugin_ParseConfigAuditReportData(t *testing.T) {
g := NewGomegaWithT(t)
config := starboard.ConfigData{
"conftest.imageRef": "openpolicyagent/conftest:v0.23.0",
}
plugin := conftest.NewPlugin(ext.NewSimpleIDGenerator(), fixedClock, config)
plugin := conftest.NewPlugin(ext.NewSimpleIDGenerator(), fixedClock)
logsReader := ioutil.NopCloser(strings.NewReader(`[
{
"filename": "/project/workload.yaml",
Expand Down Expand Up @@ -273,7 +270,22 @@ func TestPlugin_ParseConfigAuditReportData(t *testing.T) {
}
]`))

data, err := plugin.ParseConfigAuditReportData(logsReader)
pluginContext := starboard.NewPluginContext().
WithName(string(starboard.Conftest)).
WithNamespace("starboard-ns").
WithServiceAccountName("starboard-sa").
WithClient(fake.NewClientBuilder().WithObjects(&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "starboard-conftest-config",
Namespace: "starboard-ns",
},
Data: map[string]string{
"conftest.imageRef": "openpolicyagent/conftest:v0.25.0",
},
}).Build()).
Get()

data, err := plugin.ParseConfigAuditReportData(pluginContext, logsReader)

// When Conftest plugin is used with https://github.com/aquasecurity/appshield
// Rego scripts the Check.ID is not unique. For example, for a Pod with multiple
Expand All @@ -289,7 +301,7 @@ func TestPlugin_ParseConfigAuditReportData(t *testing.T) {
"Scanner": Equal(v1alpha1.Scanner{
Name: "Conftest",
Vendor: "Open Policy Agent",
Version: "v0.23.0",
Version: "v0.25.0",
}),
"Summary": Equal(v1alpha1.ConfigAuditSummary{
DangerCount: 6,
Expand Down Expand Up @@ -379,7 +391,7 @@ func TestPlugin_GetConfigHash(t *testing.T) {
"foo": "baz",
})

plugin := conftest.NewPlugin(ext.NewSimpleIDGenerator(), fixedClock, starboard.ConfigData{})
plugin := conftest.NewPlugin(ext.NewSimpleIDGenerator(), fixedClock)
hash1, err := plugin.GetConfigHash(pluginContext1)
g.Expect(err).ToNot(HaveOccurred())

Expand All @@ -400,7 +412,7 @@ func TestPlugin_GetConfigHash(t *testing.T) {
"foo": "bar",
})

plugin := conftest.NewPlugin(ext.NewSimpleIDGenerator(), fixedClock, starboard.ConfigData{})
plugin := conftest.NewPlugin(ext.NewSimpleIDGenerator(), fixedClock)
hash1, err := plugin.GetConfigHash(pluginContext1)
g.Expect(err).ToNot(HaveOccurred())

Expand All @@ -413,6 +425,6 @@ func TestPlugin_GetConfigHash(t *testing.T) {
func TestPlugin_GetContainerName(t *testing.T) {
g := NewGomegaWithT(t)

plugin := conftest.NewPlugin(ext.NewSimpleIDGenerator(), fixedClock, starboard.ConfigData{})
plugin := conftest.NewPlugin(ext.NewSimpleIDGenerator(), fixedClock)
g.Expect(plugin.GetContainerName()).To(Equal("conftest"))
}
18 changes: 7 additions & 11 deletions pkg/plugin/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,12 @@ func (r *Resolver) WithClient(client client.Client) *Resolver {
return r
}

// GetVulnerabilityPlugin is a factory method that instantiates the
// vulnerabilityreport.Plugin for the specified starboard.ConfigData.
// GetVulnerabilityPlugin is a factory method that instantiates the vulnerabilityreport.Plugin.
//
// Starboard currently supports Trivy scanner in Standalone and ClientServer
// mode, and Aqua Enterprise scanner.
//
// You could add your own scanner by implementing the
// vulnerabilityreport.Plugin interface.
// You could add your own scanner by implementing the vulnerabilityreport.Plugin interface.
func (r *Resolver) GetVulnerabilityPlugin() (vulnerabilityreport.Plugin, starboard.PluginContext, error) {
scanner, err := r.config.GetVulnerabilityReportsScanner()
if err != nil {
Expand All @@ -81,13 +79,11 @@ func (r *Resolver) GetVulnerabilityPlugin() (vulnerabilityreport.Plugin, starboa
return nil, nil, fmt.Errorf("unsupported vulnerability scanner plugin: %s", scanner)
}

// GetConfigAuditPlugin is a factory method that instantiates the
// configauditreport.Plugin for the specified starboard.ConfigData.
// GetConfigAuditPlugin is a factory method that instantiates the configauditreport.Plugin.
//
// Starboard supports Polaris as the only configuration auditing tool.
// Starboard supports Polaris and Conftest as configuration auditing tools.
//
// You could add your own scanner by implementing the configauditreport.Plugin
// interface.
// You could add your own scanner by implementing the configauditreport.Plugin interface.
func (r *Resolver) GetConfigAuditPlugin() (configauditreport.Plugin, starboard.PluginContext, error) {
scanner, err := r.config.GetConfigAuditReportsScanner()
if err != nil {
Expand All @@ -103,9 +99,9 @@ func (r *Resolver) GetConfigAuditPlugin() (configauditreport.Plugin, starboard.P

switch scanner {
case starboard.Polaris:
return polaris.NewPlugin(ext.NewSystemClock(), r.config), pluginContext, nil
return polaris.NewPlugin(ext.NewSystemClock()), pluginContext, nil
case starboard.Conftest:
return conftest.NewPlugin(ext.NewGoogleUUIDGenerator(), ext.NewSystemClock(), r.config), pluginContext, nil
return conftest.NewPlugin(ext.NewGoogleUUIDGenerator(), ext.NewSystemClock()), pluginContext, nil
}
return nil, nil, fmt.Errorf("unsupported configuration audit scanner plugin: %s", scanner)
}
Loading