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

feat(operator): Allow configuring scanners #224

Merged
merged 1 commit into from Oct 23, 2020
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
38 changes: 25 additions & 13 deletions cmd/starboard-operator/main.go
@@ -1,6 +1,7 @@
package main

import (
"context"
"errors"
"fmt"

Expand Down Expand Up @@ -74,22 +75,22 @@ func main() {

func run() error {
setupLog.Info("Starting operator", "version", versionInfo)
config, err := etc.GetOperatorConfig()
operatorConfig, err := etc.GetOperatorConfig()
if err != nil {
return fmt.Errorf("getting operator config: %w", err)
}

log.SetLogger(zap.New(zap.UseDevMode(config.Operator.LogDevMode)))
log.SetLogger(zap.New(zap.UseDevMode(operatorConfig.Operator.LogDevMode)))

// Validate configured namespaces to resolve install mode.
operatorNamespace, err := config.Operator.GetOperatorNamespace()
operatorNamespace, err := operatorConfig.Operator.GetOperatorNamespace()
if err != nil {
return fmt.Errorf("getting operator namespace: %w", err)
}

targetNamespaces := config.Operator.GetTargetNamespaces()
targetNamespaces := operatorConfig.Operator.GetTargetNamespaces()

installMode, err := config.Operator.GetInstallMode()
installMode, err := operatorConfig.Operator.GetInstallMode()
if err != nil {
return fmt.Errorf("getting install mode: %w", err)
}
Expand All @@ -100,8 +101,8 @@ func run() error {
// Set the default manager options.
options := manager.Options{
Scheme: scheme,
MetricsBindAddress: config.Operator.MetricsBindAddress,
HealthProbeBindAddress: config.Operator.HealthProbeBindAddress,
MetricsBindAddress: operatorConfig.Operator.MetricsBindAddress,
HealthProbeBindAddress: operatorConfig.Operator.HealthProbeBindAddress,
}

switch installMode {
Expand Down Expand Up @@ -158,16 +159,27 @@ func run() error {
return err
}

configManager := starboard.NewConfigManager(kubernetesClientset, operatorNamespace)
err = configManager.EnsureDefault(context.Background())
if err != nil {
return err
}

starboardConfig, err := configManager.Read(context.Background())
if err != nil {
return err
}

store := reports.NewStore(mgr.GetClient(), scheme)
idGenerator := ext.NewGoogleUUIDGenerator()

scanner, err := getEnabledScanner(idGenerator, config)
scanner, err := getEnabledScanner(idGenerator, operatorConfig, starboardConfig)
if err != nil {
return err
}

if err = (&pod.PodController{
Config: config.Operator,
Config: operatorConfig.Operator,
Client: mgr.GetClient(),
IDGenerator: idGenerator,
Store: store,
Expand All @@ -178,7 +190,7 @@ func run() error {
}

if err = (&job.JobController{
Config: config.Operator,
Config: operatorConfig.Operator,
LogsReader: logs.NewReader(kubernetesClientset),
Client: mgr.GetClient(),
Store: store,
Expand All @@ -196,16 +208,16 @@ func run() error {
return nil
}

func getEnabledScanner(idGenerator ext.IDGenerator, config etc.Config) (scanner.VulnerabilityScanner, error) {
func getEnabledScanner(idGenerator ext.IDGenerator, config etc.Config, starboardConfig starboard.ConfigData) (scanner.VulnerabilityScanner, error) {
if config.ScannerTrivy.Enabled && config.ScannerAquaCSP.Enabled {
return nil, fmt.Errorf("invalid configuration: multiple vulnerability scanners enabled")
}
if !config.ScannerTrivy.Enabled && !config.ScannerAquaCSP.Enabled {
return nil, fmt.Errorf("invalid configuration: none vulnerability scanner enabled")
}
if config.ScannerTrivy.Enabled {
setupLog.Info("Using Trivy as vulnerability scanner", "image", config.ScannerTrivy.ImageRef)
return trivy.NewScanner(idGenerator, config.ScannerTrivy), nil
setupLog.Info("Using Trivy as vulnerability scanner", "image", starboardConfig.GetTrivyImageRef())
return trivy.NewScanner(idGenerator, starboardConfig), nil
}
if config.ScannerAquaCSP.Enabled {
setupLog.Info("Using Aqua CSP as vulnerability scanner", "image", config.ScannerAquaCSP.ImageRef)
Expand Down
7 changes: 7 additions & 0 deletions deploy/helm/templates/rbac.yaml
Expand Up @@ -36,6 +36,13 @@ rules:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- create
- apiGroups:
- apps
resources: # resources that own pods are inspected
Expand Down
7 changes: 7 additions & 0 deletions deploy/kubectl/03-starboard-operator.clusterrole.yaml
Expand Up @@ -14,6 +14,13 @@ rules:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- create
- apiGroups:
- apps
resources:
Expand Down
14 changes: 8 additions & 6 deletions pkg/cmd/cleanup.go
Expand Up @@ -3,6 +3,8 @@ package cmd
import (
"context"

"github.com/aquasecurity/starboard/pkg/starboard"

"github.com/aquasecurity/starboard/pkg/kube"
"github.com/spf13/cobra"
extapi "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1"
Expand All @@ -14,22 +16,22 @@ func NewCleanupCmd(cf *genericclioptions.ConfigFlags) *cobra.Command {
cmd := &cobra.Command{
Use: "cleanup",
Short: "Delete custom resource definitions created by starboard",
RunE: func(cmd *cobra.Command, args []string) (err error) {
RunE: func(cmd *cobra.Command, args []string) error {
ctx := context.Background()
config, err := cf.ToRESTConfig()
if err != nil {
return
return err
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
return
return err
}
clientsetext, err := extapi.NewForConfig(config)
if err != nil {
return
return err
}
err = kube.NewCRManager(clientset, clientsetext).Cleanup(ctx)
return
return kube.NewCRManager(starboard.NewConfigManager(clientset, starboard.NamespaceName), clientset, clientsetext).
Cleanup(ctx)
},
}
return cmd
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/config.go
Expand Up @@ -33,7 +33,7 @@ func NewConfigCmd(cf *genericclioptions.ConfigFlags, outWriter io.Writer) *cobra
if err != nil {
return
}
config, err := starboard.NewConfigReader(clientset).Read(ctx)
config, err := starboard.NewConfigManager(clientset, starboard.NamespaceName).Read(ctx)
if err != nil {
return
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/find_vulnerabilities.go
Expand Up @@ -72,7 +72,7 @@ NAME is the name of a particular Kubernetes workload.
if err != nil {
return err
}
config, err := starboard.NewConfigReader(kubernetesClientset).Read(ctx)
config, err := starboard.NewConfigManager(kubernetesClientset, starboard.NamespaceName).Read(ctx)
if err != nil {
return
}
Expand Down
20 changes: 10 additions & 10 deletions pkg/cmd/init.go
Expand Up @@ -3,6 +3,8 @@ package cmd
import (
"context"

"github.com/aquasecurity/starboard/pkg/starboard"

"github.com/aquasecurity/starboard/pkg/kube"
"github.com/spf13/cobra"
extensionsapi "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1"
Expand All @@ -14,8 +16,7 @@ func NewInitCmd(cf *genericclioptions.ConfigFlags) *cobra.Command {
cmd := &cobra.Command{
Use: "init",
Short: "Create custom resource definitions used by starboard",
Long: `
Create all the resources used by starboard. It will create the following
Long: `Create all the resources used by starboard. It will create the following
in the cluster:

- custom resource definitions
Expand All @@ -27,24 +28,23 @@ in the cluster:
The config map contains the default configuration parameters. However this
can be modified to change the behaviour of the scanner.

These resources can be removed from the cluster using the "cleanup" command.
`,
RunE: func(cmd *cobra.Command, args []string) (err error) {
These resources can be removed from the cluster using the "cleanup" command.`,
RunE: func(cmd *cobra.Command, args []string) error {
ctx := context.Background()
config, err := cf.ToRESTConfig()
if err != nil {
return
return err
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
return
return err
}
clientsetext, err := extensionsapi.NewForConfig(config)
if err != nil {
return
return err
}
err = kube.NewCRManager(clientset, clientsetext).Init(ctx)
return
return kube.NewCRManager(starboard.NewConfigManager(clientset, starboard.NamespaceName), clientset, clientsetext).
Init(ctx)
},
}
return cmd
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/kube_bench.go
Expand Up @@ -46,7 +46,7 @@ func NewKubeBenchCmd(cf *genericclioptions.ConfigFlags) *cobra.Command {
err = fmt.Errorf("listing nodes: %w", err)
return
}
config, err := starboard.NewConfigReader(kubernetesClientset).Read(ctx)
config, err := starboard.NewConfigManager(kubernetesClientset, starboard.NamespaceName).Read(ctx)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/ext/id_generator.go
Expand Up @@ -2,8 +2,9 @@ package ext

import (
"fmt"
"github.com/google/uuid"
"sync/atomic"

"github.com/google/uuid"
)

// IDGenerator defines contract for generating universally unique identifiers.
Expand Down
1 change: 1 addition & 0 deletions pkg/find/vulnerabilities/scanner.go
Expand Up @@ -2,6 +2,7 @@ package vulnerabilities

import (
"context"

"github.com/aquasecurity/starboard/pkg/docker"

starboard "github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
Expand Down
3 changes: 2 additions & 1 deletion pkg/find/vulnerabilities/trivy/scanner.go
Expand Up @@ -3,9 +3,10 @@ package trivy
import (
"context"
"fmt"
"github.com/aquasecurity/starboard/pkg/starboard"
"io"

"github.com/aquasecurity/starboard/pkg/starboard"

"github.com/aquasecurity/starboard/pkg/docker"
"github.com/aquasecurity/starboard/pkg/kube/secrets"
"github.com/aquasecurity/starboard/pkg/scanners"
Expand Down
51 changes: 16 additions & 35 deletions pkg/kube/cr_manager.go
Expand Up @@ -3,9 +3,10 @@ package kube
import (
"context"
"fmt"
"github.com/aquasecurity/starboard/pkg/starboard"
"time"

"github.com/aquasecurity/starboard/pkg/starboard"

"k8s.io/utils/pointer"

"k8s.io/apimachinery/pkg/labels"
Expand Down Expand Up @@ -44,15 +45,6 @@ var (
},
AutomountServiceAccountToken: pointer.BoolPtr(false),
}
configMap = &core.ConfigMap{
ObjectMeta: meta.ObjectMeta{
Name: starboard.ConfigMapName,
Labels: labels.Set{
"app.kubernetes.io/managed-by": "starboard",
},
},
Data: starboard.GetDefaultConfig(),
}
clusterRole = &rbac.ClusterRole{
ObjectMeta: meta.ObjectMeta{
Name: clusterRoleStarboard,
Expand Down Expand Up @@ -136,15 +128,20 @@ type CRManager interface {
}

type crManager struct {
clientset kubernetes.Interface
clientsetext extapi.ApiextensionsV1beta1Interface
configManager starboard.ConfigManager
clientset kubernetes.Interface
clientsetext extapi.ApiextensionsV1beta1Interface
}

// NewCRManager constructs a CRManager with the given Kubernetes interface.
func NewCRManager(clientset kubernetes.Interface, clientsetext extapi.ApiextensionsV1beta1Interface) CRManager {
// NewCRManager constructs a CRManager with the given starboard.ConfigManager and kubernetes.Interface.
func NewCRManager(
configManager starboard.ConfigManager,
clientset kubernetes.Interface,
clientsetext extapi.ApiextensionsV1beta1Interface) CRManager {
return &crManager{
clientset: clientset,
clientsetext: clientsetext,
configManager: configManager,
clientset: clientset,
clientsetext: clientsetext,
}
}

Expand Down Expand Up @@ -175,7 +172,7 @@ func (m *crManager) Init(ctx context.Context) (err error) {
return
}

err = m.createConfigMapIfNotFound(ctx, configMap)
err = m.configManager.EnsureDefault(ctx)
if err != nil {
return
}
Expand Down Expand Up @@ -275,21 +272,6 @@ func (m *crManager) createServiceAccountIfNotFound(ctx context.Context, sa *core
return
}

func (m *crManager) createConfigMapIfNotFound(ctx context.Context, cm *core.ConfigMap) (err error) {
name := cm.Name
_, err = m.clientset.CoreV1().ConfigMaps(starboard.NamespaceName).Get(ctx, name, meta.GetOptions{})
switch {
case err == nil:
klog.V(3).Infof("ConfigMap %q already exists", starboard.NamespaceName+"/"+name)
return
case errors.IsNotFound(err):
klog.V(3).Infof("Creating ConfigMap %q", starboard.NamespaceName+"/"+name)
_, err = m.clientset.CoreV1().ConfigMaps(starboard.NamespaceName).Create(ctx, cm, meta.CreateOptions{})
return
}
return
}

func (m *crManager) createOrUpdateClusterRole(ctx context.Context, cr *rbac.ClusterRole) (err error) {
existingRole, err := m.clientset.RbacV1().ClusterRoles().Get(ctx, cr.GetName(), meta.GetOptions{})
switch {
Expand Down Expand Up @@ -374,9 +356,8 @@ func (m *crManager) Cleanup(ctx context.Context) (err error) {
return
}

klog.V(3).Infof("Deleting ConfigMap %q", starboard.NamespaceName+"/"+starboard.ConfigMapName)
err = m.clientset.CoreV1().ConfigMaps(starboard.NamespaceName).Delete(ctx, starboard.ConfigMapName, meta.DeleteOptions{})
if err != nil && !errors.IsNotFound(err) {
err = m.configManager.Delete(ctx)
if err != nil {
return
}

Expand Down
3 changes: 2 additions & 1 deletion pkg/kube/runnable_job.go
Expand Up @@ -3,9 +3,10 @@ package kube
import (
"context"
"fmt"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"time"

meta "k8s.io/apimachinery/pkg/apis/meta/v1"

"k8s.io/klog"

"k8s.io/apimachinery/pkg/util/wait"
Expand Down