Skip to content

Commit

Permalink
Merge branch 'feature/221_security_context' into feature/221_security…
Browse files Browse the repository at this point in the history
…_context_update_deployment
  • Loading branch information
nroeske committed Dec 19, 2024
2 parents e16bb5e + fbca234 commit 1063464
Show file tree
Hide file tree
Showing 18 changed files with 594 additions and 9 deletions.
46 changes: 46 additions & 0 deletions api/v2/dogu_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ package v2
import (
"context"
"embed"
"errors"
"fmt"
"github.com/cloudogu/cesapp-lib/core"
"github.com/cloudogu/retry-lib/retry"
appsv1 "k8s.io/api/apps/v1"
"k8s.io/apimachinery/pkg/api/resource"
"slices"
"time"

corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -42,6 +45,16 @@ const (
DoguLabelVersion = "dogu.version"
)

// AllCapabilities are all possible values for capabilities.
var AllCapabilities = func() []Capability {
// To avoid duplication and deviations, we copy these from cesapp-lib.
allCapabilities := make([]Capability, len(core.AllCapabilities), len(core.AllCapabilities))
for i, capability := range core.AllCapabilities {
allCapabilities[i] = Capability(capability)
}
return allCapabilities
}()

// DoguSpec defines the desired state of a Dogu
type DoguSpec struct {
// Name of the dogu (e.g. official/ldap)
Expand Down Expand Up @@ -353,6 +366,39 @@ func (d *Dogu) GetPrivateKeySecret(ctx context.Context, cli client.Client) (*cor
return secret, nil
}

// ValidateSecurity checks the dogu's Security section for configuration errors.
func (d *Dogu) ValidateSecurity() error {
var errs []error
for _, value := range d.Spec.Security.Capabilities.Add {
if value == core.All {
continue
}

if !slices.Contains(AllCapabilities, value) {
err := fmt.Errorf("%s is not a valid capability to be added", value)
errs = append(errs, err)
}
}

for _, value := range d.Spec.Security.Capabilities.Drop {
if value == core.All {
continue
}

if !slices.Contains(AllCapabilities, value) {
err := fmt.Errorf("%s is not a valid capability to be dropped", value)
errs = append(errs, err)
}
}

err := errors.Join(errs...)
if err != nil {
return fmt.Errorf("dogu resource %s:%s contains at least one invalid security field: %w", d.Spec.Name, d.Spec.Version, err)
}

return nil
}

// +kubebuilder:object:root=true

// DoguList contains a list of Dogu
Expand Down
53 changes: 53 additions & 0 deletions api/v2/dogu_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/cloudogu/cesapp-lib/core"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
eventV1 "k8s.io/api/events/v1"
Expand Down Expand Up @@ -513,3 +515,54 @@ func TestDogu_NextRequeueWithRetry(t *testing.T) {
assert.ErrorContains(t, err, "dogus.k8s.cloudogu.com \"postgresql\" not found")
})
}

func TestDogu_ValidateSecurity(t *testing.T) {
type args struct {
dogu *Dogu
}
tests := []struct {
name string
args args
wantErr assert.ErrorAssertionFunc
}{
{"valid empty", args{&Dogu{}}, assert.NoError},
{"valid add filled", args{&Dogu{Spec: DoguSpec{Security: Security{Capabilities: Capabilities{Add: []Capability{core.AuditControl}}}}}}, assert.NoError},
{"valid add filled", args{&Dogu{Spec: DoguSpec{Security: Security{Capabilities: Capabilities{Drop: []Capability{core.AuditControl}}}}}}, assert.NoError},
{"all possible values", args{&Dogu{Spec: DoguSpec{Security: Security{Capabilities: Capabilities{Add: AllCapabilities, Drop: AllCapabilities}}}}}, assert.NoError},
{"add all keyword", args{&Dogu{Spec: DoguSpec{Security: Security{Capabilities: Capabilities{Add: []Capability{core.All}}}}}}, assert.NoError},
{"drop all keyword", args{&Dogu{Spec: DoguSpec{Security: Security{Capabilities: Capabilities{Drop: []Capability{core.All}}}}}}, assert.NoError},

{"invalid valid add filled", args{&Dogu{Spec: DoguSpec{Security: Security{Capabilities: Capabilities{Add: []Capability{"err"}}}}}}, assert.Error},
{"invalid valid drop filled", args{&Dogu{Spec: DoguSpec{Security: Security{Capabilities: Capabilities{Drop: []Capability{"err"}}}}}}, assert.Error},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.wantErr(t, tt.args.dogu.ValidateSecurity(), fmt.Sprintf("ValidateSecurity(%v)", tt.args.dogu))
})
}
}

func TestDogu_ValidateSecurity_message(t *testing.T) {
t.Run("should match for drop errors", func(t *testing.T) {
// given
dogu := &Dogu{Spec: DoguSpec{Name: "official/dogu", Version: "1.2.3", Security: Security{Capabilities: Capabilities{Drop: []Capability{"err"}}}}}

// when
actual := dogu.ValidateSecurity()

// then
require.Error(t, actual)
assert.ErrorContains(t, actual, "dogu resource official/dogu:1.2.3 contains at least one invalid security field: err is not a valid capability to be dropped")
})
t.Run("should match for add errors", func(t *testing.T) {
// given
dogu := &Dogu{Spec: DoguSpec{Name: "official/dogu", Version: "1.2.3", Security: Security{Capabilities: Capabilities{Add: []Capability{"err"}}}}}

// when
actual := dogu.ValidateSecurity()

// then
require.Error(t, actual)
assert.ErrorContains(t, actual, "dogu resource official/dogu:1.2.3 contains at least one invalid security field: err is not a valid capability to be added")
})
}
9 changes: 9 additions & 0 deletions controllers/doguInstallManager.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type doguInstallManager struct {
execPodFactory exec.ExecPodFactory
doguConfigRepository doguConfigRepository
sensitiveDoguRepository doguConfigRepository
securityValidator securityValidator
}

// NewDoguInstallManager creates a new instance of doguInstallManager.
Expand All @@ -63,6 +64,7 @@ func NewDoguInstallManager(client client.Client, mgrSet *util.ManagerSet, eventR
execPodFactory: exec.NewExecPodFactory(client, mgrSet.RestConfig, mgrSet.CommandExecutor),
doguConfigRepository: configRepos.DoguConfigRepository,
sensitiveDoguRepository: configRepos.SensitiveDoguRepository,
securityValidator: mgrSet.SecurityValidator,
}
}

Expand Down Expand Up @@ -100,6 +102,13 @@ func (m *doguInstallManager) Install(ctx context.Context, doguResource *k8sv2.Do
return err
}

logger.Info("Validating dogu security...")
m.recorder.Event(doguResource, corev1.EventTypeNormal, InstallEventReason, "Validating dogu security...")
err = m.securityValidator.ValidateSecurity(dogu, doguResource)
if err != nil {
return err
}

logger.Info("Create dogu config and sensitive dogu config...")
m.recorder.Event(doguResource, corev1.EventTypeNormal, InstallEventReason, "Create dogu and sensitive config...")
cleanUp, err := m.createConfigs(ctx, doguResource.Name, logger)
Expand Down
Loading

0 comments on commit 1063464

Please sign in to comment.