Skip to content

Commit

Permalink
feat(operator): Allow configuring scanners
Browse files Browse the repository at this point in the history
Resolves: #212

Signed-off-by: Daniel Pacak <pacak.daniel@gmail.com>
  • Loading branch information
danielpacak committed Oct 23, 2020
1 parent cf4be11 commit 8c8883d
Show file tree
Hide file tree
Showing 19 changed files with 267 additions and 99 deletions.
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 ConfigWriter and Kubernetes interfaces.
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

0 comments on commit 8c8883d

Please sign in to comment.