Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
19b8900
#129 Reconciliation of the blueprint on changes in managed resources
meiserloh Oct 2, 2025
99373b0
Merge remote-tracking branch 'origin/feature/121.3-remove-components'…
meiserloh Oct 2, 2025
8e34e1d
#129 add debounce touch on reconcile start to avoid more unnecessary …
meiserloh Oct 2, 2025
d4404b2
Merge remote-tracking branch 'origin/feature/121.3-remove-components'…
meiserloh Oct 2, 2025
4a16b12
#129 remove debounce touch, because it can omit trailing events that …
meiserloh Oct 2, 2025
ff6d472
#129 handle error on reading debounce window env var
meiserloh Oct 3, 2025
ac69f8e
#129 fix main tests
meiserloh Oct 3, 2025
84cd5e6
#129 include global config in config map watches
meiserloh Oct 6, 2025
f872244
Merge remote-tracking branch 'origin/feature/121.3-remove-components'…
meiserloh Oct 7, 2025
1f77c86
Merge remote-tracking branch 'origin/feature/121.3-remove-components'…
meiserloh Oct 7, 2025
fb0f915
#129 replace List-call with ListIds to avoid working on api-objects
meiserloh Oct 7, 2025
6a06d82
Merge remote-tracking branch 'origin/feature/121.3-remove-components'…
meiserloh Oct 7, 2025
22b0d52
Merge remote-tracking branch 'origin/feature/121.3-remove-components'…
meiserloh Oct 8, 2025
3f347d9
Merge remote-tracking branch 'origin/feature/121.3-remove-components'…
meiserloh Oct 8, 2025
106b8e5
Merge remote-tracking branch 'origin/feature/121.3-remove-components'…
meiserloh Oct 10, 2025
e553d88
Merge branch 'v2/develop' into feature/129-reconcile-on-secondary-res…
alexander-dammeier Oct 17, 2025
00628fc
#121 fix problems after merge
alexander-dammeier Oct 17, 2025
48c6bf6
#121 fix adapter docs breaking the abstraction
alexander-dammeier Oct 17, 2025
c0c2085
#129 reconcile all secrets in the operator namespace
meiserloh Oct 20, 2025
3ed0f13
#129 integrate secrets into UpToDate-Check
meiserloh Oct 20, 2025
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 @@ -108,6 +108,22 @@ func (repo *blueprintSpecRepo) Count(ctx context.Context, limit int) (int, error
return len(list.Items), nil
}

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
}

// Update persists changes in the blueprint to the corresponding blueprint CR.
func (repo *blueprintSpecRepo) Update(ctx context.Context, spec *domain.BlueprintSpec) error {
logger := log.FromContext(ctx).WithName("blueprintSpecRepo.Update")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -481,3 +481,52 @@ func Test_blueprintSpecRepo_Count(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