forked from kyma-project/kyma
-
Notifications
You must be signed in to change notification settings - Fork 0
/
labels_fetcher.go
123 lines (102 loc) · 4.68 KB
/
labels_fetcher.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
package controller
import (
"encoding/json"
"fmt"
scTypes "github.com/kubernetes-incubator/service-catalog/pkg/apis/servicecatalog/v1beta1"
scListers "github.com/kubernetes-incubator/service-catalog/pkg/client/listers_generated/servicecatalog/v1beta1"
"github.com/kyma-project/kyma/components/service-binding-usage-controller/internal/controller/pretty"
"github.com/pkg/errors"
)
// BindingLabelsFetcher extracts binding labels defined in ClusterServiceClass for given ServiceBinding
type BindingLabelsFetcher struct {
siLister scListers.ServiceInstanceLister
cscLister scListers.ClusterServiceClassLister
scLister scListers.ServiceClassLister
}
// NewBindingLabelsFetcher returnd BindingLabelsFetcher
func NewBindingLabelsFetcher(siLister scListers.ServiceInstanceLister,
cscLister scListers.ClusterServiceClassLister, scLister scListers.ServiceClassLister) *BindingLabelsFetcher {
return &BindingLabelsFetcher{
siLister: siLister,
cscLister: cscLister,
scLister: scLister,
}
}
// Fetch returns binding labels defined in ClusterServiceClass/ServiceClass
func (c *BindingLabelsFetcher) Fetch(svcBinding *scTypes.ServiceBinding) (map[string]string, error) {
if svcBinding == nil {
return nil, errors.New("cannot fetch labels from ClusterServiceClass/ServiceClass because binding is nil")
}
svcInstanceName := svcBinding.Spec.ServiceInstanceRef.Name
svcInstance, err := c.siLister.ServiceInstances(svcBinding.Namespace).Get(svcInstanceName)
if err != nil {
return nil, errors.Wrapf(err, "while fetching ServiceInstance [%s] from namespace [%s] indicated by ServiceBinding", svcInstanceName, svcBinding.Namespace)
}
svcClusterServiceClassName := c.getClusterServiceClassNameFromInstance(svcInstance)
svcServiceClassName := c.getServiceClassNameFromInstance(svcInstance)
switch {
case svcClusterServiceClassName != "" && svcServiceClassName != "":
return nil, fmt.Errorf("unable to get class details because the ServiceInstance %s refers to ClusterServiceClass %s and ServiceClass %s",
pretty.ServiceInstanceName(svcInstance), svcClusterServiceClassName, svcServiceClassName)
case svcClusterServiceClassName != "":
svcClass, err := c.cscLister.Get(svcClusterServiceClassName)
if err != nil {
return nil, errors.Wrapf(err, "while fetching ClusterServiceClass [%s]", svcClusterServiceClassName)
}
labels, err := c.getBindingLabelsFromClassSpec(&svcClass.Spec.CommonServiceClassSpec)
if err != nil {
return nil, errors.Wrapf(err, "while getting labels from %s", pretty.ClusterServiceClassName(svcClass))
}
return labels, nil
case svcServiceClassName != "":
svcClass, err := c.scLister.ServiceClasses(svcBinding.Namespace).Get(svcServiceClassName)
if err != nil {
return nil, errors.Wrapf(err, "while fetching ServiceClass [%s/%s]", svcBinding.Namespace, svcServiceClassName)
}
labels, err := c.getBindingLabelsFromClassSpec(&svcClass.Spec.CommonServiceClassSpec)
if err != nil {
return nil, errors.Wrapf(err, "while getting labels from %s", pretty.ServiceClassName(svcClass))
}
return labels, nil
default:
return nil, fmt.Errorf("cannot fetch ClusterServiceClass or ServiceClass from [%s]", pretty.ServiceInstanceName(svcInstance))
}
}
func (c *BindingLabelsFetcher) getClusterServiceClassNameFromInstance(svcInstance *scTypes.ServiceInstance) string {
if svcInstance.Spec.ClusterServiceClassExternalName != "" && svcInstance.Spec.ClusterServiceClassRef != nil {
return svcInstance.Spec.ClusterServiceClassRef.Name
}
return svcInstance.Spec.ClusterServiceClassName
}
func (c *BindingLabelsFetcher) getServiceClassNameFromInstance(svcInstance *scTypes.ServiceInstance) string {
if svcInstance.Spec.ServiceClassExternalName != "" && svcInstance.Spec.ServiceClassRef != nil {
return svcInstance.Spec.ServiceClassRef.Name
}
return svcInstance.Spec.ServiceClassName
}
func (c *BindingLabelsFetcher) getBindingLabelsFromClassSpec(svcSpec *scTypes.CommonServiceClassSpec) (map[string]string, error) {
var jsonDataAsAMap map[string]interface{}
if svcSpec.ExternalMetadata == nil {
return nil, nil
}
if err := json.Unmarshal(svcSpec.ExternalMetadata.Raw, &jsonDataAsAMap); err != nil {
return nil, errors.Wrap(err, "while unmarshalling raw metadata to json")
}
rawBindingLabels, exists := jsonDataAsAMap["bindingLabels"]
if !exists {
return nil, nil
}
bindingLabels, ok := rawBindingLabels.(map[string]interface{})
if !ok {
return nil, errors.New("cannot cast bindingLabels to map[string]interface{}")
}
out := make(map[string]string)
for label, value := range bindingLabels {
strValue, ok := value.(string)
if !ok {
return nil, fmt.Errorf("cannot cast bindingLabels[%s]=[%v] to string value", label, value)
}
out[label] = strValue
}
return out, nil
}