Skip to content

Commit b7114fa

Browse files
authored
[Feature] Add Labels and Envs customization (#586)
1 parent d562b93 commit b7114fa

File tree

15 files changed

+812
-51
lines changed

15 files changed

+812
-51
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- Add Kustomize support
88
- Improve Helm 3 support
99
- Allow to customize ID Pod selectors
10+
- Add Label and Envs Pod customization
1011

1112
## [1.0.3](https://github.com/arangodb/kube-arangodb/tree/1.0.3) (2020-05-25)
1213
- Prevent deletion of not known PVC's

pkg/apis/deployment/v1/deployment_spec.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ type DeploymentSpec struct {
6464

6565
// Annotations specified the annotations added to all resources
6666
Annotations map[string]string `json:"annotations,omitempty"`
67+
// Labels specified the labels added to all resources
68+
Labels map[string]string `json:"labels,omitempty"`
6769

6870
RestoreFrom *string `json:"restoreFrom,omitempty"`
6971

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2020 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+
// Author Adam Janikowski
21+
//
22+
23+
package v1
24+
25+
type ServerGroupEnvVars []ServerGroupEnvVar
26+
27+
type ServerGroupEnvVar struct {
28+
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
29+
Value string `json:"value,omitempty"`
30+
}

pkg/apis/deployment/v1/server_group_spec.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ type ServerGroupSpec struct {
5858
Tolerations []core.Toleration `json:"tolerations,omitempty"`
5959
// Annotations specified the annotations added to Pods in this group.
6060
Annotations map[string]string `json:"annotations,omitempty"`
61+
// Labels specified the labels added to Pods in this group.
62+
Labels map[string]string `json:"labels,omitempty"`
63+
// Envs allow to specify additional envs in this group.
64+
Envs ServerGroupEnvVars `json:"envs,omitempty"`
6165
// ServiceAccountName specifies the name of the service account used for Pods in this group.
6266
ServiceAccountName *string `json:"serviceAccountName,omitempty"`
6367
// NodeSelector speficies a set of selectors for nodes

pkg/apis/deployment/v1/zz_generated.deepcopy.go

Lines changed: 55 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/deployment/deployment_inspector.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,10 @@ func (d *Deployment) ensureResources(lastInterval util.Interval, cachedStatus in
301301
return minInspectionInterval, errors.Wrapf(err, "Annotation update failed")
302302
}
303303

304+
if err := d.resources.EnsureLabels(cachedStatus); err != nil {
305+
return minInspectionInterval, errors.Wrapf(err, "Labels update failed")
306+
}
307+
304308
return lastInterval, nil
305309
}
306310

pkg/deployment/patch/item.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,18 @@ const (
3838

3939
var _ json.Marshaler = &Path{}
4040

41+
func EscapePatchElement(element string) string {
42+
return strings.ReplaceAll(element, "/", "~1") // https://tools.ietf.org/html/rfc6901#section-3
43+
}
44+
4145
func NewPath(items ...string) Path {
42-
return items
46+
i := make([]string, len(items))
47+
48+
for id, item := range items {
49+
i[id] = EscapePatchElement(item)
50+
}
51+
52+
return i
4353
}
4454

4555
type Path []string

pkg/deployment/reconcile/plan_builder_test.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import (
2828
"io/ioutil"
2929
"testing"
3030

31+
policy "k8s.io/api/policy/v1beta1"
32+
3133
"github.com/arangodb/kube-arangodb/pkg/deployment/resources/inspector"
3234

3335
backupApi "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1"
@@ -533,10 +535,12 @@ func TestCreatePlan(t *testing.T) {
533535
ExpectedLog string
534536
ExpectedEvent *k8sutil.Event
535537

536-
Pods map[string]*core.Pod
537-
Secrets map[string]*core.Secret
538-
Services map[string]*core.Service
539-
PVCS map[string]*core.PersistentVolumeClaim
538+
Pods map[string]*core.Pod
539+
Secrets map[string]*core.Secret
540+
Services map[string]*core.Service
541+
PVCS map[string]*core.PersistentVolumeClaim
542+
ServiceAccounts map[string]*core.ServiceAccount
543+
PDBS map[string]*policy.PodDisruptionBudget
540544
}{
541545
{
542546
Name: "Can not create plan for single deployment",
@@ -796,7 +800,7 @@ func TestCreatePlan(t *testing.T) {
796800
if testCase.Helper != nil {
797801
testCase.Helper(testCase.context.ArangoDeployment)
798802
}
799-
err, _ := r.CreatePlan(ctx, inspector.NewInspectorFromData(testCase.Pods, testCase.Secrets, testCase.PVCS, testCase.Services))
803+
err, _ := r.CreatePlan(ctx, inspector.NewInspectorFromData(testCase.Pods, testCase.Secrets, testCase.PVCS, testCase.Services, testCase.ServiceAccounts, testCase.PDBS))
800804

801805
// Assert
802806
if testCase.ExpectedEvent != nil {

pkg/deployment/resources/annotations.go

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ func (r *Resources) EnsureAnnotations(cachedStatus inspector.Inspector) error {
5454
}
5555

5656
if err := ensureServiceAccountsAnnotations(kubecli.CoreV1().ServiceAccounts(r.context.GetNamespace()),
57+
cachedStatus,
5758
deployment.ArangoDeploymentResourceKind,
5859
r.context.GetAPIObject().GetName(),
5960
r.context.GetAPIObject().GetNamespace(),
@@ -71,6 +72,7 @@ func (r *Resources) EnsureAnnotations(cachedStatus inspector.Inspector) error {
7172
}
7273

7374
if err := ensurePdbsAnnotations(kubecli.PolicyV1beta1().PodDisruptionBudgets(r.context.GetNamespace()),
75+
cachedStatus,
7476
deployment.ArangoDeploymentResourceKind,
7577
r.context.GetAPIObject().GetName(),
7678
r.context.GetAPIObject().GetNamespace(),
@@ -137,22 +139,20 @@ func setSecretAnnotations(client typedCore.SecretInterface, secret *core.Secret,
137139
})
138140
}
139141

140-
func ensureServiceAccountsAnnotations(client typedCore.ServiceAccountInterface, kind, name, namespace string, annotations map[string]string) error {
141-
serviceAccounts, err := k8sutil.GetServiceAccountsForParent(client,
142-
kind,
143-
name,
144-
namespace)
145-
if err != nil {
146-
return err
147-
}
148-
149-
for _, serviceAccount := range serviceAccounts {
142+
func ensureServiceAccountsAnnotations(client typedCore.ServiceAccountInterface, cachedStatus inspector.Inspector, kind, name, namespace string, annotations map[string]string) error {
143+
if err := cachedStatus.IterateServiceAccounts(func(serviceAccount *core.ServiceAccount) error {
150144
if !k8sutil.CompareAnnotations(serviceAccount.GetAnnotations(), annotations) {
151145
log.Info().Msgf("Replacing annotations for ServiceAccount %s", serviceAccount.Name)
152-
if err = setServiceAccountAnnotations(client, serviceAccount, annotations); err != nil {
146+
if err := setServiceAccountAnnotations(client, serviceAccount, annotations); err != nil {
153147
return err
154148
}
155149
}
150+
151+
return nil
152+
}, func(serviceAccount *core.ServiceAccount) bool {
153+
return k8sutil.IsChildResource(kind, name, namespace, serviceAccount)
154+
}); err != nil {
155+
return err
156156
}
157157

158158
return nil
@@ -213,22 +213,20 @@ func setServiceAnnotations(client typedCore.ServiceInterface, service *core.Serv
213213
})
214214
}
215215

216-
func ensurePdbsAnnotations(client policyTyped.PodDisruptionBudgetInterface, kind, name, namespace string, annotations map[string]string) error {
217-
podDisruptionBudgets, err := k8sutil.GetPDBForParent(client,
218-
kind,
219-
name,
220-
namespace)
221-
if err != nil {
222-
return err
223-
}
224-
225-
for _, podDisruptionBudget := range podDisruptionBudgets {
216+
func ensurePdbsAnnotations(client policyTyped.PodDisruptionBudgetInterface, cachedStatus inspector.Inspector, kind, name, namespace string, annotations map[string]string) error {
217+
if err := cachedStatus.IteratePodDisruptionBudgets(func(podDisruptionBudget *policy.PodDisruptionBudget) error {
226218
if !k8sutil.CompareAnnotations(podDisruptionBudget.GetAnnotations(), annotations) {
227-
log.Info().Msgf("Replacing annotations for PDB %s", podDisruptionBudget.Name)
228-
if err = setPdbAnnotations(client, podDisruptionBudget, annotations); err != nil {
219+
log.Info().Msgf("Replacing annotations for PodDisruptionBudget %s", podDisruptionBudget.Name)
220+
if err := setPdbAnnotations(client, podDisruptionBudget, annotations); err != nil {
229221
return err
230222
}
231223
}
224+
225+
return nil
226+
}, func(podDisruptionBudget *policy.PodDisruptionBudget) bool {
227+
return k8sutil.IsChildResource(kind, name, namespace, podDisruptionBudget)
228+
}); err != nil {
229+
return err
232230
}
233231

234232
return nil
@@ -289,17 +287,23 @@ func setPvcAnnotations(client typedCore.PersistentVolumeClaimInterface, persiste
289287
})
290288
}
291289

292-
func getPodGroup(pod *core.Pod) api.ServerGroup {
293-
if pod.Labels == nil {
290+
func getObjectGroup(obj meta.Object) api.ServerGroup {
291+
l := obj.GetLabels()
292+
if len(l) == 0 {
294293
return api.ServerGroupUnknown
295294
}
296295

297-
return api.ServerGroupFromRole(pod.Labels[k8sutil.LabelKeyRole])
296+
group, ok := l[k8sutil.LabelKeyRole]
297+
if !ok {
298+
return api.ServerGroupUnknown
299+
}
300+
301+
return api.ServerGroupFromRole(group)
298302
}
299303

300304
func ensurePodsAnnotations(client typedCore.PodInterface, cachedStatus inspector.Inspector, kind, name, namespace string, annotations map[string]string, spec api.DeploymentSpec) error {
301305
if err := cachedStatus.IteratePods(func(pod *core.Pod) error {
302-
group := getPodGroup(pod)
306+
group := getObjectGroup(pod)
303307
mergedAnnotations := k8sutil.MergeAnnotations(annotations, spec.GetServerGroupSpec(group).Annotations)
304308

305309
if !k8sutil.CompareAnnotations(pod.GetAnnotations(), mergedAnnotations) {
@@ -336,3 +340,10 @@ func setPodAnnotations(client typedCore.PodInterface, pod *core.Pod, annotations
336340
return nil
337341
})
338342
}
343+
344+
func (r *Resources) isChildResource(obj meta.Object) bool {
345+
return k8sutil.IsChildResource(deployment.ArangoDeploymentResourceKind,
346+
r.context.GetAPIObject().GetName(),
347+
r.context.GetAPIObject().GetNamespace(),
348+
obj)
349+
}

pkg/deployment/resources/inspector/inspector.go

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ package inspector
2424

2525
import (
2626
core "k8s.io/api/core/v1"
27+
policy "k8s.io/api/policy/v1beta1"
2728
"k8s.io/client-go/kubernetes"
2829
)
2930

@@ -48,19 +49,36 @@ func NewInspector(k kubernetes.Interface, namespace string) (Inspector, error) {
4849
return nil, err
4950
}
5051

51-
return NewInspectorFromData(pods, secrets, pvcs, services), nil
52+
serviceAccounts, err := serviceAccountsToMap(k, namespace)
53+
if err != nil {
54+
return nil, err
55+
}
56+
57+
podDisruptionBudgets, err := podDisruptionBudgetsToMap(k, namespace)
58+
if err != nil {
59+
return nil, err
60+
}
61+
62+
return NewInspectorFromData(pods, secrets, pvcs, services, serviceAccounts, podDisruptionBudgets), nil
5263
}
5364

5465
func NewEmptyInspector() Inspector {
55-
return NewInspectorFromData(nil, nil, nil, nil)
66+
return NewInspectorFromData(nil, nil, nil, nil, nil, nil)
5667
}
5768

58-
func NewInspectorFromData(pods map[string]*core.Pod, secrets map[string]*core.Secret, pvcs map[string]*core.PersistentVolumeClaim, services map[string]*core.Service) Inspector {
69+
func NewInspectorFromData(pods map[string]*core.Pod,
70+
secrets map[string]*core.Secret,
71+
pvcs map[string]*core.PersistentVolumeClaim,
72+
services map[string]*core.Service,
73+
serviceAccounts map[string]*core.ServiceAccount,
74+
podDisruptionBudgets map[string]*policy.PodDisruptionBudget) Inspector {
5975
return &inspector{
60-
pods: pods,
61-
secrets: secrets,
62-
pvcs: pvcs,
63-
services: services,
76+
pods: pods,
77+
secrets: secrets,
78+
pvcs: pvcs,
79+
services: services,
80+
serviceAccounts: serviceAccounts,
81+
podDisruptionBudgets: podDisruptionBudgets,
6482
}
6583
}
6684

@@ -76,11 +94,19 @@ type Inspector interface {
7694

7795
Service(name string) (*core.Service, bool)
7896
IterateServices(action ServiceAction, filters ...ServiceFilter) error
97+
98+
ServiceAccount(name string) (*core.ServiceAccount, bool)
99+
IterateServiceAccounts(action ServiceAccountAction, filters ...ServiceAccountFilter) error
100+
101+
PodDisruptionBudget(name string) (*policy.PodDisruptionBudget, bool)
102+
IteratePodDisruptionBudgets(action PodDisruptionBudgetAction, filters ...PodDisruptionBudgetFilter) error
79103
}
80104

81105
type inspector struct {
82-
pods map[string]*core.Pod
83-
secrets map[string]*core.Secret
84-
pvcs map[string]*core.PersistentVolumeClaim
85-
services map[string]*core.Service
106+
pods map[string]*core.Pod
107+
secrets map[string]*core.Secret
108+
pvcs map[string]*core.PersistentVolumeClaim
109+
services map[string]*core.Service
110+
serviceAccounts map[string]*core.ServiceAccount
111+
podDisruptionBudgets map[string]*policy.PodDisruptionBudget
86112
}

0 commit comments

Comments
 (0)