mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 16:29:21 +00:00
Merge pull request #47050 from sttts/sttts-deprecate-tpr-example
Automatic merge from submit-queue (batch tested with PRs 47024, 47050, 47086, 47081, 47013) client-go: deprecate TPR example and add CRD example /cc @nilebox Part of https://github.com/kubernetes/kubernetes/issues/46702
This commit is contained in:
commit
43295501a3
@ -324,6 +324,7 @@ plugin/pkg/scheduler/algorithmprovider
|
|||||||
plugin/pkg/scheduler/algorithmprovider/defaults
|
plugin/pkg/scheduler/algorithmprovider/defaults
|
||||||
plugin/pkg/scheduler/api/validation
|
plugin/pkg/scheduler/api/validation
|
||||||
staging/src/k8s.io/apiextensions-apiserver
|
staging/src/k8s.io/apiextensions-apiserver
|
||||||
|
staging/src/k8s.io/apiextensions-apiserver/examples/client-go
|
||||||
staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install
|
staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install
|
||||||
staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation
|
staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation
|
||||||
staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions
|
staging/src/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions
|
||||||
@ -384,7 +385,7 @@ staging/src/k8s.io/client-go/discovery
|
|||||||
staging/src/k8s.io/client-go/examples/create-update-delete-deployment
|
staging/src/k8s.io/client-go/examples/create-update-delete-deployment
|
||||||
staging/src/k8s.io/client-go/examples/in-cluster
|
staging/src/k8s.io/client-go/examples/in-cluster
|
||||||
staging/src/k8s.io/client-go/examples/out-of-cluster
|
staging/src/k8s.io/client-go/examples/out-of-cluster
|
||||||
staging/src/k8s.io/client-go/examples/third-party-resources
|
staging/src/k8s.io/client-go/examples/third-party-resources-deprecated
|
||||||
staging/src/k8s.io/client-go/informers
|
staging/src/k8s.io/client-go/informers
|
||||||
staging/src/k8s.io/client-go/informers/admissionregistration
|
staging/src/k8s.io/client-go/informers/admissionregistration
|
||||||
staging/src/k8s.io/client-go/informers/admissionregistration/v1alpha1
|
staging/src/k8s.io/client-go/informers/admissionregistration/v1alpha1
|
||||||
|
@ -80,7 +80,7 @@ if grep -rq '// import "k8s.io/kubernetes/' 'staging/'; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for EXAMPLE in vendor/k8s.io/client-go/examples/{in-cluster,out-of-cluster,third-party-resources}; do
|
for EXAMPLE in vendor/k8s.io/client-go/examples/{in-cluster,out-of-cluster,third-party-resources-deprecated} vendor/k8s.io/apiextensions-apiserver/examples ; do
|
||||||
test -d "${EXAMPLE}" # make sure example is still there
|
test -d "${EXAMPLE}" # make sure example is still there
|
||||||
if go list -f '{{ join .Deps "\n" }}' "./${EXAMPLE}/..." | sort | uniq | grep -q k8s.io/client-go/plugin; then
|
if go list -f '{{ join .Deps "\n" }}' "./${EXAMPLE}/..." | sort | uniq | grep -q k8s.io/client-go/plugin; then
|
||||||
echo "${EXAMPLE} imports client-go plugins by default, but shouldn't."
|
echo "${EXAMPLE} imports client-go plugins by default, but shouldn't."
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
licenses(["notice"])
|
||||||
|
|
||||||
|
load(
|
||||||
|
"@io_bazel_rules_go//go:def.bzl",
|
||||||
|
"go_binary",
|
||||||
|
"go_library",
|
||||||
|
)
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = ["main.go"],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
deps = [
|
||||||
|
"//vendor/k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1:go_default_library",
|
||||||
|
"//vendor/k8s.io/apiextensions-apiserver/examples/client-go/client:go_default_library",
|
||||||
|
"//vendor/k8s.io/apiextensions-apiserver/examples/client-go/controller:go_default_library",
|
||||||
|
"//vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_binary(
|
||||||
|
name = "client-go",
|
||||||
|
library = ":go_default_library",
|
||||||
|
tags = ["automanaged"],
|
||||||
|
)
|
@ -0,0 +1,46 @@
|
|||||||
|
# Custom Resource Example
|
||||||
|
|
||||||
|
**Note:** CustomResourceDefinition is the successor of the deprecated ThirdPartyResource.
|
||||||
|
|
||||||
|
This particular example demonstrates how to perform basic operations such as:
|
||||||
|
|
||||||
|
* How to register a new custom resource (custom resource type) using a CustomResourceDefinition
|
||||||
|
* How to create/get/list instances of your new resource type (update/delete/etc work as well but are not demonstrated)
|
||||||
|
* How to setup a controller on resource handling create/update/delete events
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
```
|
||||||
|
# assumes you have a working kubeconfig, not required if operating in-cluster
|
||||||
|
go run *.go -kubeconfig=$HOME/.kube/config
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use Cases
|
||||||
|
|
||||||
|
CustomResourceDefinitions can be used to implement custom resource types for your Kubernetes cluster.
|
||||||
|
These act like most other Resources in Kubernetes, and may be `kubectl apply`'d, etc.
|
||||||
|
|
||||||
|
Some example use cases:
|
||||||
|
|
||||||
|
* Provisioning/Management of external datastores/databases (eg. CloudSQL/RDS instances)
|
||||||
|
* Higher level abstractions around Kubernetes primitives (eg. a single Resource to define an etcd cluster, backed by a Service and a ReplicationController)
|
||||||
|
|
||||||
|
## Defining types
|
||||||
|
|
||||||
|
Each instance of your custom resource has an attached Spec, which should be defined via a `struct{}` to provide data format validation.
|
||||||
|
In practice, this Spec is arbitrary key-value data that specifies the configuration/behavior of your Resource.
|
||||||
|
|
||||||
|
For example, if you were implementing a custom resource for a Database, you might provide a DatabaseSpec like the following:
|
||||||
|
|
||||||
|
``` go
|
||||||
|
type DatabaseSpec struct {
|
||||||
|
Databases []string `json:"databases"`
|
||||||
|
Users []User `json:"users"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
```
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2017 The Kubernetes 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 v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||||
|
AddToScheme = SchemeBuilder.AddToScheme
|
||||||
|
)
|
||||||
|
|
||||||
|
// GroupName is the group name used in this package.
|
||||||
|
const GroupName = "cr.client-go.k8s.io"
|
||||||
|
|
||||||
|
// SchemeGroupVersion is the group version used to register these objects.
|
||||||
|
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"}
|
||||||
|
|
||||||
|
// Resource takes an unqualified resource and returns a Group-qualified GroupResource.
|
||||||
|
func Resource(resource string) schema.GroupResource {
|
||||||
|
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||||
|
}
|
||||||
|
|
||||||
|
// addKnownTypes adds the set of types defined in this package to the supplied scheme.
|
||||||
|
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||||
|
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||||
|
&Example{},
|
||||||
|
&ExampleList{},
|
||||||
|
)
|
||||||
|
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||||
|
return nil
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
licenses(["notice"])
|
||||||
|
|
||||||
|
load(
|
||||||
|
"@io_bazel_rules_go//go:def.bzl",
|
||||||
|
"go_library",
|
||||||
|
)
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"client.go",
|
||||||
|
"cr.go",
|
||||||
|
],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
deps = [
|
||||||
|
"//vendor/k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1:go_default_library",
|
||||||
|
"//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
|
||||||
|
"//vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2017 The Kubernetes 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 client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
|
|
||||||
|
crv1 "k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewClient(cfg *rest.Config) (*rest.RESTClient, *runtime.Scheme, error) {
|
||||||
|
scheme := runtime.NewScheme()
|
||||||
|
if err := crv1.AddToScheme(scheme); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
config := *cfg
|
||||||
|
config.GroupVersion = &crv1.SchemeGroupVersion
|
||||||
|
config.APIPath = "/apis"
|
||||||
|
config.ContentType = runtime.ContentTypeJSON
|
||||||
|
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: serializer.NewCodecFactory(scheme)}
|
||||||
|
|
||||||
|
client, err := rest.RESTClientFor(&config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, scheme, nil
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2017 The Kubernetes 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 client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
crv1 "k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1"
|
||||||
|
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||||
|
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/util/errors"
|
||||||
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
|
apiv1 "k8s.io/client-go/pkg/api/v1"
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
|
// Uncomment the following line to load the gcp plugin (only required to authenticate against GKE clusters).
|
||||||
|
// _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||||
|
)
|
||||||
|
|
||||||
|
const exampleCRDName = crv1.ExampleResourcePlural + "." + crv1.GroupName
|
||||||
|
|
||||||
|
func CreateCustomResourceDefinition(clientset apiextensionsclient.Interface) (*apiextensionsv1beta1.CustomResourceDefinition, error) {
|
||||||
|
crd := &apiextensionsv1beta1.CustomResourceDefinition{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: exampleCRDName,
|
||||||
|
},
|
||||||
|
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
||||||
|
Group: crv1.GroupName,
|
||||||
|
Version: crv1.SchemeGroupVersion.Version,
|
||||||
|
Scope: apiextensionsv1beta1.NamespaceScoped,
|
||||||
|
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
||||||
|
Plural: crv1.ExampleResourcePlural,
|
||||||
|
Kind: reflect.TypeOf(crv1.Example{}).Name(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_, err := clientset.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for CRD being established
|
||||||
|
err = wait.Poll(500*time.Millisecond, 60*time.Second, func() (bool, error) {
|
||||||
|
crd, err = clientset.ApiextensionsV1beta1().CustomResourceDefinitions().Get(exampleCRDName, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
for _, cond := range crd.Status.Conditions {
|
||||||
|
switch cond.Type {
|
||||||
|
case apiextensionsv1beta1.Established:
|
||||||
|
if cond.Status == apiextensionsv1beta1.ConditionTrue {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
case apiextensionsv1beta1.NamesAccepted:
|
||||||
|
if cond.Status == apiextensionsv1beta1.ConditionFalse {
|
||||||
|
fmt.Printf("Name conflict: %v\n", cond.Reason)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, err
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
deleteErr := clientset.ApiextensionsV1beta1().CustomResourceDefinitions().Delete(exampleCRDName, nil)
|
||||||
|
if deleteErr != nil {
|
||||||
|
return nil, errors.NewAggregate([]error{err, deleteErr})
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return crd, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func WaitForExampleInstanceProcessed(exampleClient *rest.RESTClient, name string) error {
|
||||||
|
return wait.Poll(100*time.Millisecond, 10*time.Second, func() (bool, error) {
|
||||||
|
var example crv1.Example
|
||||||
|
err := exampleClient.Get().
|
||||||
|
Resource(crv1.ExampleResourcePlural).
|
||||||
|
Namespace(apiv1.NamespaceDefault).
|
||||||
|
Name(name).
|
||||||
|
Do().Into(&example)
|
||||||
|
|
||||||
|
if err == nil && example.Status.State == crv1.ExampleStateProcessed {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, err
|
||||||
|
})
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
licenses(["notice"])
|
||||||
|
|
||||||
|
load(
|
||||||
|
"@io_bazel_rules_go//go:def.bzl",
|
||||||
|
"go_library",
|
||||||
|
)
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = ["controller.go"],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
deps = [
|
||||||
|
"//vendor/k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/fields:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2017 The Kubernetes 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 controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/fields"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
apiv1 "k8s.io/client-go/pkg/api/v1"
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
|
|
||||||
|
crv1 "k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Watcher is an example of watching on resource create/update/delete events
|
||||||
|
type ExampleController struct {
|
||||||
|
ExampleClient *rest.RESTClient
|
||||||
|
ExampleScheme *runtime.Scheme
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run starts an Example resource controller
|
||||||
|
func (c *ExampleController) Run(ctx context.Context) error {
|
||||||
|
fmt.Print("Watch Example objects\n")
|
||||||
|
|
||||||
|
// Watch Example objects
|
||||||
|
_, err := c.watchExamples(ctx)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Failed to register watch for Example resource: %v\n", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
<-ctx.Done()
|
||||||
|
return ctx.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ExampleController) watchExamples(ctx context.Context) (cache.Controller, error) {
|
||||||
|
source := cache.NewListWatchFromClient(
|
||||||
|
c.ExampleClient,
|
||||||
|
crv1.ExampleResourcePlural,
|
||||||
|
apiv1.NamespaceAll,
|
||||||
|
fields.Everything())
|
||||||
|
|
||||||
|
_, controller := cache.NewInformer(
|
||||||
|
source,
|
||||||
|
|
||||||
|
// The object type.
|
||||||
|
&crv1.Example{},
|
||||||
|
|
||||||
|
// resyncPeriod
|
||||||
|
// Every resyncPeriod, all resources in the cache will retrigger events.
|
||||||
|
// Set to 0 to disable the resync.
|
||||||
|
0,
|
||||||
|
|
||||||
|
// Your custom resource event handlers.
|
||||||
|
cache.ResourceEventHandlerFuncs{
|
||||||
|
AddFunc: c.onAdd,
|
||||||
|
UpdateFunc: c.onUpdate,
|
||||||
|
DeleteFunc: c.onDelete,
|
||||||
|
})
|
||||||
|
|
||||||
|
go controller.Run(ctx.Done())
|
||||||
|
return controller, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ExampleController) onAdd(obj interface{}) {
|
||||||
|
example := obj.(*crv1.Example)
|
||||||
|
fmt.Printf("[CONTROLLER] OnAdd %s\n", example.ObjectMeta.SelfLink)
|
||||||
|
|
||||||
|
// NEVER modify objects from the store. It's a read-only, local cache.
|
||||||
|
// You can use exampleScheme.Copy() to make a deep copy of original object and modify this copy
|
||||||
|
// Or create a copy manually for better performance
|
||||||
|
copyObj, err := c.ExampleScheme.Copy(example)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("ERROR creating a deep copy of example object: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
exampleCopy := copyObj.(*crv1.Example)
|
||||||
|
exampleCopy.Status = crv1.ExampleStatus{
|
||||||
|
State: crv1.ExampleStateProcessed,
|
||||||
|
Message: "Successfully processed by controller",
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.ExampleClient.Put().
|
||||||
|
Name(example.ObjectMeta.Name).
|
||||||
|
Namespace(example.ObjectMeta.Namespace).
|
||||||
|
Resource(crv1.ExampleResourcePlural).
|
||||||
|
Body(exampleCopy).
|
||||||
|
Do().
|
||||||
|
Error()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("ERROR updating status: %v\n", err)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("UPDATED status: %#v\n", exampleCopy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ExampleController) onUpdate(oldObj, newObj interface{}) {
|
||||||
|
oldExample := oldObj.(*crv1.Example)
|
||||||
|
newExample := newObj.(*crv1.Example)
|
||||||
|
fmt.Printf("[CONTROLLER] OnUpdate oldObj: %s\n", oldExample.ObjectMeta.SelfLink)
|
||||||
|
fmt.Printf("[CONTROLLER] OnUpdate newObj: %s\n", newExample.ObjectMeta.SelfLink)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ExampleController) onDelete(obj interface{}) {
|
||||||
|
example := obj.(*crv1.Example)
|
||||||
|
fmt.Printf("[CONTROLLER] OnDelete %s\n", example.ObjectMeta.SelfLink)
|
||||||
|
}
|
@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2017 The Kubernetes 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Note: the example only works with the code within the same release/branch.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||||
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
apiv1 "k8s.io/client-go/pkg/api/v1"
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
|
|
||||||
|
// Uncomment the following line to load the gcp plugin (only required to authenticate against GKE clusters).
|
||||||
|
// _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||||
|
|
||||||
|
crv1 "k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1"
|
||||||
|
exampleclient "k8s.io/apiextensions-apiserver/examples/client-go/client"
|
||||||
|
examplecontroller "k8s.io/apiextensions-apiserver/examples/client-go/controller"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
kubeconfig := flag.String("kubeconfig", "", "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.
|
||||||
|
config, err := buildConfig(*kubeconfig)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
apiextensionsclientset, err := apiextensionsclient.NewForConfig(config)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize custom resource using a CustomResourceDefinition if it does not exist
|
||||||
|
crd, err := exampleclient.CreateCustomResourceDefinition(apiextensionsclientset)
|
||||||
|
if err != nil && !apierrors.IsAlreadyExists(err) {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer apiextensionsclientset.ApiextensionsV1beta1().CustomResourceDefinitions().Delete(crd.Name, nil)
|
||||||
|
|
||||||
|
// make a new config for our extension's API group, using the first config as a baseline
|
||||||
|
exampleClient, exampleScheme, err := exampleclient.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// start a controller on instances of our custom resource
|
||||||
|
controller := examplecontroller.ExampleController{
|
||||||
|
ExampleClient: exampleClient,
|
||||||
|
ExampleScheme: exampleScheme,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||||
|
defer cancelFunc()
|
||||||
|
go controller.Run(ctx)
|
||||||
|
|
||||||
|
// Create an instance of our custom resource
|
||||||
|
example := &crv1.Example{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "example1",
|
||||||
|
},
|
||||||
|
Spec: crv1.ExampleSpec{
|
||||||
|
Foo: "hello",
|
||||||
|
Bar: true,
|
||||||
|
},
|
||||||
|
Status: crv1.ExampleStatus{
|
||||||
|
State: crv1.ExampleStateCreated,
|
||||||
|
Message: "Created, not processed yet",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
var result crv1.Example
|
||||||
|
err = exampleClient.Post().
|
||||||
|
Resource(crv1.ExampleResourcePlural).
|
||||||
|
Namespace(apiv1.NamespaceDefault).
|
||||||
|
Body(example).
|
||||||
|
Do().Into(&result)
|
||||||
|
if err == nil {
|
||||||
|
fmt.Printf("CREATED: %#v\n", result)
|
||||||
|
} else if apierrors.IsAlreadyExists(err) {
|
||||||
|
fmt.Printf("ALREADY EXISTS: %#v\n", result)
|
||||||
|
} else {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Poll until Example object is handled by controller and gets status updated to "Processed"
|
||||||
|
err = exampleclient.WaitForExampleInstanceProcessed(exampleClient, "example1")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Print("PROCESSED\n")
|
||||||
|
|
||||||
|
// Fetch a list of our TPRs
|
||||||
|
exampleList := crv1.ExampleList{}
|
||||||
|
err = exampleClient.Get().Resource(crv1.ExampleResourcePlural).Do().Into(&exampleList)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("LIST: %#v\n", exampleList)
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildConfig(kubeconfig string) (*rest.Config, error) {
|
||||||
|
if kubeconfig != "" {
|
||||||
|
return clientcmd.BuildConfigFromFlags("", kubeconfig)
|
||||||
|
}
|
||||||
|
return rest.InClusterConfig()
|
||||||
|
}
|
@ -11,6 +11,7 @@ go_test(
|
|||||||
name = "go_default_test",
|
name = "go_default_test",
|
||||||
srcs = [
|
srcs = [
|
||||||
"basic_test.go",
|
"basic_test.go",
|
||||||
|
"client-go_test.go",
|
||||||
"finalization_test.go",
|
"finalization_test.go",
|
||||||
"registration_test.go",
|
"registration_test.go",
|
||||||
"validation_test.go",
|
"validation_test.go",
|
||||||
@ -22,6 +23,9 @@ go_test(
|
|||||||
deps = [
|
deps = [
|
||||||
"//vendor/github.com/coreos/etcd/clientv3:go_default_library",
|
"//vendor/github.com/coreos/etcd/clientv3:go_default_library",
|
||||||
"//vendor/github.com/stretchr/testify/require:go_default_library",
|
"//vendor/github.com/stretchr/testify/require:go_default_library",
|
||||||
|
"//vendor/k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1:go_default_library",
|
||||||
|
"//vendor/k8s.io/apiextensions-apiserver/examples/client-go/client:go_default_library",
|
||||||
|
"//vendor/k8s.io/apiextensions-apiserver/examples/client-go/controller:go_default_library",
|
||||||
"//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
|
"//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
|
||||||
"//vendor/k8s.io/apiextensions-apiserver/pkg/apiserver:go_default_library",
|
"//vendor/k8s.io/apiextensions-apiserver/pkg/apiserver:go_default_library",
|
||||||
"//vendor/k8s.io/apiextensions-apiserver/test/integration/testserver:go_default_library",
|
"//vendor/k8s.io/apiextensions-apiserver/test/integration/testserver:go_default_library",
|
||||||
@ -33,5 +37,6 @@ go_test(
|
|||||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/dynamic:go_default_library",
|
"//vendor/k8s.io/client-go/dynamic:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2017 The Kubernetes 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 integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/apiextensions-apiserver/test/integration/testserver"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
apiv1 "k8s.io/client-go/pkg/api/v1"
|
||||||
|
|
||||||
|
examplecrv1 "k8s.io/apiextensions-apiserver/examples/client-go/apis/cr/v1"
|
||||||
|
exampleclient "k8s.io/apiextensions-apiserver/examples/client-go/client"
|
||||||
|
examplecontroller "k8s.io/apiextensions-apiserver/examples/client-go/controller"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestClientGoCustomResourceExample(t *testing.T) {
|
||||||
|
t.Logf("Creating apiextensions apiserver")
|
||||||
|
config, err := testserver.DefaultServerConfig()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
stopCh, apiExtensionClient, _, err := testserver.StartServer(config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
defer close(stopCh)
|
||||||
|
|
||||||
|
t.Logf("Creating CustomResourceDefinition")
|
||||||
|
crd, err := exampleclient.CreateCustomResourceDefinition(apiExtensionClient)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error creating the CustomResourceDefinition: %v", err)
|
||||||
|
}
|
||||||
|
defer apiExtensionClient.ApiextensionsV1beta1().CustomResourceDefinitions().Delete(crd.Name, nil)
|
||||||
|
|
||||||
|
exampleClient, exampleScheme, err := exampleclient.NewClient(config.GenericConfig.LoopbackClientConfig)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Starting a controller on instances of custom resource %q", examplecrv1.ExampleResourcePlural)
|
||||||
|
controller := examplecontroller.ExampleController{
|
||||||
|
ExampleClient: exampleClient,
|
||||||
|
ExampleScheme: exampleScheme,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||||
|
defer cancelFunc()
|
||||||
|
go controller.Run(ctx)
|
||||||
|
|
||||||
|
// Create an instance of our custom resource
|
||||||
|
t.Logf("Creating custom resource instance")
|
||||||
|
example := &examplecrv1.Example{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "example1",
|
||||||
|
},
|
||||||
|
Spec: examplecrv1.ExampleSpec{
|
||||||
|
Foo: "hello",
|
||||||
|
Bar: true,
|
||||||
|
},
|
||||||
|
Status: examplecrv1.ExampleStatus{
|
||||||
|
State: examplecrv1.ExampleStateCreated,
|
||||||
|
Message: "Created, not processed yet",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
var result examplecrv1.Example
|
||||||
|
err = exampleClient.Post().
|
||||||
|
Resource(examplecrv1.ExampleResourcePlural).
|
||||||
|
Namespace(apiv1.NamespaceDefault).
|
||||||
|
Body(example).
|
||||||
|
Do().Into(&result)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to create an instance of the custom resource: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Waiting instance to be processed by the controller")
|
||||||
|
if err := exampleclient.WaitForExampleInstanceProcessed(exampleClient, "example1"); err != nil {
|
||||||
|
t.Fatalf("Instance was not processed correctly: %v", err)
|
||||||
|
}
|
||||||
|
t.Logf("Instance is processed")
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
# Custom Resource Example
|
||||||
|
|
||||||
|
**Note:** CustomResourceDefinition is the successor of the deprecated ThirdPartyResource.
|
||||||
|
|
||||||
|
For a client-go example using CustomResourceDefinitions, go to
|
||||||
|
|
||||||
|
http://github.com/kubernetes/apiextensions-apiserver/examples/client-go.
|
@ -8,12 +8,6 @@ load(
|
|||||||
"go_library",
|
"go_library",
|
||||||
)
|
)
|
||||||
|
|
||||||
go_binary(
|
|
||||||
name = "third-party-resources",
|
|
||||||
library = ":go_default_library",
|
|
||||||
tags = ["automanaged"],
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = ["main.go"],
|
srcs = ["main.go"],
|
||||||
@ -21,12 +15,18 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/examples/third-party-resources/apis/tpr/v1:go_default_library",
|
"//vendor/k8s.io/client-go/examples/third-party-resources-deprecated/apis/tpr/v1:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/examples/third-party-resources/client:go_default_library",
|
"//vendor/k8s.io/client-go/examples/third-party-resources-deprecated/client:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/examples/third-party-resources/controller:go_default_library",
|
"//vendor/k8s.io/client-go/examples/third-party-resources-deprecated/controller:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
|
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
|
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
go_binary(
|
||||||
|
name = "third-party-resources-deprecated",
|
||||||
|
library = ":go_default_library",
|
||||||
|
tags = ["automanaged"],
|
||||||
|
)
|
@ -1,4 +1,6 @@
|
|||||||
# Third Party Resources Example
|
# Third Party Resources Example – Deprecated
|
||||||
|
|
||||||
|
**Note:** ThirdPartyResources are deprecated since 1.7. The successor is CustomResourceDefinition in the apiextensions.k8s.io API group.
|
||||||
|
|
||||||
This particular example demonstrates how to perform basic operations such as:
|
This particular example demonstrates how to perform basic operations such as:
|
||||||
|
|
@ -0,0 +1,37 @@
|
|||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
licenses(["notice"])
|
||||||
|
|
||||||
|
load(
|
||||||
|
"@io_bazel_rules_go//go:def.bzl",
|
||||||
|
"go_library",
|
||||||
|
"go_test",
|
||||||
|
)
|
||||||
|
|
||||||
|
go_test(
|
||||||
|
name = "go_default_test",
|
||||||
|
srcs = ["types_test.go"],
|
||||||
|
library = ":go_default_library",
|
||||||
|
tags = ["automanaged"],
|
||||||
|
deps = [
|
||||||
|
"//vendor/github.com/google/gofuzz:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/api/testing:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"register.go",
|
||||||
|
"types.go",
|
||||||
|
],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
deps = [
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2017 The Kubernetes 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 v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
const ExampleResourcePlural = "examples"
|
||||||
|
|
||||||
|
type Example struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ObjectMeta `json:"metadata"`
|
||||||
|
Spec ExampleSpec `json:"spec"`
|
||||||
|
Status ExampleStatus `json:"status,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ExampleSpec struct {
|
||||||
|
Foo string `json:"foo"`
|
||||||
|
Bar bool `json:"bar"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ExampleStatus struct {
|
||||||
|
State ExampleState `json:"state,omitempty"`
|
||||||
|
Message string `json:"message,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ExampleState string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ExampleStateCreated ExampleState = "Created"
|
||||||
|
ExampleStateProcessed ExampleState = "Processed"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ExampleList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ListMeta `json:"metadata"`
|
||||||
|
Items []Example `json:"items"`
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2017 The Kubernetes 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 v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/gofuzz"
|
||||||
|
|
||||||
|
apitesting "k8s.io/apimachinery/pkg/api/testing"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ runtime.Object = &Example{}
|
||||||
|
var _ metav1.ObjectMetaAccessor = &Example{}
|
||||||
|
|
||||||
|
var _ runtime.Object = &ExampleList{}
|
||||||
|
var _ metav1.ListMetaAccessor = &ExampleList{}
|
||||||
|
|
||||||
|
func exampleFuzzerFuncs(t apitesting.TestingCommon) []interface{} {
|
||||||
|
return []interface{}{
|
||||||
|
func(obj *ExampleList, c fuzz.Continue) {
|
||||||
|
c.FuzzNoCustom(obj)
|
||||||
|
obj.Items = make([]Example, c.Intn(10))
|
||||||
|
for i := range obj.Items {
|
||||||
|
c.Fuzz(&obj.Items[i])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestRoundTrip tests that the third-party kinds can be marshaled and unmarshaled correctly to/from JSON
|
||||||
|
// without the loss of information. Moreover, deep copy is tested.
|
||||||
|
func TestRoundTrip(t *testing.T) {
|
||||||
|
scheme := runtime.NewScheme()
|
||||||
|
codecs := serializer.NewCodecFactory(scheme)
|
||||||
|
|
||||||
|
AddToScheme(scheme)
|
||||||
|
|
||||||
|
seed := rand.Int63()
|
||||||
|
fuzzerFuncs := apitesting.MergeFuzzerFuncs(t, apitesting.GenericFuzzerFuncs(t, codecs), exampleFuzzerFuncs(t))
|
||||||
|
fuzzer := apitesting.FuzzerFor(fuzzerFuncs, rand.NewSource(seed))
|
||||||
|
|
||||||
|
apitesting.RoundTripSpecificKindWithoutProtobuf(t, SchemeGroupVersion.WithKind("Example"), scheme, codecs, fuzzer, nil)
|
||||||
|
apitesting.RoundTripSpecificKindWithoutProtobuf(t, SchemeGroupVersion.WithKind("ExampleList"), scheme, codecs, fuzzer, nil)
|
||||||
|
}
|
@ -20,7 +20,7 @@ go_library(
|
|||||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/examples/third-party-resources/apis/tpr/v1:go_default_library",
|
"//vendor/k8s.io/client-go/examples/third-party-resources-deprecated/apis/tpr/v1:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
|
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/pkg/apis/extensions/v1beta1:go_default_library",
|
"//vendor/k8s.io/client-go/pkg/apis/extensions/v1beta1:go_default_library",
|
@ -21,7 +21,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
|
|
||||||
tprv1 "k8s.io/client-go/examples/third-party-resources/apis/tpr/v1"
|
tprv1 "k8s.io/client-go/examples/third-party-resources-deprecated/apis/tpr/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewClient(cfg *rest.Config) (*rest.RESTClient, *runtime.Scheme, error) {
|
func NewClient(cfg *rest.Config) (*rest.RESTClient, *runtime.Scheme, error) {
|
@ -22,7 +22,7 @@ import (
|
|||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
tprv1 "k8s.io/client-go/examples/third-party-resources/apis/tpr/v1"
|
tprv1 "k8s.io/client-go/examples/third-party-resources-deprecated/apis/tpr/v1"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
apiv1 "k8s.io/client-go/pkg/api/v1"
|
apiv1 "k8s.io/client-go/pkg/api/v1"
|
||||||
"k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
"k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
@ -14,7 +14,7 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//vendor/k8s.io/apimachinery/pkg/fields:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/fields:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/examples/third-party-resources/apis/tpr/v1:go_default_library",
|
"//vendor/k8s.io/client-go/examples/third-party-resources-deprecated/apis/tpr/v1:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
|
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
|
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
|
@ -26,7 +26,7 @@ import (
|
|||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
|
|
||||||
tprv1 "k8s.io/client-go/examples/third-party-resources/apis/tpr/v1"
|
tprv1 "k8s.io/client-go/examples/third-party-resources-deprecated/apis/tpr/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Watcher is an example of watching on resource create/update/delete events
|
// Watcher is an example of watching on resource create/update/delete events
|
@ -32,9 +32,9 @@ import (
|
|||||||
// Uncomment the following line to load the gcp plugin (only required to authenticate against GKE clusters).
|
// Uncomment the following line to load the gcp plugin (only required to authenticate against GKE clusters).
|
||||||
// _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
// _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||||
|
|
||||||
tprv1 "k8s.io/client-go/examples/third-party-resources/apis/tpr/v1"
|
tprv1 "k8s.io/client-go/examples/third-party-resources-deprecated/apis/tpr/v1"
|
||||||
exampleclient "k8s.io/client-go/examples/third-party-resources/client"
|
exampleclient "k8s.io/client-go/examples/third-party-resources-deprecated/client"
|
||||||
examplecontroller "k8s.io/client-go/examples/third-party-resources/controller"
|
examplecontroller "k8s.io/client-go/examples/third-party-resources-deprecated/controller"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
6
test/integration/thirdparty/BUILD
vendored
6
test/integration/thirdparty/BUILD
vendored
@ -29,9 +29,9 @@ go_test(
|
|||||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/examples/third-party-resources/apis/tpr/v1:go_default_library",
|
"//vendor/k8s.io/client-go/examples/third-party-resources-deprecated/apis/tpr/v1:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/examples/third-party-resources/client:go_default_library",
|
"//vendor/k8s.io/client-go/examples/third-party-resources-deprecated/client:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/examples/third-party-resources/controller:go_default_library",
|
"//vendor/k8s.io/client-go/examples/third-party-resources-deprecated/controller:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
|
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||||
|
@ -28,9 +28,9 @@ import (
|
|||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
"k8s.io/kubernetes/test/integration/framework"
|
"k8s.io/kubernetes/test/integration/framework"
|
||||||
|
|
||||||
exampletprv1 "k8s.io/client-go/examples/third-party-resources/apis/tpr/v1"
|
exampletprv1 "k8s.io/client-go/examples/third-party-resources-deprecated/apis/tpr/v1"
|
||||||
exampleclient "k8s.io/client-go/examples/third-party-resources/client"
|
exampleclient "k8s.io/client-go/examples/third-party-resources-deprecated/client"
|
||||||
examplecontroller "k8s.io/client-go/examples/third-party-resources/controller"
|
examplecontroller "k8s.io/client-go/examples/third-party-resources-deprecated/controller"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestClientGoThirdPartyResourceExample(t *testing.T) {
|
func TestClientGoThirdPartyResourceExample(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user