1 package selector
2
3 import (
4 "context"
5 "errors"
6
7 corev1 "k8s.io/api/core/v1"
8 "k8s.io/apimachinery/pkg/fields"
9 "k8s.io/apimachinery/pkg/labels"
10 "sigs.k8s.io/controller-runtime/pkg/client"
11
12 "edge-infra.dev/pkg/sds/ien/k8s/controllers/nodeagent/config"
13 "edge-infra.dev/pkg/sds/ien/k8s/controllers/nodeagent/plugins/thinclient/configobject"
14 )
15
16 var (
17 configMapObjectType = "ConfigMap"
18 secretObjectType = "Secret"
19
20 errInvalidObjectType = errors.New("object type must be 'ConfigMap' or 'Secret'")
21 )
22
23 type Selector struct {
24 Type string `json:"type"`
25 Namespace string `json:"namespace"`
26 Fields string `json:"field"`
27 Labels string `json:"selector"`
28 Directory string `json:"directory"`
29 Service string `json:"service"`
30 }
31
32 func (selector *Selector) GetTargetConfigObjects(ctx context.Context, conf config.Config) ([]configobject.ConfigObject, error) {
33 listOptions, err := selector.GetListOptions()
34 if err != nil {
35 return nil, err
36 }
37 switch selector.Type {
38 case configMapObjectType:
39 return selector.getTargetConfigMaps(ctx, listOptions, conf)
40 case secretObjectType:
41 return selector.getTargetSecrets(ctx, listOptions, conf)
42 }
43 return nil, errInvalidObjectType
44 }
45
46 func (selector *Selector) GetListOptions() (*client.ListOptions, error) {
47 labelsSelector, err := selector.GetLabelsSelector()
48 if err != nil {
49 return nil, err
50 }
51 fieldsSelector, err := selector.GetFieldsSelector()
52 if err != nil {
53 return nil, err
54 }
55 listOptions := &client.ListOptions{
56 LabelSelector: labelsSelector,
57 FieldSelector: fieldsSelector,
58 Namespace: selector.Namespace,
59 }
60 return listOptions, nil
61 }
62
63 func (selector *Selector) GetLabelsSelector() (labels.Selector, error) {
64 labelsSelector, err := labels.Parse(selector.Labels)
65 if err != nil {
66 return nil, err
67 }
68 return labelsSelector, nil
69 }
70
71 func (selector *Selector) GetFieldsSelector() (fields.Selector, error) {
72 fieldsSelector, err := fields.ParseSelector(selector.Fields)
73 if err != nil {
74 return nil, err
75 }
76 return fieldsSelector, nil
77 }
78
79 func (selector *Selector) getTargetConfigMaps(ctx context.Context, listOptions *client.ListOptions, conf config.Config) ([]configobject.ConfigObject, error) {
80 configMapList := &corev1.ConfigMapList{}
81 if err := conf.GetReader().List(ctx, configMapList, listOptions); err != nil {
82 return nil, err
83 }
84 configObjects := []configobject.ConfigObject{}
85 for _, configMap := range configMapList.Items {
86 configObjects = append(configObjects, configobject.NewFromConfigMap(configMap))
87 }
88 return configObjects, nil
89 }
90
91 func (selector *Selector) getTargetSecrets(ctx context.Context, listOptions *client.ListOptions, conf config.Config) ([]configobject.ConfigObject, error) {
92 secretList := &corev1.SecretList{}
93 if err := conf.GetReader().List(ctx, secretList, listOptions); err != nil {
94 return nil, err
95 }
96 configObjects := []configobject.ConfigObject{}
97 for _, secret := range secretList.Items {
98 configObjects = append(configObjects, configobject.NewFromSecret(secret))
99 }
100 return configObjects, nil
101 }
102
103
104 func (selector *Selector) MatchesConfigObject(configObject configobject.ConfigObject) (bool, error) {
105 namespaceMatches := selector.NamespaceMatchesConfigObject(configObject)
106
107 labelSelectorMatches, err := selector.LabelSelectorMatchesConfigObject(configObject)
108 if err != nil {
109 return false, err
110 }
111
112 fieldSelectorMatches, err := selector.FieldSelectorMatchesConfigObject(configObject)
113 if err != nil {
114 return false, err
115 }
116
117 matches := namespaceMatches && labelSelectorMatches && fieldSelectorMatches
118 return matches, nil
119 }
120
121
122 func (selector *Selector) NamespaceMatchesConfigObject(configObject configobject.ConfigObject) bool {
123 if selector.Namespace == "" {
124 return true
125 }
126 return configObject.GetNamespace() == selector.Namespace
127 }
128
129
130 func (selector *Selector) LabelSelectorMatchesConfigObject(configObject configobject.ConfigObject) (bool, error) {
131 if selector.Labels == "" {
132 return true, nil
133 }
134 labelsSelector, err := selector.GetLabelsSelector()
135 if err != nil {
136 return false, err
137 }
138 objectLabels := configObject.GetLabelsSet()
139 return labelsSelector.Matches(objectLabels), nil
140 }
141
142
143 func (selector *Selector) FieldSelectorMatchesConfigObject(configObject configobject.ConfigObject) (bool, error) {
144 if selector.Fields == "" {
145 return true, nil
146 }
147 fieldsSelector, err := selector.GetFieldsSelector()
148 if err != nil {
149 return false, err
150 }
151 objectFields, err := configObject.GetFieldsSet()
152 if err != nil {
153 return false, err
154 }
155 return fieldsSelector.Matches(objectFields), nil
156 }
157
View as plain text