Skip to content

Commit df73735

Browse files
authored
[Improvement] Use stanradized k8s object handlers (#1659)
1 parent ccdf309 commit df73735

File tree

8 files changed

+445
-144
lines changed

8 files changed

+445
-144
lines changed

.golangci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ linters-settings:
4444
- pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1
4545
alias: schedulerApi
4646
- pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/profiles
47-
alias: schedulerProfilesv1beta1
47+
alias: schedulerProfiles
4848
- pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container
4949
alias: schedulerContainerApi
5050
- pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container/resources

pkg/util/compare/k8s/filter.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package k8s
22+
23+
import (
24+
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
25+
)
26+
27+
type FilterFunc[T any] func(in T) T
28+
29+
func FilterP[T any](in *T, filters ...FilterFunc[*T]) *T {
30+
if in == nil {
31+
return nil
32+
}
33+
34+
return Filter(in, filters...)
35+
}
36+
37+
func Filter[T any](in T, filters ...FilterFunc[T]) T {
38+
for _, f := range filters {
39+
in = f(in)
40+
}
41+
42+
return in
43+
}
44+
45+
func ObjectMetaFilter(in meta.ObjectMeta) meta.ObjectMeta {
46+
return meta.ObjectMeta{
47+
Labels: in.Labels,
48+
Annotations: in.Annotations,
49+
OwnerReferences: in.OwnerReferences,
50+
Finalizers: in.Finalizers,
51+
}
52+
}

pkg/util/compare/k8s/service.go

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2023 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2023-2024 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -21,21 +21,56 @@
2121
package k8s
2222

2323
import (
24+
"fmt"
25+
2426
core "k8s.io/api/core/v1"
2527

28+
"github.com/arangodb/kube-arangodb/pkg/logging"
2629
"github.com/arangodb/kube-arangodb/pkg/util"
30+
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/helpers"
2731
)
2832

29-
func ChecksumService(s *core.Service) (string, error) {
30-
return checksumServiceSpec(&s.Spec)
33+
func CoreService(in *core.Service) *core.Service {
34+
return FilterP(in, func(in *core.Service) *core.Service {
35+
return &core.Service{
36+
ObjectMeta: ObjectMetaFilter(in.ObjectMeta),
37+
Spec: Filter(in.Spec, func(in core.ServiceSpec) core.ServiceSpec {
38+
return core.ServiceSpec{
39+
Type: in.Type,
40+
Ports: in.Ports,
41+
Selector: in.Selector,
42+
}
43+
}),
44+
}
45+
})
46+
}
47+
48+
func CoreServiceChecksum(in *core.Service) (string, error) {
49+
return util.SHA256FromJSON(CoreService(in))
3150
}
3251

33-
func checksumServiceSpec(s *core.ServiceSpec) (string, error) {
34-
parts := map[string]interface{}{
35-
"type": s.Type,
36-
"ports": s.Ports,
37-
"selector": s.Selector,
38-
// add here more fields when needed
39-
}
40-
return util.SHA256FromJSON(parts)
52+
func CoreServiceImmutableRecreate(logger logging.Logger) helpers.Decision[*core.Service] {
53+
return helpers.NewImmutableFields[*core.Service](func(a, b *core.Service, changes map[string]string) helpers.Action {
54+
if len(changes) > 0 {
55+
s := logger
56+
57+
for k, v := range changes {
58+
s = s.Str(fmt.Sprintf("field%s", k), v)
59+
}
60+
61+
s.Info("Replace of Service %s required", a.GetName())
62+
return helpers.ActionReplace
63+
}
64+
65+
return helpers.ActionOK
66+
}).Evaluate(
67+
helpers.SubCompare[*core.Service, core.ServiceSpec](".spec", func(in *core.Service) core.ServiceSpec {
68+
if in == nil {
69+
return core.ServiceSpec{}
70+
}
71+
return in.Spec
72+
}, helpers.FromSimpleCompareStack(".type", func(a, b core.ServiceSpec) (string, bool) {
73+
return "ServiceType change requires object recreation", a.Type != b.Type
74+
})),
75+
)
4176
}
Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2023 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2023-2024 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -21,23 +21,49 @@
2121
package k8s
2222

2323
import (
24+
"fmt"
25+
2426
apps "k8s.io/api/apps/v1"
2527

28+
"github.com/arangodb/kube-arangodb/pkg/logging"
2629
"github.com/arangodb/kube-arangodb/pkg/util"
30+
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/helpers"
2731
)
2832

29-
func ChecksumStatefulSet(s *apps.StatefulSet) (string, error) {
30-
return checksumStatefulSetSpec(&s.Spec)
33+
func AppsStatefulSet(in *apps.StatefulSet) *apps.StatefulSet {
34+
return FilterP(in, func(in *apps.StatefulSet) *apps.StatefulSet {
35+
return &apps.StatefulSet{
36+
ObjectMeta: ObjectMetaFilter(in.ObjectMeta),
37+
Spec: Filter(in.Spec, func(in apps.StatefulSetSpec) apps.StatefulSetSpec {
38+
return apps.StatefulSetSpec{
39+
Template: in.Template,
40+
Replicas: in.Replicas,
41+
MinReadySeconds: in.MinReadySeconds,
42+
Selector: in.Selector,
43+
ServiceName: in.ServiceName,
44+
}
45+
}),
46+
}
47+
})
48+
}
49+
50+
func AppsStatefulSetChecksum(in *apps.StatefulSet) (string, error) {
51+
return util.SHA256FromJSON(AppsStatefulSet(in))
3152
}
3253

33-
func checksumStatefulSetSpec(s *apps.StatefulSetSpec) (string, error) {
34-
parts := map[string]interface{}{
35-
"replicas": s.Replicas,
36-
"serviceName": s.ServiceName,
37-
"minReadySeconds": s.MinReadySeconds,
38-
"selector": s.Selector,
39-
"template": s.Template,
40-
// add here more fields when needed
41-
}
42-
return util.SHA256FromJSON(parts)
54+
func AppsStatefulSetRecreate(logger logging.Logger) helpers.Decision[*apps.StatefulSet] {
55+
return helpers.NewImmutableFields[*apps.StatefulSet](func(a, b *apps.StatefulSet, changes map[string]string) helpers.Action {
56+
if len(changes) > 0 {
57+
s := logger
58+
59+
for k, v := range changes {
60+
s = s.Str(fmt.Sprintf("field%s", k), v)
61+
}
62+
63+
s.Info("Replace of StatefulSet %s required", a.GetName())
64+
return helpers.ActionReplace
65+
}
66+
67+
return helpers.ActionOK
68+
}).Evaluate()
4369
}

0 commit comments

Comments
 (0)