/
configmap_service.go
135 lines (107 loc) · 4 KB
/
configmap_service.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package k8s
import (
"fmt"
"github.com/kyma-project/kyma/components/console-backend-service/pkg/resource"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
"github.com/kyma-project/kyma/components/console-backend-service/internal/apierror"
"github.com/kyma-project/kyma/components/console-backend-service/internal/domain/k8s/pretty"
"github.com/kyma-project/kyma/components/console-backend-service/internal/pager"
"k8s.io/client-go/tools/cache"
)
type configMapService struct {
client corev1.CoreV1Interface
informer cache.SharedIndexInformer
notifier resource.Notifier
}
func newConfigMapService(informer cache.SharedIndexInformer, client corev1.CoreV1Interface) *configMapService {
notifier := resource.NewNotifier()
informer.AddEventHandler(notifier)
return &configMapService{
client: client,
informer: informer,
notifier: notifier,
}
}
func (svc *configMapService) Find(name, namespace string) (*v1.ConfigMap, error) {
key := fmt.Sprintf("%s/%s", namespace, name)
item, exists, err := svc.informer.GetStore().GetByKey(key)
if err != nil || !exists {
return nil, err
}
configMap, ok := item.(*v1.ConfigMap)
if !ok {
return nil, fmt.Errorf("Incorrect item type: %T, should be: *ConfigMap", item)
}
svc.ensureTypeMeta(configMap)
return configMap, nil
}
func (svc *configMapService) List(namespace string, pagingParams pager.PagingParams) ([]*v1.ConfigMap, error) {
items, err := pager.FromIndexer(svc.informer.GetIndexer(), "namespace", namespace).Limit(pagingParams)
if err != nil {
return nil, err
}
var configMaps []*v1.ConfigMap
for _, item := range items {
configMap, ok := item.(*v1.ConfigMap)
if !ok {
return nil, fmt.Errorf("Incorrect item type: %T, should be: *ConfigMap", item)
}
svc.ensureTypeMeta(configMap)
configMaps = append(configMaps, configMap)
}
return configMaps, nil
}
func (svc *configMapService) Update(name, namespace string, update v1.ConfigMap) (*v1.ConfigMap, error) {
err := svc.checkUpdatePreconditions(name, namespace, update)
if err != nil {
return nil, err
}
updated, err := svc.client.ConfigMaps(namespace).Update(&update)
if err != nil {
return nil, err
}
svc.ensureTypeMeta(updated)
return updated, nil
}
func (svc *configMapService) Delete(name, namespace string) error {
return svc.client.ConfigMaps(namespace).Delete(name, nil)
}
func (svc *configMapService) Subscribe(listener resource.Listener) {
svc.notifier.AddListener(listener)
}
func (svc *configMapService) Unsubscribe(listener resource.Listener) {
svc.notifier.DeleteListener(listener)
}
func (svc *configMapService) checkUpdatePreconditions(name string, namespace string, update v1.ConfigMap) error {
var errs apierror.ErrorFieldAggregate
if name != update.Name {
errs = append(errs, apierror.NewInvalidField("metadata.name", update.Name, fmt.Sprintf("name of updated object does not match the original (%s)", name)))
}
if namespace != update.Namespace {
errs = append(errs, apierror.NewInvalidField("metadata.namespace", update.Namespace, fmt.Sprintf("namespace of updated object does not match the original (%s)", namespace)))
}
typeMeta := svc.configMapTypeMeta()
if update.Kind != typeMeta.Kind {
errs = append(errs, apierror.NewInvalidField("kind", update.Kind, "ConfigMap's kind should not be changed"))
}
if update.APIVersion != typeMeta.APIVersion {
errs = append(errs, apierror.NewInvalidField("apiVersion", update.APIVersion, "ConfigMap's apiVersion should not be changed"))
}
if len(errs) > 0 {
return apierror.NewInvalid(pretty.ConfigMap, errs)
}
return nil
}
// Kubernetes API used by client-go doesn't provide kind and apiVersion so we have to add it here
// See: https://github.com/kubernetes/kubernetes/issues/3030
func (svc *configMapService) ensureTypeMeta(configMap *v1.ConfigMap) {
configMap.TypeMeta = svc.configMapTypeMeta()
}
func (svc *configMapService) configMapTypeMeta() metav1.TypeMeta {
return metav1.TypeMeta{
Kind: "ConfigMap",
APIVersion: "v1",
}
}