| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | // Copyright 2016 The Prometheus Authors
 | 
					
						
							|  |  |  | // Licensed under the Apache License, Version 2.0 (the "License");
 | 
					
						
							|  |  |  | // you may not use this file except in compliance with the License.
 | 
					
						
							|  |  |  | // You may obtain a copy of the License at
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Unless required by applicable law or agreed to in writing, software
 | 
					
						
							|  |  |  | // distributed under the License is distributed on an "AS IS" BASIS,
 | 
					
						
							|  |  |  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					
						
							|  |  |  | // See the License for the specific language governing permissions and
 | 
					
						
							|  |  |  | // limitations under the License.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package kubernetes | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2017-10-25 12:21:42 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2022-06-03 19:47:14 +08:00
										 |  |  | 	"errors" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2024-09-10 09:41:53 +08:00
										 |  |  | 	"log/slog" | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | 	"net" | 
					
						
							|  |  |  | 	"strconv" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-23 21:55:36 +08:00
										 |  |  | 	"github.com/prometheus/client_golang/prometheus" | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | 	"github.com/prometheus/common/model" | 
					
						
							| 
									
										
										
										
											2024-09-10 09:41:53 +08:00
										 |  |  | 	"github.com/prometheus/common/promslog" | 
					
						
							| 
									
										
										
										
											2018-07-03 15:37:22 +08:00
										 |  |  | 	apiv1 "k8s.io/api/core/v1" | 
					
						
							| 
									
										
										
										
											2018-04-07 06:27:39 +08:00
										 |  |  | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 
					
						
							| 
									
										
										
										
											2017-05-11 16:29:10 +08:00
										 |  |  | 	"k8s.io/client-go/tools/cache" | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	"k8s.io/client-go/util/workqueue" | 
					
						
							| 
									
										
										
										
											2017-10-25 12:21:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Refactor SD configuration to remove `config` dependency (#3629)
* refactor: move targetGroup struct and CheckOverflow() to their own package
* refactor: move auth and security related structs to a utility package, fix import error in utility package
* refactor: Azure SD, remove SD struct from config
* refactor: DNS SD, remove SD struct from config into dns package
* refactor: ec2 SD, move SD struct from config into the ec2 package
* refactor: file SD, move SD struct from config to file discovery package
* refactor: gce, move SD struct from config to gce discovery package
* refactor: move HTTPClientConfig and URL into util/config, fix import error in httputil
* refactor: consul, move SD struct from config into consul discovery package
* refactor: marathon, move SD struct from config into marathon discovery package
* refactor: triton, move SD struct from config to triton discovery package, fix test
* refactor: zookeeper, move SD structs from config to zookeeper discovery package
* refactor: openstack, remove SD struct from config, move into openstack discovery package
* refactor: kubernetes, move SD struct from config into kubernetes discovery package
* refactor: notifier, use targetgroup package instead of config
* refactor: tests for file, marathon, triton SD - use targetgroup package instead of config.TargetGroup
* refactor: retrieval, use targetgroup package instead of config.TargetGroup
* refactor: storage, use config util package
* refactor: discovery manager, use targetgroup package instead of config.TargetGroup
* refactor: use HTTPClient and TLS config from configUtil instead of config
* refactor: tests, use targetgroup package instead of config.TargetGroup
* refactor: fix tagetgroup.Group pointers that were removed by mistake
* refactor: openstack, kubernetes: drop prefixes
* refactor: remove import aliases forced due to vscode bug
* refactor: move main SD struct out of config into discovery/config
* refactor: rename configUtil to config_util
* refactor: rename yamlUtil to yaml_config
* refactor: kubernetes, remove prefixes
* refactor: move the TargetGroup package to discovery/
* refactor: fix order of imports
											
										 
											2017-12-30 04:01:34 +08:00
										 |  |  | 	"github.com/prometheus/prometheus/discovery/targetgroup" | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-01 20:34:37 +08:00
										 |  |  | const ( | 
					
						
							|  |  |  | 	nodeIndex = "node" | 
					
						
							|  |  |  | 	podIndex  = "pod" | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2022-03-10 22:33:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | // Pod discovers new pod targets.
 | 
					
						
							|  |  |  | type Pod struct { | 
					
						
							| 
									
										
										
										
											2025-07-03 23:06:44 +08:00
										 |  |  | 	podInf                cache.SharedIndexInformer | 
					
						
							|  |  |  | 	nodeInf               cache.SharedInformer | 
					
						
							|  |  |  | 	withNodeMetadata      bool | 
					
						
							|  |  |  | 	namespaceInf          cache.SharedInformer | 
					
						
							|  |  |  | 	withNamespaceMetadata bool | 
					
						
							|  |  |  | 	store                 cache.Store | 
					
						
							|  |  |  | 	logger                *slog.Logger | 
					
						
							| 
									
										
										
										
											2025-09-24 11:30:23 +08:00
										 |  |  | 	queue                 *workqueue.Typed[string] | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-17 17:05:13 +08:00
										 |  |  | // NewPod creates a new pod discovery.
 | 
					
						
							| 
									
										
										
										
											2025-07-03 23:06:44 +08:00
										 |  |  | func NewPod(l *slog.Logger, pods cache.SharedIndexInformer, nodes, namespace cache.SharedInformer, eventCount *prometheus.CounterVec) *Pod { | 
					
						
							| 
									
										
										
										
											2017-08-12 02:45:52 +08:00
										 |  |  | 	if l == nil { | 
					
						
							| 
									
										
										
										
											2024-09-10 09:41:53 +08:00
										 |  |  | 		l = promslog.NewNopLogger() | 
					
						
							| 
									
										
										
										
											2017-08-12 02:45:52 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-03-10 22:33:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-11 21:17:47 +08:00
										 |  |  | 	podAddCount := eventCount.WithLabelValues(RolePod.String(), MetricLabelRoleAdd) | 
					
						
							|  |  |  | 	podDeleteCount := eventCount.WithLabelValues(RolePod.String(), MetricLabelRoleDelete) | 
					
						
							|  |  |  | 	podUpdateCount := eventCount.WithLabelValues(RolePod.String(), MetricLabelRoleUpdate) | 
					
						
							| 
									
										
										
										
											2023-12-11 21:12:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	p := &Pod{ | 
					
						
							| 
									
										
										
										
											2025-07-03 23:06:44 +08:00
										 |  |  | 		podInf:                pods, | 
					
						
							|  |  |  | 		nodeInf:               nodes, | 
					
						
							|  |  |  | 		withNodeMetadata:      nodes != nil, | 
					
						
							|  |  |  | 		namespaceInf:          namespace, | 
					
						
							|  |  |  | 		withNamespaceMetadata: namespace != nil, | 
					
						
							|  |  |  | 		store:                 pods.GetStore(), | 
					
						
							|  |  |  | 		logger:                l, | 
					
						
							| 
									
										
										
										
											2025-09-24 11:30:23 +08:00
										 |  |  | 		queue: workqueue.NewTypedWithConfig(workqueue.TypedQueueConfig[string]{ | 
					
						
							|  |  |  | 			Name: RolePod.String(), | 
					
						
							|  |  |  | 		}), | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-14 17:43:53 +08:00
										 |  |  | 	_, err := p.podInf.AddEventHandler(cache.ResourceEventHandlerFuncs{ | 
					
						
							| 
									
										
										
										
											2025-08-27 20:38:54 +08:00
										 |  |  | 		AddFunc: func(o any) { | 
					
						
							| 
									
										
										
										
											2023-12-11 21:12:43 +08:00
										 |  |  | 			podAddCount.Inc() | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 			p.enqueue(o) | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2025-08-27 20:38:54 +08:00
										 |  |  | 		DeleteFunc: func(o any) { | 
					
						
							| 
									
										
										
										
											2023-12-11 21:12:43 +08:00
										 |  |  | 			podDeleteCount.Inc() | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 			p.enqueue(o) | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2025-08-27 20:38:54 +08:00
										 |  |  | 		UpdateFunc: func(_, o any) { | 
					
						
							| 
									
										
										
										
											2023-12-11 21:12:43 +08:00
										 |  |  | 			podUpdateCount.Inc() | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 			p.enqueue(o) | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2022-12-14 17:43:53 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2024-09-10 09:41:53 +08:00
										 |  |  | 		l.Error("Error adding pods event handler.", "err", err) | 
					
						
							| 
									
										
										
										
											2022-12-14 17:43:53 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-12-23 17:50:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if p.withNodeMetadata { | 
					
						
							| 
									
										
										
										
											2022-12-14 17:43:53 +08:00
										 |  |  | 		_, err = p.nodeInf.AddEventHandler(cache.ResourceEventHandlerFuncs{ | 
					
						
							| 
									
										
										
										
											2025-08-27 20:38:54 +08:00
										 |  |  | 			AddFunc: func(o any) { | 
					
						
							| 
									
										
										
										
											2021-12-23 17:50:00 +08:00
										 |  |  | 				node := o.(*apiv1.Node) | 
					
						
							|  |  |  | 				p.enqueuePodsForNode(node.Name) | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2025-08-27 20:38:54 +08:00
										 |  |  | 			UpdateFunc: func(_, o any) { | 
					
						
							| 
									
										
										
										
											2021-12-23 17:50:00 +08:00
										 |  |  | 				node := o.(*apiv1.Node) | 
					
						
							|  |  |  | 				p.enqueuePodsForNode(node.Name) | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2025-08-27 20:38:54 +08:00
										 |  |  | 			DeleteFunc: func(o any) { | 
					
						
							| 
									
										
										
										
											2024-10-16 02:29:07 +08:00
										 |  |  | 				nodeName, err := nodeName(o) | 
					
						
							|  |  |  | 				if err != nil { | 
					
						
							|  |  |  | 					l.Error("Error getting Node name", "err", err) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				p.enqueuePodsForNode(nodeName) | 
					
						
							| 
									
										
										
										
											2021-12-23 17:50:00 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2022-12-14 17:43:53 +08:00
										 |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2024-09-10 09:41:53 +08:00
										 |  |  | 			l.Error("Error adding pods event handler.", "err", err) | 
					
						
							| 
									
										
										
										
											2022-12-14 17:43:53 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-12-23 17:50:00 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-03 23:06:44 +08:00
										 |  |  | 	if p.withNamespaceMetadata { | 
					
						
							|  |  |  | 		_, err = p.namespaceInf.AddEventHandler(cache.ResourceEventHandlerFuncs{ | 
					
						
							| 
									
										
										
										
											2025-08-27 20:38:54 +08:00
										 |  |  | 			UpdateFunc: func(_, o any) { | 
					
						
							| 
									
										
										
										
											2025-07-03 23:06:44 +08:00
										 |  |  | 				namespace := o.(*apiv1.Namespace) | 
					
						
							|  |  |  | 				p.enqueuePodsForNamespace(namespace.Name) | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2025-07-17 15:53:16 +08:00
										 |  |  | 			// Creation and deletion will trigger events for the change handlers of the resources within the namespace.
 | 
					
						
							|  |  |  | 			// No need to have additional handlers for them here.
 | 
					
						
							| 
									
										
										
										
											2025-07-03 23:06:44 +08:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			l.Error("Error adding namespaces event handler.", "err", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	return p | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-27 20:38:54 +08:00
										 |  |  | func (p *Pod) enqueue(obj any) { | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 12:07:33 +08:00
										 |  |  | 	p.queue.Add(key) | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-09 07:59:18 +08:00
										 |  |  | // Run implements the Discoverer interface.
 | 
					
						
							| 
									
										
											  
											
												Refactor SD configuration to remove `config` dependency (#3629)
* refactor: move targetGroup struct and CheckOverflow() to their own package
* refactor: move auth and security related structs to a utility package, fix import error in utility package
* refactor: Azure SD, remove SD struct from config
* refactor: DNS SD, remove SD struct from config into dns package
* refactor: ec2 SD, move SD struct from config into the ec2 package
* refactor: file SD, move SD struct from config to file discovery package
* refactor: gce, move SD struct from config to gce discovery package
* refactor: move HTTPClientConfig and URL into util/config, fix import error in httputil
* refactor: consul, move SD struct from config into consul discovery package
* refactor: marathon, move SD struct from config into marathon discovery package
* refactor: triton, move SD struct from config to triton discovery package, fix test
* refactor: zookeeper, move SD structs from config to zookeeper discovery package
* refactor: openstack, remove SD struct from config, move into openstack discovery package
* refactor: kubernetes, move SD struct from config into kubernetes discovery package
* refactor: notifier, use targetgroup package instead of config
* refactor: tests for file, marathon, triton SD - use targetgroup package instead of config.TargetGroup
* refactor: retrieval, use targetgroup package instead of config.TargetGroup
* refactor: storage, use config util package
* refactor: discovery manager, use targetgroup package instead of config.TargetGroup
* refactor: use HTTPClient and TLS config from configUtil instead of config
* refactor: tests, use targetgroup package instead of config.TargetGroup
* refactor: fix tagetgroup.Group pointers that were removed by mistake
* refactor: openstack, kubernetes: drop prefixes
* refactor: remove import aliases forced due to vscode bug
* refactor: move main SD struct out of config into discovery/config
* refactor: rename configUtil to config_util
* refactor: rename yamlUtil to yaml_config
* refactor: kubernetes, remove prefixes
* refactor: move the TargetGroup package to discovery/
* refactor: fix order of imports
											
										 
											2017-12-30 04:01:34 +08:00
										 |  |  | func (p *Pod) Run(ctx context.Context, ch chan<- []*targetgroup.Group) { | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	defer p.queue.ShutDown() | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-23 17:50:00 +08:00
										 |  |  | 	cacheSyncs := []cache.InformerSynced{p.podInf.HasSynced} | 
					
						
							|  |  |  | 	if p.withNodeMetadata { | 
					
						
							|  |  |  | 		cacheSyncs = append(cacheSyncs, p.nodeInf.HasSynced) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-03 23:06:44 +08:00
										 |  |  | 	if p.withNamespaceMetadata { | 
					
						
							|  |  |  | 		cacheSyncs = append(cacheSyncs, p.namespaceInf.HasSynced) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-12-23 17:50:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if !cache.WaitForCacheSync(ctx.Done(), cacheSyncs...) { | 
					
						
							| 
									
										
										
										
											2022-06-03 19:47:14 +08:00
										 |  |  | 		if !errors.Is(ctx.Err(), context.Canceled) { | 
					
						
							| 
									
										
										
										
											2024-09-10 09:41:53 +08:00
										 |  |  | 			p.logger.Error("pod informer unable to sync cache") | 
					
						
							| 
									
										
										
										
											2019-10-09 17:51:38 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	go func() { | 
					
						
							| 
									
										
										
										
											2023-10-31 19:35:13 +08:00
										 |  |  | 		for p.process(ctx, ch) { | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | 	// Block until the target provider is explicitly canceled.
 | 
					
						
							|  |  |  | 	<-ctx.Done() | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-10 16:53:00 +08:00
										 |  |  | func (p *Pod) process(ctx context.Context, ch chan<- []*targetgroup.Group) bool { | 
					
						
							| 
									
										
										
										
											2025-09-24 11:30:23 +08:00
										 |  |  | 	key, quit := p.queue.Get() | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	if quit { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-09-24 11:30:23 +08:00
										 |  |  | 	defer p.queue.Done(key) | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	namespace, name, err := cache.SplitMetaNamespaceKey(key) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return true | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	o, exists, err := p.store.GetByKey(key) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return true | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !exists { | 
					
						
							| 
									
										
										
										
											2020-02-19 00:36:57 +08:00
										 |  |  | 		send(ctx, ch, &targetgroup.Group{Source: podSourceFromNamespaceAndName(namespace, name)}) | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 		return true | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-02-10 20:17:04 +08:00
										 |  |  | 	pod, err := convertToPod(o) | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2024-09-10 09:41:53 +08:00
										 |  |  | 		p.logger.Error("converting to Pod object failed", "err", err) | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 		return true | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-02-10 20:17:04 +08:00
										 |  |  | 	send(ctx, ch, p.buildPod(pod)) | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	return true | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-27 20:38:54 +08:00
										 |  |  | func convertToPod(o any) (*apiv1.Pod, error) { | 
					
						
							| 
									
										
										
										
											2017-09-04 19:10:44 +08:00
										 |  |  | 	pod, ok := o.(*apiv1.Pod) | 
					
						
							|  |  |  | 	if ok { | 
					
						
							|  |  |  | 		return pod, nil | 
					
						
							| 
									
										
										
										
											2016-11-14 23:21:38 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-03 19:47:14 +08:00
										 |  |  | 	return nil, fmt.Errorf("received unexpected object: %v", o) | 
					
						
							| 
									
										
										
										
											2016-11-14 23:21:38 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | const ( | 
					
						
							|  |  |  | 	podIPLabel                    = metaLabelPrefix + "pod_ip" | 
					
						
							|  |  |  | 	podContainerNameLabel         = metaLabelPrefix + "pod_container_name" | 
					
						
							| 
									
										
										
										
											2023-01-12 00:19:08 +08:00
										 |  |  | 	podContainerIDLabel           = metaLabelPrefix + "pod_container_id" | 
					
						
							| 
									
										
										
										
											2022-07-18 20:31:45 +08:00
										 |  |  | 	podContainerImageLabel        = metaLabelPrefix + "pod_container_image" | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | 	podContainerPortNameLabel     = metaLabelPrefix + "pod_container_port_name" | 
					
						
							|  |  |  | 	podContainerPortNumberLabel   = metaLabelPrefix + "pod_container_port_number" | 
					
						
							|  |  |  | 	podContainerPortProtocolLabel = metaLabelPrefix + "pod_container_port_protocol" | 
					
						
							| 
									
										
										
										
											2019-05-29 21:20:29 +08:00
										 |  |  | 	podContainerIsInit            = metaLabelPrefix + "pod_container_init" | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | 	podReadyLabel                 = metaLabelPrefix + "pod_ready" | 
					
						
							| 
									
										
										
										
											2018-11-06 22:40:24 +08:00
										 |  |  | 	podPhaseLabel                 = metaLabelPrefix + "pod_phase" | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | 	podNodeNameLabel              = metaLabelPrefix + "pod_node_name" | 
					
						
							|  |  |  | 	podHostIPLabel                = metaLabelPrefix + "pod_host_ip" | 
					
						
							| 
									
										
										
										
											2017-11-08 00:24:23 +08:00
										 |  |  | 	podUID                        = metaLabelPrefix + "pod_uid" | 
					
						
							| 
									
										
										
										
											2018-04-07 06:27:39 +08:00
										 |  |  | 	podControllerKind             = metaLabelPrefix + "pod_controller_kind" | 
					
						
							|  |  |  | 	podControllerName             = metaLabelPrefix + "pod_controller_name" | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | ) | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-07 06:27:39 +08:00
										 |  |  | // GetControllerOf returns a pointer to a copy of the controllerRef if controllee has a controller
 | 
					
						
							|  |  |  | // https://github.com/kubernetes/apimachinery/blob/cd2cae2b39fa57e8063fa1f5f13cfe9862db3d41/pkg/apis/meta/v1/controller_ref.go
 | 
					
						
							|  |  |  | func GetControllerOf(controllee metav1.Object) *metav1.OwnerReference { | 
					
						
							|  |  |  | 	for _, ref := range controllee.GetOwnerReferences() { | 
					
						
							|  |  |  | 		if ref.Controller != nil && *ref.Controller { | 
					
						
							|  |  |  | 			return &ref | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | func podLabels(pod *apiv1.Pod) model.LabelSet { | 
					
						
							|  |  |  | 	ls := model.LabelSet{ | 
					
						
							|  |  |  | 		podIPLabel:       lv(pod.Status.PodIP), | 
					
						
							|  |  |  | 		podReadyLabel:    podReady(pod), | 
					
						
							| 
									
										
										
										
											2018-11-06 22:40:24 +08:00
										 |  |  | 		podPhaseLabel:    lv(string(pod.Status.Phase)), | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | 		podNodeNameLabel: lv(pod.Spec.NodeName), | 
					
						
							|  |  |  | 		podHostIPLabel:   lv(pod.Status.HostIP), | 
					
						
							| 
									
										
										
										
											2025-05-04 01:05:13 +08:00
										 |  |  | 		podUID:           lv(string(pod.UID)), | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-30 20:13:00 +08:00
										 |  |  | 	addObjectMetaLabels(ls, pod.ObjectMeta, RolePod) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-07 06:27:39 +08:00
										 |  |  | 	createdBy := GetControllerOf(pod) | 
					
						
							|  |  |  | 	if createdBy != nil { | 
					
						
							|  |  |  | 		if createdBy.Kind != "" { | 
					
						
							|  |  |  | 			ls[podControllerKind] = lv(createdBy.Kind) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if createdBy.Name != "" { | 
					
						
							|  |  |  | 			ls[podControllerName] = lv(createdBy.Name) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | 	return ls | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-04 14:20:57 +08:00
										 |  |  | func (*Pod) findPodContainerStatus(statuses *[]apiv1.ContainerStatus, containerName string) (*apiv1.ContainerStatus, error) { | 
					
						
							| 
									
										
										
										
											2023-01-12 00:19:08 +08:00
										 |  |  | 	for _, s := range *statuses { | 
					
						
							|  |  |  | 		if s.Name == containerName { | 
					
						
							|  |  |  | 			return &s, nil | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil, fmt.Errorf("cannot find container with name %v", containerName) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (p *Pod) findPodContainerID(statuses *[]apiv1.ContainerStatus, containerName string) string { | 
					
						
							|  |  |  | 	cStatus, err := p.findPodContainerStatus(statuses, containerName) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2024-09-10 09:41:53 +08:00
										 |  |  | 		p.logger.Debug("cannot find container ID", "err", err) | 
					
						
							| 
									
										
										
										
											2023-01-12 00:19:08 +08:00
										 |  |  | 		return "" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return cStatus.ContainerID | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Refactor SD configuration to remove `config` dependency (#3629)
* refactor: move targetGroup struct and CheckOverflow() to their own package
* refactor: move auth and security related structs to a utility package, fix import error in utility package
* refactor: Azure SD, remove SD struct from config
* refactor: DNS SD, remove SD struct from config into dns package
* refactor: ec2 SD, move SD struct from config into the ec2 package
* refactor: file SD, move SD struct from config to file discovery package
* refactor: gce, move SD struct from config to gce discovery package
* refactor: move HTTPClientConfig and URL into util/config, fix import error in httputil
* refactor: consul, move SD struct from config into consul discovery package
* refactor: marathon, move SD struct from config into marathon discovery package
* refactor: triton, move SD struct from config to triton discovery package, fix test
* refactor: zookeeper, move SD structs from config to zookeeper discovery package
* refactor: openstack, remove SD struct from config, move into openstack discovery package
* refactor: kubernetes, move SD struct from config into kubernetes discovery package
* refactor: notifier, use targetgroup package instead of config
* refactor: tests for file, marathon, triton SD - use targetgroup package instead of config.TargetGroup
* refactor: retrieval, use targetgroup package instead of config.TargetGroup
* refactor: storage, use config util package
* refactor: discovery manager, use targetgroup package instead of config.TargetGroup
* refactor: use HTTPClient and TLS config from configUtil instead of config
* refactor: tests, use targetgroup package instead of config.TargetGroup
* refactor: fix tagetgroup.Group pointers that were removed by mistake
* refactor: openstack, kubernetes: drop prefixes
* refactor: remove import aliases forced due to vscode bug
* refactor: move main SD struct out of config into discovery/config
* refactor: rename configUtil to config_util
* refactor: rename yamlUtil to yaml_config
* refactor: kubernetes, remove prefixes
* refactor: move the TargetGroup package to discovery/
* refactor: fix order of imports
											
										 
											2017-12-30 04:01:34 +08:00
										 |  |  | func (p *Pod) buildPod(pod *apiv1.Pod) *targetgroup.Group { | 
					
						
							|  |  |  | 	tg := &targetgroup.Group{ | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | 		Source: podSource(pod), | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-02-14 21:23:52 +08:00
										 |  |  | 	// PodIP can be empty when a pod is starting or has been evicted.
 | 
					
						
							|  |  |  | 	if len(pod.Status.PodIP) == 0 { | 
					
						
							|  |  |  | 		return tg | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | 	tg.Labels = podLabels(pod) | 
					
						
							|  |  |  | 	tg.Labels[namespaceLabel] = lv(pod.Namespace) | 
					
						
							| 
									
										
										
										
											2021-12-23 17:50:00 +08:00
										 |  |  | 	if p.withNodeMetadata { | 
					
						
							| 
									
										
										
										
											2022-05-27 17:45:09 +08:00
										 |  |  | 		tg.Labels = addNodeLabels(tg.Labels, p.nodeInf, p.logger, &pod.Spec.NodeName) | 
					
						
							| 
									
										
										
										
											2021-12-23 17:50:00 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-03 23:06:44 +08:00
										 |  |  | 	if p.withNamespaceMetadata { | 
					
						
							|  |  |  | 		tg.Labels = addNamespaceLabels(tg.Labels, p.namespaceInf, p.logger, pod.Namespace) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 03:31:52 +08:00
										 |  |  | 	containers := append(pod.Spec.Containers, pod.Spec.InitContainers...) | 
					
						
							| 
									
										
										
										
											2019-05-27 23:46:39 +08:00
										 |  |  | 	for i, c := range containers { | 
					
						
							| 
									
										
										
										
											2019-05-29 17:22:10 +08:00
										 |  |  | 		isInit := i >= len(pod.Spec.Containers) | 
					
						
							| 
									
										
										
										
											2019-05-27 23:46:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-12 00:19:08 +08:00
										 |  |  | 		cStatuses := &pod.Status.ContainerStatuses | 
					
						
							|  |  |  | 		if isInit { | 
					
						
							|  |  |  | 			cStatuses = &pod.Status.InitContainerStatuses | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		cID := p.findPodContainerID(cStatuses, c.Name) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | 		// If no ports are defined for the container, create an anonymous
 | 
					
						
							|  |  |  | 		// target per container.
 | 
					
						
							|  |  |  | 		if len(c.Ports) == 0 { | 
					
						
							|  |  |  | 			// We don't have a port so we just set the address label to the pod IP.
 | 
					
						
							|  |  |  | 			// The user has to add a port manually.
 | 
					
						
							|  |  |  | 			tg.Targets = append(tg.Targets, model.LabelSet{ | 
					
						
							| 
									
										
										
										
											2022-07-18 20:31:45 +08:00
										 |  |  | 				model.AddressLabel:     lv(pod.Status.PodIP), | 
					
						
							|  |  |  | 				podContainerNameLabel:  lv(c.Name), | 
					
						
							| 
									
										
										
										
											2023-01-12 00:19:08 +08:00
										 |  |  | 				podContainerIDLabel:    lv(cID), | 
					
						
							| 
									
										
										
										
											2022-07-18 20:31:45 +08:00
										 |  |  | 				podContainerImageLabel: lv(c.Image), | 
					
						
							|  |  |  | 				podContainerIsInit:     lv(strconv.FormatBool(isInit)), | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// Otherwise create one target for each container/port combination.
 | 
					
						
							|  |  |  | 		for _, port := range c.Ports { | 
					
						
							| 
									
										
										
										
											2016-10-17 17:05:13 +08:00
										 |  |  | 			ports := strconv.FormatUint(uint64(port.ContainerPort), 10) | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | 			addr := net.JoinHostPort(pod.Status.PodIP, ports) | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | 			tg.Targets = append(tg.Targets, model.LabelSet{ | 
					
						
							|  |  |  | 				model.AddressLabel:            lv(addr), | 
					
						
							|  |  |  | 				podContainerNameLabel:         lv(c.Name), | 
					
						
							| 
									
										
										
										
											2023-01-12 00:19:08 +08:00
										 |  |  | 				podContainerIDLabel:           lv(cID), | 
					
						
							| 
									
										
										
										
											2022-07-18 20:31:45 +08:00
										 |  |  | 				podContainerImageLabel:        lv(c.Image), | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | 				podContainerPortNumberLabel:   lv(ports), | 
					
						
							|  |  |  | 				podContainerPortNameLabel:     lv(port.Name), | 
					
						
							|  |  |  | 				podContainerPortProtocolLabel: lv(string(port.Protocol)), | 
					
						
							| 
									
										
										
										
											2019-05-29 17:22:10 +08:00
										 |  |  | 				podContainerIsInit:            lv(strconv.FormatBool(isInit)), | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return tg | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-23 17:50:00 +08:00
										 |  |  | func (p *Pod) enqueuePodsForNode(nodeName string) { | 
					
						
							| 
									
										
										
										
											2022-03-10 22:33:34 +08:00
										 |  |  | 	pods, err := p.podInf.GetIndexer().ByIndex(nodeIndex, nodeName) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2024-09-10 09:41:53 +08:00
										 |  |  | 		p.logger.Error("Error getting pods for node", "node", nodeName, "err", err) | 
					
						
							| 
									
										
										
										
											2022-03-10 22:33:34 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, pod := range pods { | 
					
						
							|  |  |  | 		p.enqueue(pod.(*apiv1.Pod)) | 
					
						
							| 
									
										
										
										
											2021-12-23 17:50:00 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-03 23:06:44 +08:00
										 |  |  | func (p *Pod) enqueuePodsForNamespace(namespace string) { | 
					
						
							|  |  |  | 	pods, err := p.podInf.GetIndexer().ByIndex(cache.NamespaceIndex, namespace) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		p.logger.Error("Error getting pods in namespace", "namespace", namespace, "err", err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, pod := range pods { | 
					
						
							|  |  |  | 		p.enqueue(pod.(*apiv1.Pod)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | func podSource(pod *apiv1.Pod) string { | 
					
						
							| 
									
										
										
										
											2018-04-26 00:36:22 +08:00
										 |  |  | 	return podSourceFromNamespaceAndName(pod.Namespace, pod.Name) | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | func podSourceFromNamespaceAndName(namespace, name string) string { | 
					
						
							| 
									
										
										
										
											2024-02-01 20:34:37 +08:00
										 |  |  | 	return "pod/" + namespacedName(namespace, name) | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-07 20:53:11 +08:00
										 |  |  | func podReady(pod *apiv1.Pod) model.LabelValue { | 
					
						
							|  |  |  | 	for _, cond := range pod.Status.Conditions { | 
					
						
							|  |  |  | 		if cond.Type == apiv1.PodReady { | 
					
						
							|  |  |  | 			return lv(strings.ToLower(string(cond.Status))) | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-07-03 15:37:22 +08:00
										 |  |  | 	return lv(strings.ToLower(string(apiv1.ConditionUnknown))) | 
					
						
							| 
									
										
										
										
											2016-07-01 18:17:17 +08:00
										 |  |  | } |