Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added
- [#121] Added use case to check if dogus actually use the desired version and config before completing the blueprint
- [#129] Reconciliation of the blueprint on changes of dogu-crs, ces-configMaps and ces-secrets

### Changed
- [#119] *breaking* sensitive dogu config can now only be referenced with secrets
Expand Down
2 changes: 2 additions & 0 deletions k8s/helm/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ spec:
name: ces-proxy
key: url
optional: true
- name: DEBOUNCE_WINDOW
value: {{ quote .Values.manager.reconciler.debounceWindow | default "10s" }}
image: "{{ .Values.manager.image.registry }}/{{ .Values.manager.image.repository }}:{{ .Values.manager.image.tag | default .Chart.AppVersion }}"
livenessProbe:
httpGet:
Expand Down
20 changes: 18 additions & 2 deletions k8s/helm/templates/manager-role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,26 @@ rules:
resources:
- secrets
verbs:
- create
- update
- get
- list # needed, as the registry-lib seems to need that for a normal get command
- watch
# issue PVC read-only permissions to amend the Blueprint CR with a currently configured Dogu volume size
- apiGroups:
- ""
resources:
- configmaps # for normal dogu config
verbs:
- get
- list # needed, as the registry-lib seems to need that for a normal get command
- watch
- apiGroups:
- k8s.cloudogu.com
resources:
- dogus
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
Expand Down
2 changes: 2 additions & 0 deletions k8s/helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ manager:
memory: 105M
networkPolicies:
enabled: true
reconciler:
debounceWindow: 10s
doguRegistry:
certificate:
secret: dogu-registry-cert
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/cloudogu/k8s-blueprint-operator/v2/pkg"
"github.com/cloudogu/k8s-blueprint-operator/v2/pkg/adapter/reconciler"
"github.com/cloudogu/k8s-blueprint-operator/v2/pkg/config"
v2 "github.com/cloudogu/k8s-dogu-lib/v2/api/v2"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
Expand Down Expand Up @@ -46,6 +47,7 @@ func init() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))

utilruntime.Must(bpv2.AddToScheme(scheme))
utilruntime.Must(v2.AddToScheme(scheme))
// +kubebuilder:scaffold:scheme
}

Expand Down
7 changes: 6 additions & 1 deletion main_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"testing"

"github.com/go-logr/logr"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -181,6 +180,7 @@ func Test_startOperator(t *testing.T) {
t.Setenv("DOGU_REGISTRY_ENDPOINT", "dogu.example.com")
t.Setenv("DOGU_REGISTRY_USERNAME", "user")
t.Setenv("DOGU_REGISTRY_PASSWORD", "password")
t.Setenv("DEBOUNCE_WINDOW", "10s")

oldNewManagerFunc := ctrl.NewManager
oldGetConfigFunc := ctrl.GetConfigOrDie
Expand All @@ -196,6 +196,7 @@ func Test_startOperator(t *testing.T) {
//ctrlManMock.EXPECT().GetConfig().Return(restConfig)
ctrlManMock.EXPECT().GetControllerOptions().Return(config.Controller{})
ctrlManMock.EXPECT().GetScheme().Return(runtime.NewScheme())
ctrlManMock.EXPECT().GetCache().Return(nil)

ctrl.NewManager = func(config *rest.Config, options manager.Options) (manager.Manager, error) {
return ctrlManMock, nil
Expand All @@ -220,6 +221,7 @@ func Test_startOperator(t *testing.T) {
t.Setenv("DOGU_REGISTRY_ENDPOINT", "dogu.example.com")
t.Setenv("DOGU_REGISTRY_USERNAME", "user")
t.Setenv("DOGU_REGISTRY_PASSWORD", "password")
t.Setenv("DEBOUNCE_WINDOW", "10s")

oldNewManagerFunc := ctrl.NewManager
oldGetConfigFunc := ctrl.GetConfigOrDie
Expand Down Expand Up @@ -268,6 +270,7 @@ func Test_startOperator(t *testing.T) {
t.Setenv("DOGU_REGISTRY_ENDPOINT", "dogu.example.com")
t.Setenv("DOGU_REGISTRY_USERNAME", "user")
t.Setenv("DOGU_REGISTRY_PASSWORD", "password")
t.Setenv("DEBOUNCE_WINDOW", "10s")

oldNewManagerFunc := ctrl.NewManager
oldGetConfigFunc := ctrl.GetConfigOrDie
Expand Down Expand Up @@ -317,6 +320,7 @@ func Test_startOperator(t *testing.T) {
t.Setenv("DOGU_REGISTRY_ENDPOINT", "dogu.example.com")
t.Setenv("DOGU_REGISTRY_USERNAME", "user")
t.Setenv("DOGU_REGISTRY_PASSWORD", "password")
t.Setenv("DEBOUNCE_WINDOW", "10s")

oldNewManagerFunc := ctrl.NewManager
oldGetConfigFunc := ctrl.GetConfigOrDie
Expand Down Expand Up @@ -372,6 +376,7 @@ func Test_startOperator(t *testing.T) {
t.Setenv("DOGU_REGISTRY_ENDPOINT", "dogu.example.com")
t.Setenv("DOGU_REGISTRY_USERNAME", "user")
t.Setenv("DOGU_REGISTRY_PASSWORD", "password")
t.Setenv("DEBOUNCE_WINDOW", "10s")

oldNewManagerFunc := ctrl.NewManager
oldGetConfigFunc := ctrl.GetConfigOrDie
Expand Down
16 changes: 16 additions & 0 deletions pkg/adapter/kubernetes/blueprintcr/v2/blueprintSpecCRRepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,22 @@ func (repo *blueprintSpecRepo) CheckSingleton(ctx context.Context) error {
}
}

func (repo *blueprintSpecRepo) ListIds(ctx context.Context) ([]string, error) {
list, err := repo.blueprintClient.List(ctx, metav1.ListOptions{})
if err != nil {
return nil, &domainservice.InternalError{
WrappedError: err,
Message: "error while listing blueprint resources",
}
}

result := make([]string, len(list.Items))
for index, blueprint := range list.Items {
result[index] = blueprint.Name
}
return result, nil
}

func (repo *blueprintSpecRepo) serializeBlueprintAndMask(blueprintSpec *domain.BlueprintSpec, blueprintCR *v2.Blueprint, blueprintId string) error {
blueprint, blueprintErr := serializerv2.ConvertToBlueprintDomain(blueprintCR.Spec.Blueprint)
if blueprintErr != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ func Test_blueprintSpecRepo_CheckSingleton(t *testing.T) {
eventRecorderMock := newMockEventRecorder(t)
repo := NewBlueprintSpecRepository(restClientMock, eventRecorderMock)

restClientMock.EXPECT().List(ctx, metav1.ListOptions{Limit: 2}).Return(nil, nil)
restClientMock.EXPECT().List(ctx, mock.Anything).Return(nil, nil)

// when
err := repo.CheckSingleton(ctx)
Expand All @@ -413,7 +413,7 @@ func Test_blueprintSpecRepo_CheckSingleton(t *testing.T) {
restClientMock := newMockBlueprintInterface(t)
eventRecorderMock := newMockEventRecorder(t)
repo := NewBlueprintSpecRepository(restClientMock, eventRecorderMock)
restClientMock.EXPECT().List(ctx, metav1.ListOptions{Limit: 2}).Return(&bpv2.BlueprintList{}, nil)
restClientMock.EXPECT().List(ctx, mock.Anything).Return(&bpv2.BlueprintList{}, nil)

// when
err := repo.CheckSingleton(ctx)
Expand All @@ -435,7 +435,7 @@ func Test_blueprintSpecRepo_CheckSingleton(t *testing.T) {
},
},
}
restClientMock.EXPECT().List(ctx, metav1.ListOptions{Limit: 2}).Return(list, nil)
restClientMock.EXPECT().List(ctx, mock.Anything).Return(list, nil)

// when
err := repo.CheckSingleton(ctx)
Expand All @@ -462,7 +462,7 @@ func Test_blueprintSpecRepo_CheckSingleton(t *testing.T) {
},
},
}
restClientMock.EXPECT().List(ctx, metav1.ListOptions{Limit: 2}).Return(list, nil)
restClientMock.EXPECT().List(ctx, mock.Anything).Return(list, nil)

// when
err := repo.CheckSingleton(ctx)
Expand All @@ -479,7 +479,7 @@ func Test_blueprintSpecRepo_CheckSingleton(t *testing.T) {
eventRecorderMock := newMockEventRecorder(t)
repo := NewBlueprintSpecRepository(restClientMock, eventRecorderMock)

restClientMock.EXPECT().List(ctx, metav1.ListOptions{Limit: 2}).Return(nil, assert.AnError)
restClientMock.EXPECT().List(ctx, mock.Anything).Return(nil, assert.AnError)

// when
err := repo.CheckSingleton(ctx)
Expand All @@ -491,3 +491,52 @@ func Test_blueprintSpecRepo_CheckSingleton(t *testing.T) {
assert.ErrorContains(t, err, "error while listing blueprint resources")
})
}

func Test_blueprintSpecRepo_ListIds(t *testing.T) {
t.Run("success", func(t *testing.T) {
restClientMock := newMockBlueprintInterface(t)
repo := NewBlueprintSpecRepository(restClientMock, nil)

returnList := bpv2.BlueprintList{Items: []bpv2.Blueprint{
{
ObjectMeta: metav1.ObjectMeta{
Name: "test1",
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "test2",
},
},
}}

restClientMock.EXPECT().List(ctx, metav1.ListOptions{}).Return(&returnList, nil)

// when
idList, err := repo.ListIds(ctx)

// then
require.NoError(t, err)
assert.Len(t, idList, 2)
assert.Contains(t, idList, "test1")
assert.Contains(t, idList, "test2")
})

t.Run("throw internal error on list error", func(t *testing.T) {
restClientMock := newMockBlueprintInterface(t)
repo := NewBlueprintSpecRepository(restClientMock, nil)

restClientMock.EXPECT().List(ctx, metav1.ListOptions{}).Return(nil, assert.AnError)

// when
list, err := repo.ListIds(ctx)

// then
require.Error(t, err)
assert.Nil(t, list)
var targetErr *domainservice.InternalError
assert.ErrorAs(t, err, &targetErr)
assert.ErrorContains(t, err, "error while listing blueprint resources")
})

}
Loading