| 
									
										
										
										
											2017-09-04 19:10:44 +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" | 
					
						
							| 
									
										
										
										
											2021-08-26 21:31:05 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2017-09-04 19:10:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-12 00:17:59 +08:00
										 |  |  | 	"github.com/go-kit/log" | 
					
						
							|  |  |  | 	"github.com/go-kit/log/level" | 
					
						
							| 
									
										
										
										
											2017-09-04 19:10:44 +08:00
										 |  |  | 	"github.com/prometheus/common/model" | 
					
						
							| 
									
										
										
										
											2021-08-16 07:34:36 +08:00
										 |  |  | 	v1 "k8s.io/api/networking/v1" | 
					
						
							| 
									
										
										
										
											2020-04-07 00:23:02 +08:00
										 |  |  | 	"k8s.io/api/networking/v1beta1" | 
					
						
							| 
									
										
										
										
											2017-09-04 19:10:44 +08:00
										 |  |  | 	"k8s.io/client-go/tools/cache" | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	"k8s.io/client-go/util/workqueue" | 
					
						
							| 
									
										
										
										
											2019-03-26 07:01:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/prometheus/prometheus/discovery/targetgroup" | 
					
						
							|  |  |  | 	"github.com/prometheus/prometheus/util/strutil" | 
					
						
							| 
									
										
										
										
											2017-09-04 19:10:44 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 23:52:58 +08:00
										 |  |  | var ( | 
					
						
							|  |  |  | 	ingressAddCount    = eventCount.WithLabelValues("ingress", "add") | 
					
						
							|  |  |  | 	ingressUpdateCount = eventCount.WithLabelValues("ingress", "update") | 
					
						
							|  |  |  | 	ingressDeleteCount = eventCount.WithLabelValues("ingress", "delete") | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-28 02:07:23 +08:00
										 |  |  | // Ingress implements discovery of Kubernetes ingress.
 | 
					
						
							| 
									
										
										
										
											2017-09-04 19:10:44 +08:00
										 |  |  | type Ingress struct { | 
					
						
							|  |  |  | 	logger   log.Logger | 
					
						
							|  |  |  | 	informer cache.SharedInformer | 
					
						
							|  |  |  | 	store    cache.Store | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	queue    *workqueue.Type | 
					
						
							| 
									
										
										
										
											2017-09-04 19:10:44 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // NewIngress returns a new ingress discovery.
 | 
					
						
							|  |  |  | func NewIngress(l log.Logger, inf cache.SharedInformer) *Ingress { | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	s := &Ingress{logger: l, informer: inf, store: inf.GetStore(), queue: workqueue.NewNamed("ingress")} | 
					
						
							| 
									
										
										
										
											2022-12-14 17:43:53 +08:00
										 |  |  | 	_, err := s.informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 		AddFunc: func(o interface{}) { | 
					
						
							| 
									
										
										
										
											2020-02-06 23:52:58 +08:00
										 |  |  | 			ingressAddCount.Inc() | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 			s.enqueue(o) | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		DeleteFunc: func(o interface{}) { | 
					
						
							| 
									
										
										
										
											2020-02-06 23:52:58 +08:00
										 |  |  | 			ingressDeleteCount.Inc() | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 			s.enqueue(o) | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		UpdateFunc: func(_, o interface{}) { | 
					
						
							| 
									
										
										
										
											2020-02-06 23:52:58 +08:00
										 |  |  | 			ingressUpdateCount.Inc() | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 			s.enqueue(o) | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2022-12-14 17:43:53 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		level.Error(l).Log("msg", "Error adding ingresses event handler.", "err", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	return s | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 12:07:33 +08:00
										 |  |  | func (i *Ingress) enqueue(obj interface{}) { | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 	i.queue.Add(key) | 
					
						
							| 
									
										
										
										
											2017-09-04 19:10:44 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-09 07:59:18 +08:00
										 |  |  | // Run implements the Discoverer interface.
 | 
					
						
							| 
									
										
										
										
											2018-07-18 12:07:33 +08:00
										 |  |  | func (i *Ingress) Run(ctx context.Context, ch chan<- []*targetgroup.Group) { | 
					
						
							|  |  |  | 	defer i.queue.ShutDown() | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 12:07:33 +08:00
										 |  |  | 	if !cache.WaitForCacheSync(ctx.Done(), i.informer.HasSynced) { | 
					
						
							| 
									
										
										
										
											2022-06-03 19:47:14 +08:00
										 |  |  | 		if !errors.Is(ctx.Err(), context.Canceled) { | 
					
						
							| 
									
										
										
										
											2019-10-09 17:51:38 +08:00
										 |  |  | 			level.Error(i.logger).Log("msg", "ingress informer unable to sync cache") | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-09-04 19:10:44 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	go func() { | 
					
						
							| 
									
										
										
										
											2018-07-18 12:07:33 +08:00
										 |  |  | 		for i.process(ctx, ch) { | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2017-09-04 19:10:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Block until the target provider is explicitly canceled.
 | 
					
						
							|  |  |  | 	<-ctx.Done() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 12:07:33 +08:00
										 |  |  | func (i *Ingress) process(ctx context.Context, ch chan<- []*targetgroup.Group) bool { | 
					
						
							|  |  |  | 	keyObj, quit := i.queue.Get() | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	if quit { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-07-18 12:07:33 +08:00
										 |  |  | 	defer i.queue.Done(keyObj) | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	key := keyObj.(string) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	namespace, name, err := cache.SplitMetaNamespaceKey(key) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return true | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 12:07:33 +08:00
										 |  |  | 	o, exists, err := i.store.GetByKey(key) | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return true | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !exists { | 
					
						
							| 
									
										
										
										
											2020-02-19 00:36:57 +08:00
										 |  |  | 		send(ctx, ch, &targetgroup.Group{Source: ingressSourceFromNamespaceAndName(namespace, name)}) | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 		return true | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-08-16 07:34:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 12:31:33 +08:00
										 |  |  | 	var ia ingressAdaptor | 
					
						
							| 
									
										
										
										
											2021-08-16 07:34:36 +08:00
										 |  |  | 	switch ingress := o.(type) { | 
					
						
							|  |  |  | 	case *v1.Ingress: | 
					
						
							| 
									
										
										
										
											2021-08-20 12:31:33 +08:00
										 |  |  | 		ia = newIngressAdaptorFromV1(ingress) | 
					
						
							| 
									
										
										
										
											2021-08-16 07:34:36 +08:00
										 |  |  | 	case *v1beta1.Ingress: | 
					
						
							| 
									
										
										
										
											2021-08-20 12:31:33 +08:00
										 |  |  | 		ia = newIngressAdaptorFromV1beta1(ingress) | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		level.Error(i.logger).Log("msg", "converting to Ingress object failed", "err", | 
					
						
							| 
									
										
										
										
											2022-06-03 19:47:14 +08:00
										 |  |  | 			fmt.Errorf("received unexpected object: %v", o)) | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 		return true | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-08-20 12:31:33 +08:00
										 |  |  | 	send(ctx, ch, i.buildIngress(ia)) | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | 	return true | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 12:31:33 +08:00
										 |  |  | func ingressSource(s ingressAdaptor) string { | 
					
						
							|  |  |  | 	return ingressSourceFromNamespaceAndName(s.namespace(), s.name()) | 
					
						
							| 
									
										
										
										
											2017-09-04 19:10:44 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-10 00:35:14 +08:00
										 |  |  | func ingressSourceFromNamespaceAndName(namespace, name string) string { | 
					
						
							|  |  |  | 	return "ingress/" + namespace + "/" + name | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-04 19:10:44 +08:00
										 |  |  | const ( | 
					
						
							| 
									
										
										
										
											2019-04-10 20:21:42 +08:00
										 |  |  | 	ingressNameLabel               = metaLabelPrefix + "ingress_name" | 
					
						
							|  |  |  | 	ingressLabelPrefix             = metaLabelPrefix + "ingress_label_" | 
					
						
							|  |  |  | 	ingressLabelPresentPrefix      = metaLabelPrefix + "ingress_labelpresent_" | 
					
						
							|  |  |  | 	ingressAnnotationPrefix        = metaLabelPrefix + "ingress_annotation_" | 
					
						
							|  |  |  | 	ingressAnnotationPresentPrefix = metaLabelPrefix + "ingress_annotationpresent_" | 
					
						
							|  |  |  | 	ingressSchemeLabel             = metaLabelPrefix + "ingress_scheme" | 
					
						
							|  |  |  | 	ingressHostLabel               = metaLabelPrefix + "ingress_host" | 
					
						
							|  |  |  | 	ingressPathLabel               = metaLabelPrefix + "ingress_path" | 
					
						
							| 
									
										
										
										
											2021-06-11 20:43:22 +08:00
										 |  |  | 	ingressClassNameLabel          = metaLabelPrefix + "ingress_class_name" | 
					
						
							| 
									
										
										
										
											2017-09-04 19:10:44 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 12:31:33 +08:00
										 |  |  | func ingressLabels(ingress ingressAdaptor) model.LabelSet { | 
					
						
							| 
									
										
										
										
											2019-10-26 10:06:00 +08:00
										 |  |  | 	// Each label and annotation will create two key-value pairs in the map.
 | 
					
						
							| 
									
										
										
										
											2021-08-20 12:31:33 +08:00
										 |  |  | 	ls := make(model.LabelSet, 2*(len(ingress.labels())+len(ingress.annotations()))+2) | 
					
						
							|  |  |  | 	ls[ingressNameLabel] = lv(ingress.name()) | 
					
						
							|  |  |  | 	ls[namespaceLabel] = lv(ingress.namespace()) | 
					
						
							|  |  |  | 	if cls := ingress.ingressClassName(); cls != nil { | 
					
						
							|  |  |  | 		ls[ingressClassNameLabel] = lv(*cls) | 
					
						
							| 
									
										
										
										
											2021-06-11 01:02:42 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-09-04 19:10:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 12:31:33 +08:00
										 |  |  | 	for k, v := range ingress.labels() { | 
					
						
							| 
									
										
										
										
											2019-04-10 20:21:42 +08:00
										 |  |  | 		ln := strutil.SanitizeLabelName(k) | 
					
						
							|  |  |  | 		ls[model.LabelName(ingressLabelPrefix+ln)] = lv(v) | 
					
						
							|  |  |  | 		ls[model.LabelName(ingressLabelPresentPrefix+ln)] = presentValue | 
					
						
							| 
									
										
										
										
											2017-09-04 19:10:44 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 12:31:33 +08:00
										 |  |  | 	for k, v := range ingress.annotations() { | 
					
						
							| 
									
										
										
										
											2019-04-10 20:21:42 +08:00
										 |  |  | 		ln := strutil.SanitizeLabelName(k) | 
					
						
							|  |  |  | 		ls[model.LabelName(ingressAnnotationPrefix+ln)] = lv(v) | 
					
						
							|  |  |  | 		ls[model.LabelName(ingressAnnotationPresentPrefix+ln)] = presentValue | 
					
						
							| 
									
										
										
										
											2017-09-04 19:10:44 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return ls | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 12:31:33 +08:00
										 |  |  | func pathsFromIngressPaths(ingressPaths []string) []string { | 
					
						
							|  |  |  | 	if ingressPaths == nil { | 
					
						
							| 
									
										
										
										
											2021-08-16 07:34:36 +08:00
										 |  |  | 		return []string{"/"} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-08-20 12:31:33 +08:00
										 |  |  | 	paths := make([]string, len(ingressPaths)) | 
					
						
							|  |  |  | 	for n, p := range ingressPaths { | 
					
						
							|  |  |  | 		path := p | 
					
						
							|  |  |  | 		if p == "" { | 
					
						
							| 
									
										
										
										
											2021-08-16 07:34:36 +08:00
										 |  |  | 			path = "/" | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		paths[n] = path | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return paths | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 12:31:33 +08:00
										 |  |  | func (i *Ingress) buildIngress(ingress ingressAdaptor) *targetgroup.Group { | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 	tg := &targetgroup.Group{ | 
					
						
							| 
									
										
										
										
											2017-09-04 19:10:44 +08:00
										 |  |  | 		Source: ingressSource(ingress), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	tg.Labels = ingressLabels(ingress) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 12:31:33 +08:00
										 |  |  | 	for _, rule := range ingress.rules() { | 
					
						
							| 
									
										
										
										
											2021-08-26 21:31:05 +08:00
										 |  |  | 		scheme := "http" | 
					
						
							| 
									
										
										
										
											2021-08-20 12:31:33 +08:00
										 |  |  | 		paths := pathsFromIngressPaths(rule.paths()) | 
					
						
							| 
									
										
										
										
											2021-08-16 07:34:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-26 21:31:05 +08:00
										 |  |  | 	out: | 
					
						
							|  |  |  | 		for _, pattern := range ingress.tlsHosts() { | 
					
						
							|  |  |  | 			if matchesHostnamePattern(pattern, rule.host()) { | 
					
						
							|  |  |  | 				scheme = "https" | 
					
						
							|  |  |  | 				break out | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-08-16 07:34:36 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for _, path := range paths { | 
					
						
							|  |  |  | 			tg.Targets = append(tg.Targets, model.LabelSet{ | 
					
						
							| 
									
										
										
										
											2021-08-20 12:31:33 +08:00
										 |  |  | 				model.AddressLabel: lv(rule.host()), | 
					
						
							| 
									
										
										
										
											2021-08-16 07:34:36 +08:00
										 |  |  | 				ingressSchemeLabel: lv(scheme), | 
					
						
							| 
									
										
										
										
											2021-08-20 12:31:33 +08:00
										 |  |  | 				ingressHostLabel:   lv(rule.host()), | 
					
						
							| 
									
										
										
										
											2021-08-16 07:34:36 +08:00
										 |  |  | 				ingressPathLabel:   lv(path), | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return tg | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-08-26 21:31:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // matchesHostnamePattern returns true if the host matches a wildcard DNS
 | 
					
						
							| 
									
										
										
										
											2021-08-31 04:34:01 +08:00
										 |  |  | // pattern or pattern and host are equal.
 | 
					
						
							| 
									
										
										
										
											2021-08-26 21:31:05 +08:00
										 |  |  | func matchesHostnamePattern(pattern, host string) bool { | 
					
						
							|  |  |  | 	if pattern == host { | 
					
						
							|  |  |  | 		return true | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	patternParts := strings.Split(pattern, ".") | 
					
						
							|  |  |  | 	hostParts := strings.Split(host, ".") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-31 04:34:01 +08:00
										 |  |  | 	// If the first element of the pattern is not a wildcard, give up.
 | 
					
						
							| 
									
										
										
										
											2021-08-26 21:31:05 +08:00
										 |  |  | 	if len(patternParts) == 0 || patternParts[0] != "*" { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-31 04:34:01 +08:00
										 |  |  | 	// A wildcard match require the pattern to have the same length as the host
 | 
					
						
							|  |  |  | 	// path.
 | 
					
						
							| 
									
										
										
										
											2021-08-26 21:31:05 +08:00
										 |  |  | 	if len(patternParts) != len(hostParts) { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := 1; i < len(patternParts); i++ { | 
					
						
							|  |  |  | 		if patternParts[i] != hostParts[i] { | 
					
						
							|  |  |  | 			return false | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return true | 
					
						
							|  |  |  | } |