package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"k8s.io/apimachinery/pkg/api/meta"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/informers"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/cache"
	"k8s.io/client-go/tools/clientcmd"
	"strings"
)


func Start(fact informers.SharedInformerFactory)  {
	ch:=make(chan struct{})
	fact.Start(ch)
	fact.WaitForCacheSync(ch)
}


func Watch(fact informers.SharedInformerFactory,groupVersion,resource string ) cache.SharedIndexInformer  {
	gv:=strings.Split(groupVersion,"/")
	var group,version string
	if len(gv)==1{
		group=""
		version=groupVersion
	}else{
		group=gv[0]
		version=gv[1]
	}
	grv:=schema.GroupVersionResource{
		Group: group,
		Version: version,
		Resource: resource,
	}
	informer,err:=fact.ForResource(grv)
	if err!=nil{
		panic(err)
	}
	informer.Informer().AddEventHandler(&cache.ResourceEventHandlerFuncs{})
	return informer.Informer()
}

//求切片的交集   select xxwhere a=xx and a=xx
func intersect(slice1, slice2 []string) []string {
	m := make(map[string]struct{})
	nn := make([]string, 0)
	for _, v1 := range slice1 {
		m[v1]= struct{}{}
	}
	for _, v2 := range slice2 {
		if _,ok := m[v2];ok  {
			nn = append(nn, v2)
		}
	}
	return nn
}

func CmAnnotationsFunc(obj interface{}) ([]string, error) {
	meta, err := meta.Accessor(obj)
	if err != nil {
		return []string{""}, fmt.Errorf("object has no meta: %v", err)
	}
	ret:=[]string{}
	if  meta.GetAnnotations()!=nil{
		for k,v:=range meta.GetAnnotations(){
			//  best:true
			ret=append(ret,fmt.Sprintf("%s:%s",k,v))
		}
	}

	return ret, nil
}
func CmLabelsFunc(obj interface{}) ([]string, error) {
	meta, err := meta.Accessor(obj)
	if err != nil {
		return []string{""}, fmt.Errorf("object has no meta: %v", err)
	}
	ret:=[]string{}
	if  meta.GetLabels()!=nil{
			for k,v:=range meta.GetLabels(){
				//  best:true
				ret=append(ret,fmt.Sprintf("%s:%s",k,v))
			}
	}

	return ret, nil
}

func main() {

	config ,err := clientcmd.BuildConfigFromFlags("","./config")
	if err != nil {
		panic(err)
	}

	client ,err := kubernetes.NewForConfig(config)

	if err != nil {
		panic(err)
	}
	fact:=informers.NewSharedInformerFactoryWithOptions(client,0)
	cmInfomer:=Watch(fact,"v1","configmaps") //自定义函数,设置监听哪个资源
	_= cmInfomer.AddIndexers(cache.Indexers{
	 	"labels":CmLabelsFunc,"annotations":CmAnnotationsFunc,
	 })

	Start(fact)//自定义函数,启动

	r:=gin.New()

	// /configmaps.v1.?labels=user:shenyi
	r.GET("/common/:gvr", func(c *gin.Context) {
		fmt.Println(c.Query("labels"))
		gvr,_:=schema.ParseResourceArg(c.Param("gvr"))
		informer,_:=fact.ForResource(*gvr)

		//初始化都是nil
		var labelKeys,annotationKeys []string=nil,nil
		var list []string//最终结果
		if c.Query("labels")!=""{
			labelKeys,_=informer.Informer().GetIndexer().
				IndexKeys("labels",c.Query("labels"))
		}

		if c.Query("annotations")!=""{
			annotationKeys,_=informer.Informer().GetIndexer().
				IndexKeys("annotations",c.Query("annotations"))
		}

		if labelKeys!=nil && annotationKeys!=nil{
			list=intersect(labelKeys,annotationKeys)//求交集
		}
		if labelKeys!=nil{
			list=labelKeys
		}else{
			list=annotationKeys
		}
		if labelKeys == nil && annotationKeys == nil {
			list = informer.Informer().GetStore().ListKeys()
		}
		c.JSON(200,gin.H{"data":list})
	})

	// http://127.0.0.1:8080/common/configmaps.v1.?labels=app:sentry
	r.Run(":8080")


}

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐