-
Notifications
You must be signed in to change notification settings - Fork 7
/
client.go
106 lines (90 loc) · 3.78 KB
/
client.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
package configurator
import (
"fmt"
"reflect"
"k8s.io/client-go/tools/cache"
configv1alpha3 "github.com/flomesh-io/fsm/pkg/apis/config/v1alpha3"
"github.com/flomesh-io/fsm/pkg/k8s/informers"
"github.com/flomesh-io/fsm/pkg/announcements"
"github.com/flomesh-io/fsm/pkg/errcode"
"github.com/flomesh-io/fsm/pkg/k8s"
"github.com/flomesh-io/fsm/pkg/messaging"
"github.com/flomesh-io/fsm/pkg/metricsstore"
)
// NewConfigurator implements configurator.Configurator and creates the Kubernetes client to manage namespaces.
func NewConfigurator(informerCollection *informers.InformerCollection, fsmNamespace, meshConfigName string, msgBroker *messaging.Broker) *Client {
c := &Client{
informers: informerCollection,
fsmNamespace: fsmNamespace,
meshConfigName: meshConfigName,
}
// configure listener
meshConfigEventTypes := k8s.EventTypes{
Add: announcements.MeshConfigAdded,
Update: announcements.MeshConfigUpdated,
Delete: announcements.MeshConfigDeleted,
}
informerCollection.AddEventHandler(informers.InformerKeyMeshConfig, k8s.GetEventHandlerFuncs(nil, meshConfigEventTypes, msgBroker))
informerCollection.AddEventHandler(informers.InformerKeyMeshConfig, c.metricsHandler())
meshRootCertificateEventTypes := k8s.EventTypes{
Add: announcements.MeshRootCertificateAdded,
Update: announcements.MeshRootCertificateUpdated,
Delete: announcements.MeshRootCertificateDeleted,
}
informerCollection.AddEventHandler(informers.InformerKeyMeshRootCertificate, k8s.GetEventHandlerFuncs(nil, meshRootCertificateEventTypes, msgBroker))
return c
}
func (c *Client) getMeshConfigCacheKey() string {
return fmt.Sprintf("%s/%s", c.fsmNamespace, c.meshConfigName)
}
// Returns the current MeshConfig
func (c *Client) getMeshConfig() configv1alpha3.MeshConfig {
var meshConfig configv1alpha3.MeshConfig
meshConfigCacheKey := c.getMeshConfigCacheKey()
item, exists, err := c.informers.GetByKey(informers.InformerKeyMeshConfig, meshConfigCacheKey)
if err != nil {
log.Error().Err(err).Str(errcode.Kind, errcode.GetErrCodeWithMetric(errcode.ErrMeshConfigFetchFromCache)).Msgf("Error getting MeshConfig from cache with key %s", meshConfigCacheKey)
return meshConfig
}
if !exists {
log.Warn().Msgf("MeshConfig %s does not exist. Default config values will be used.", meshConfigCacheKey)
return meshConfig
}
meshConfig = *item.(*configv1alpha3.MeshConfig)
return meshConfig
}
func (c *Client) metricsHandler() cache.ResourceEventHandlerFuncs {
handleMetrics := func(obj interface{}) {
config := obj.(*configv1alpha3.MeshConfig)
// This uses reflection to iterate over the feature flags to avoid
// enumerating them here individually. This code assumes the following:
// - MeshConfig.Spec.FeatureFlags is a struct, not a pointer to a struct
// - Each field of the FeatureFlags type is a separate feature flag of
// type bool
// - Each field defines a `json` struct tag that only contains an
// alphanumeric field name without any other directive like `omitempty`
flags := reflect.ValueOf(config.Spec.FeatureFlags)
for i := 0; i < flags.NumField(); i++ {
var val float64
if flags.Field(i).Bool() {
val = 1
}
name := flags.Type().Field(i).Tag.Get("json")
metricsstore.DefaultMetricsStore.FeatureFlagEnabled.WithLabelValues(name).Set(val)
}
}
return cache.ResourceEventHandlerFuncs{
AddFunc: handleMetrics,
UpdateFunc: func(_, newObj interface{}) {
handleMetrics(newObj)
},
DeleteFunc: func(obj interface{}) {
config := obj.(*configv1alpha3.MeshConfig).DeepCopy()
// Ensure metrics reflect however the rest of the control plane
// handles when the MeshConfig doesn't exist. If this happens not to
// be the "real" MeshConfig, handleMetrics() will simply ignore it.
config.Spec.FeatureFlags = c.GetFeatureFlags()
handleMetrics(config)
},
}
}