github.com/netdata/go.d.plugin@v0.58.1/modules/k8s_state/kube_state.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package k8s_state 4 5 import ( 6 "context" 7 _ "embed" 8 "sync" 9 "time" 10 11 "github.com/netdata/go.d.plugin/agent/module" 12 13 "k8s.io/client-go/kubernetes" 14 ) 15 16 //go:embed "config_schema.json" 17 var configSchema string 18 19 func init() { 20 module.Register("k8s_state", module.Creator{ 21 JobConfigSchema: configSchema, 22 Defaults: module.Defaults{ 23 Disabled: true, 24 }, 25 Create: func() module.Module { return New() }, 26 }) 27 } 28 29 func New() *KubeState { 30 return &KubeState{ 31 initDelay: time.Second * 3, 32 newKubeClient: newKubeClient, 33 charts: baseCharts.Copy(), 34 once: &sync.Once{}, 35 wg: &sync.WaitGroup{}, 36 state: newKubeState(), 37 } 38 } 39 40 type ( 41 discoverer interface { 42 run(ctx context.Context, in chan<- resource) 43 ready() bool 44 stopped() bool 45 } 46 47 KubeState struct { 48 module.Base 49 50 newKubeClient func() (kubernetes.Interface, error) 51 52 startTime time.Time 53 initDelay time.Duration 54 55 charts *module.Charts 56 57 client kubernetes.Interface 58 once *sync.Once 59 wg *sync.WaitGroup 60 discoverer discoverer 61 ctx context.Context 62 ctxCancel context.CancelFunc 63 state *kubeState 64 65 kubeClusterID string 66 kubeClusterName string 67 } 68 ) 69 70 func (ks *KubeState) Init() bool { 71 client, err := ks.initClient() 72 if err != nil { 73 ks.Errorf("client initialization: %v", err) 74 return false 75 } 76 ks.client = client 77 78 ks.ctx, ks.ctxCancel = context.WithCancel(context.Background()) 79 80 ks.discoverer = ks.initDiscoverer(ks.client) 81 82 return true 83 } 84 85 func (ks *KubeState) Check() bool { 86 if ks.client == nil || ks.discoverer == nil { 87 ks.Error("not initialized job") 88 return false 89 } 90 91 ver, err := ks.client.Discovery().ServerVersion() 92 if err != nil { 93 ks.Errorf("failed to connect to the Kubernetes API server: %v", err) 94 return false 95 } 96 97 ks.Infof("successfully connected to the Kubernetes API server '%s'", ver) 98 return true 99 } 100 101 func (ks *KubeState) Charts() *module.Charts { 102 return ks.charts 103 } 104 105 func (ks *KubeState) Collect() map[string]int64 { 106 ms, err := ks.collect() 107 if err != nil { 108 ks.Error(err) 109 } 110 111 if len(ms) == 0 { 112 return nil 113 } 114 return ms 115 } 116 117 func (ks *KubeState) Cleanup() { 118 if ks.ctxCancel == nil { 119 return 120 } 121 ks.ctxCancel() 122 123 c := make(chan struct{}) 124 go func() { defer close(c); ks.wg.Wait() }() 125 126 t := time.NewTimer(time.Second * 3) 127 defer t.Stop() 128 129 select { 130 case <-c: 131 return 132 case <-t.C: 133 return 134 } 135 }