k8s thirdpartresource添加

28 篇文章 0 订阅
13 篇文章 1 订阅

这是github上client-go repo中关于thirdpartresource的实例。

主要使用了clientset 和restclient两种接口,通过对资源的定义以及资源实例的定义、注册,实现自定义资源加入自定义thirdpartresource。



package main

import (
	"flag"
	"fmt"

	// "encoding/json"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/pkg/api"
	"k8s.io/client-go/pkg/api/errors"
	"k8s.io/client-go/pkg/api/v1"
	"k8s.io/client-go/pkg/apis/extensions/v1beta1"
	metav1 "k8s.io/client-go/pkg/apis/meta/v1"
	"k8s.io/client-go/pkg/runtime"
	"k8s.io/client-go/pkg/runtime/schema"
	"k8s.io/client-go/pkg/runtime/serializer"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"

	"k8s.io/client-go/pkg/api/meta"
	// Only required to authenticate against GKE clusters
	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
)

var (
	config *rest.Config
)

func main() {
	kubeconfig := flag.String("kubeconfig", "./config", "Path to a kube config. Only required if out-of-cluster.")
	flag.Parse()

	// Create the client config. Use kubeconfig if given, otherwise assume in-cluster.
	// 判断是否制定kubeconfig  否则通过incluster方式启动
	config, err := buildConfig(*kubeconfig)
	if err != nil {
		panic(err)
	}
	//返回Clientset
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		panic(err)
	}

	// initialize third party resource if it does not exist
	// 判断是否资源已存在
	tpr, err := clientset.Extensions().ThirdPartyResources().Get("example.k8s.io", metav1.GetOptions{})
	if err != nil {
		if errors.IsNotFound(err) {
			// 定义ThirdPartyResource
			tpr := &v1beta1.ThirdPartyResource{
				ObjectMeta: v1.ObjectMeta{
					//定义元数据名称
					Name: "example.k8s.io",
				},
				Versions: []v1beta1.APIVersion{
					//定义versions
					{Name: "v1"},
				},
				//描述信息
				Description: "An Example ThirdPartyResource",
			}
			//创建ThirdPartyResource
			result, err := clientset.Extensions().ThirdPartyResources().Create(tpr)
			if err != nil {
				panic(err)
			}
			fmt.Printf("CREATED: %#v\nFROM: %#v\n", result, tpr)
		} else {
			panic(err)
		}
	} else {
		fmt.Printf("SKIPPING: already exists %#v\n", tpr)
	}

	// make a new config for our extension's API group, using the first config as a baseline
	var tprconfig *rest.Config
	tprconfig = config
	//按照restclient的要求增加配置
	configureClient(tprconfig)
	// 创建restclient
	tprclient, err := rest.RESTClientFor(tprconfig)
	if err != nil {
		panic(err)
	}

	var example Example
	//获取资源实例
	err = tprclient.Get().
		Resource("examples").
		Namespace(api.NamespaceDefault).
		Name("example1").
		Do().Into(&example)
	//不存在则创建
	if err != nil {
		if errors.IsNotFound(err) {
			// Create an instance of our TPR
			example := &Example{
				Metadata: api.ObjectMeta{
					Name: "example1",
				},
				Spec: ExampleSpec{
					Foo: "hello",
					Bar: true,
				},
			}

			var result Example
			//创建资源实例
			err = tprclient.Post().
				Resource("examples").
				Namespace(api.NamespaceDefault).
				Body(example).
				Do().Into(&result)

			if err != nil {
				panic(err)
			}
			fmt.Printf("CREATED: %#v\n", result)
		} else {
			panic(err)
		}
	} else {
		fmt.Printf("GET: %#v\n", example)
	}

	// Fetch a list of our TPRs
	exampleList := ExampleList{}
	//获取资源实例列表
	err = tprclient.Get().Resource("examples").Do().Into(&exampleList)
	if err != nil {
		panic(err)
	}
	fmt.Printf("LIST: %#v\n", exampleList)
}

//用于判断是否位incluster
func buildConfig(kubeconfig string) (*rest.Config, error) {
	if kubeconfig != "" {
		return clientcmd.BuildConfigFromFlags("", kubeconfig)
	}
	return rest.InClusterConfig()
}

//相对于clientset和dynamicclient resetclient需要增加额外配置
func configureClient(config *rest.Config) {
	groupversion := schema.GroupVersion{
		Group:   "k8s.io",
		Version: "v1",
	}

	config.GroupVersion = &groupversion
	// 指定访问的api接口,如果访问的是pods等正式版数据应访问/api
	config.APIPath = "/apis"
	config.ContentType = runtime.ContentTypeJSON
	//指定序列化工厂函数
	config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
	//添加数据对象到scheme
	schemeBuilder := runtime.NewSchemeBuilder(
		func(scheme *runtime.Scheme) error {
			scheme.AddKnownTypes(
				groupversion,
				&Example{},
				&ExampleList{},
				&api.ListOptions{},
				&api.DeleteOptions{},
			)
			return nil
		})
	schemeBuilder.AddToScheme(api.Scheme)
}

//SPEC 信息
type ExampleSpec struct {
	Foo string `json:"foo"`
	Bar bool   `json:"bar"`
}

//数据结构
type Example struct {
	metav1.TypeMeta `json:",inline"`
	Metadata        api.ObjectMeta `json:"metadata"`

	Spec ExampleSpec `json:"spec"`
}

type ExampleList struct {
	metav1.TypeMeta `json:",inline"`
	Metadata        metav1.ListMeta `json:"metadata"`

	Items []Example `json:"items"`
}

//实现runtime.Object接口
// Required to satisfy Object interface,为request.Result.Into的数据类型
func (e *Example) GetObjectKind() schema.ObjectKind {
	return &e.TypeMeta
}

//实现meta.ObjectMetaAccessor 用于设置填充metadata
// Required to satisfy ObjectMetaAccessor interface
func (e *Example) GetObjectMeta() meta.Object {
	return &e.Metadata
}

// Required to satisfy Object interface
func (el *ExampleList) GetObjectKind() schema.ObjectKind {
	return &el.TypeMeta
}

// Required to satisfy ListMetaAccessor interface
func (el *ExampleList) GetListMeta() metav1.List {
	return &el.Metadata
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值