mirror of https://github.com/k3s-io/k3s
Merge pull request #55127 from caesarxuchao/webhook-do-conversion
Automatic merge from submit-queue (batch tested with PRs 54005, 55127, 53850, 55486, 53440). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Validation webhook plugin converts objects to the external version before sending to webhooks **What this PR does / why we need it**: **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: https://github.com/kubernetes/features/issues/492 **Special notes for your reviewer**: **Release note**: ```release-note The apiserver sends external versioned object to the admission webhooks now. Please update the webhooks to expect admissionReview.spec.object.raw to be serialized external versions of objects. ```pull/6/head
commit
cba5aa0590
|
@ -552,6 +552,8 @@ staging/src/k8s.io/apiserver/pkg/apis/audit/v1beta1
|
|||
staging/src/k8s.io/apiserver/pkg/apis/audit/validation
|
||||
staging/src/k8s.io/apiserver/pkg/apis/example
|
||||
staging/src/k8s.io/apiserver/pkg/apis/example/v1
|
||||
staging/src/k8s.io/apiserver/pkg/apis/example2
|
||||
staging/src/k8s.io/apiserver/pkg/apis/example2/v1
|
||||
staging/src/k8s.io/apiserver/pkg/audit
|
||||
staging/src/k8s.io/apiserver/pkg/audit/policy
|
||||
staging/src/k8s.io/apiserver/pkg/authentication/authenticatorfactory
|
||||
|
|
|
@ -419,7 +419,7 @@ function start_apiserver {
|
|||
fi
|
||||
|
||||
# Admission Controllers to invoke prior to persisting objects in cluster
|
||||
ADMISSION_CONTROL=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount${security_admission},DefaultStorageClass,DefaultTolerationSeconds,ResourceQuota,GenericAdmissionWebhook
|
||||
ADMISSION_CONTROL=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount${security_admission},DefaultStorageClass,DefaultTolerationSeconds,GenericAdmissionWebhook,ResourceQuota
|
||||
# This is the default dir and filename where the apiserver will generate a self-signed cert
|
||||
# which should be able to be used as the CA to verify itself
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ PACKAGES=(
|
|||
k8s.io/metrics/pkg/apis/custom_metrics/v1beta1
|
||||
k8s.io/apiserver/pkg/apis/audit/v1alpha1
|
||||
k8s.io/apiserver/pkg/apis/audit/v1beta1
|
||||
k8s.io/apiserver/pkg/apis/example2/v1
|
||||
)
|
||||
|
||||
# requires the 'proto' tag to build (will remove when ready)
|
||||
|
|
|
@ -59,6 +59,7 @@ openapi_library(
|
|||
"k8s.io/apiserver/pkg/apis/audit/v1alpha1",
|
||||
"k8s.io/apiserver/pkg/apis/audit/v1beta1",
|
||||
"k8s.io/apiserver/pkg/apis/example/v1",
|
||||
"k8s.io/apiserver/pkg/apis/example2/v1",
|
||||
"k8s.io/client-go/pkg/version",
|
||||
"k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1",
|
||||
"k8s.io/metrics/pkg/apis/custom_metrics/v1beta1",
|
||||
|
|
|
@ -96,6 +96,7 @@ filegroup(
|
|||
"//staging/src/k8s.io/apiserver/pkg/apis/apiserver:all-srcs",
|
||||
"//staging/src/k8s.io/apiserver/pkg/apis/audit:all-srcs",
|
||||
"//staging/src/k8s.io/apiserver/pkg/apis/example:all-srcs",
|
||||
"//staging/src/k8s.io/apiserver/pkg/apis/example2:all-srcs",
|
||||
"//staging/src/k8s.io/apiserver/pkg/audit:all-srcs",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:all-srcs",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticatorfactory:all-srcs",
|
||||
|
|
|
@ -146,7 +146,11 @@ func NewCurletInstance(namespace, name string) *unstructured.Unstructured {
|
|||
}
|
||||
}
|
||||
|
||||
func CreateNewCustomResourceDefinition(crd *apiextensionsv1beta1.CustomResourceDefinition, apiExtensionsClient clientset.Interface, clientPool dynamic.ClientPool) (dynamic.Interface, error) {
|
||||
// CreateNewCustomResourceDefinitionWatchUnsafe creates the CRD and makes sure
|
||||
// the apiextension apiserver has installed the CRD. But it's not safe to watch
|
||||
// the created CR. Please call CreateNewCustomResourceDefinition if you need to
|
||||
// watch the CR.
|
||||
func CreateNewCustomResourceDefinitionWatchUnsafe(crd *apiextensionsv1beta1.CustomResourceDefinition, apiExtensionsClient clientset.Interface, clientPool dynamic.ClientPool) (dynamic.Interface, error) {
|
||||
_, err := apiExtensionsClient.Apiextensions().CustomResourceDefinitions().Create(crd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -169,7 +173,11 @@ func CreateNewCustomResourceDefinition(crd *apiextensionsv1beta1.CustomResourceD
|
|||
return nil, err
|
||||
}
|
||||
|
||||
dynamicClient, err := clientPool.ClientForGroupVersionResource(schema.GroupVersionResource{Group: crd.Spec.Group, Version: crd.Spec.Version, Resource: crd.Spec.Names.Plural})
|
||||
return clientPool.ClientForGroupVersionResource(schema.GroupVersionResource{Group: crd.Spec.Group, Version: crd.Spec.Version, Resource: crd.Spec.Names.Plural})
|
||||
}
|
||||
|
||||
func CreateNewCustomResourceDefinition(crd *apiextensionsv1beta1.CustomResourceDefinition, apiExtensionsClient clientset.Interface, clientPool dynamic.ClientPool) (dynamic.Interface, error) {
|
||||
dynamicClient, err := CreateNewCustomResourceDefinitionWatchUnsafe(crd, apiExtensionsClient, clientPool)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ go_library(
|
|||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
|
@ -46,6 +47,7 @@ go_test(
|
|||
"admission_test.go",
|
||||
"authentication_test.go",
|
||||
"certs_test.go",
|
||||
"conversion_test.go",
|
||||
"rules_test.go",
|
||||
"serviceresolver_test.go",
|
||||
],
|
||||
|
@ -58,11 +60,15 @@ go_test(
|
|||
"//vendor/k8s.io/apimachinery/pkg/api/equality: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/unstructured:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/apis/example:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/apis/example/v1:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/apis/example2/v1:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
|
||||
|
|
|
@ -37,6 +37,7 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
|
@ -134,6 +135,8 @@ type GenericAdmissionWebhook struct {
|
|||
negotiatedSerializer runtime.NegotiatedSerializer
|
||||
namespaceLister corelisters.NamespaceLister
|
||||
client clientset.Interface
|
||||
convertor runtime.ObjectConvertor
|
||||
creator runtime.ObjectCreater
|
||||
|
||||
authInfoResolver AuthenticationInfoResolver
|
||||
cache *lru.Cache
|
||||
|
@ -169,6 +172,8 @@ func (a *GenericAdmissionWebhook) SetScheme(scheme *runtime.Scheme) {
|
|||
a.negotiatedSerializer = serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{
|
||||
Serializer: serializer.NewCodecFactory(scheme).LegacyCodec(admissionv1alpha1.SchemeGroupVersion),
|
||||
})
|
||||
a.convertor = scheme
|
||||
a.creator = scheme
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,6 +224,37 @@ func (a *GenericAdmissionWebhook) loadConfiguration(attr admission.Attributes) (
|
|||
return hookConfig, nil
|
||||
}
|
||||
|
||||
type versionedAttributes struct {
|
||||
admission.Attributes
|
||||
oldObject runtime.Object
|
||||
object runtime.Object
|
||||
}
|
||||
|
||||
func (v versionedAttributes) GetObject() runtime.Object {
|
||||
return v.object
|
||||
}
|
||||
|
||||
func (v versionedAttributes) GetOldObject() runtime.Object {
|
||||
return v.oldObject
|
||||
}
|
||||
|
||||
func (a *GenericAdmissionWebhook) convertToGVK(obj runtime.Object, gvk schema.GroupVersionKind) (runtime.Object, error) {
|
||||
// Unlike other resources, custom resources do not have internal version, so
|
||||
// if obj is a custom resource, it should not need conversion.
|
||||
if obj.GetObjectKind().GroupVersionKind() == gvk {
|
||||
return obj, nil
|
||||
}
|
||||
out, err := a.creator.New(gvk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = a.convertor.Convert(obj, out, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Admit makes an admission decision based on the request attributes.
|
||||
func (a *GenericAdmissionWebhook) Admit(attr admission.Attributes) error {
|
||||
hookConfig, err := a.loadConfiguration(attr)
|
||||
|
@ -228,14 +264,49 @@ func (a *GenericAdmissionWebhook) Admit(attr admission.Attributes) error {
|
|||
hooks := hookConfig.Webhooks
|
||||
ctx := context.TODO()
|
||||
|
||||
errCh := make(chan error, len(hooks))
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(len(hooks))
|
||||
var relevantHooks []*v1alpha1.Webhook
|
||||
for i := range hooks {
|
||||
call, err := a.shouldCallHook(&hooks[i], attr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if call {
|
||||
relevantHooks = append(relevantHooks, &hooks[i])
|
||||
}
|
||||
}
|
||||
|
||||
if len(relevantHooks) == 0 {
|
||||
// no matching hooks
|
||||
return nil
|
||||
}
|
||||
|
||||
// convert the object to the external version before sending it to the webhook
|
||||
versionedAttr := versionedAttributes{
|
||||
Attributes: attr,
|
||||
}
|
||||
if oldObj := attr.GetOldObject(); oldObj != nil {
|
||||
out, err := a.convertToGVK(oldObj, attr.GetKind())
|
||||
if err != nil {
|
||||
return apierrors.NewInternalError(err)
|
||||
}
|
||||
versionedAttr.oldObject = out
|
||||
}
|
||||
if obj := attr.GetObject(); obj != nil {
|
||||
out, err := a.convertToGVK(obj, attr.GetKind())
|
||||
if err != nil {
|
||||
return apierrors.NewInternalError(err)
|
||||
}
|
||||
versionedAttr.object = out
|
||||
}
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
errCh := make(chan error, len(relevantHooks))
|
||||
wg.Add(len(relevantHooks))
|
||||
for i := range relevantHooks {
|
||||
go func(hook *v1alpha1.Webhook) {
|
||||
defer wg.Done()
|
||||
|
||||
err := a.callHook(ctx, hook, attr)
|
||||
err := a.callHook(ctx, hook, versionedAttr)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
@ -256,7 +327,7 @@ func (a *GenericAdmissionWebhook) Admit(attr admission.Attributes) error {
|
|||
|
||||
glog.Warningf("rejected by webhook %q: %#v", hook.Name, err)
|
||||
errCh <- err
|
||||
}(&hooks[i])
|
||||
}(relevantHooks[i])
|
||||
}
|
||||
wg.Wait()
|
||||
close(errCh)
|
||||
|
@ -313,7 +384,7 @@ func (a *GenericAdmissionWebhook) getNamespaceLabels(attr admission.Attributes)
|
|||
|
||||
// whether the request is exempted by the webhook because of the
|
||||
// namespaceSelector of the webhook.
|
||||
func (a *GenericAdmissionWebhook) exemptedByNamespaceSelector(h *v1alpha1.Webhook, attr admission.Attributes) (bool, error) {
|
||||
func (a *GenericAdmissionWebhook) exemptedByNamespaceSelector(h *v1alpha1.Webhook, attr admission.Attributes) (bool, *apierrors.StatusError) {
|
||||
namespaceName := attr.GetNamespace()
|
||||
if len(namespaceName) == 0 && attr.GetResource().Resource != "namespaces" {
|
||||
// If the request is about a cluster scoped resource, and it is not a
|
||||
|
@ -323,8 +394,14 @@ func (a *GenericAdmissionWebhook) exemptedByNamespaceSelector(h *v1alpha1.Webhoo
|
|||
return true, nil
|
||||
}
|
||||
namespaceLabels, err := a.getNamespaceLabels(attr)
|
||||
// this means the namespace is not found, for backwards compatibility,
|
||||
// return a 404
|
||||
if apierrors.IsNotFound(err) {
|
||||
return false, err
|
||||
status, ok := err.(apierrors.APIStatus)
|
||||
if !ok {
|
||||
return false, apierrors.NewInternalError(err)
|
||||
}
|
||||
return false, &apierrors.StatusError{status.Status()}
|
||||
}
|
||||
if err != nil {
|
||||
return false, apierrors.NewInternalError(err)
|
||||
|
@ -337,15 +414,8 @@ func (a *GenericAdmissionWebhook) exemptedByNamespaceSelector(h *v1alpha1.Webhoo
|
|||
return !selector.Matches(labels.Set(namespaceLabels)), nil
|
||||
}
|
||||
|
||||
func (a *GenericAdmissionWebhook) callHook(ctx context.Context, h *v1alpha1.Webhook, attr admission.Attributes) error {
|
||||
excluded, err := a.exemptedByNamespaceSelector(h, attr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if excluded {
|
||||
return nil
|
||||
}
|
||||
matches := false
|
||||
func (a *GenericAdmissionWebhook) shouldCallHook(h *v1alpha1.Webhook, attr admission.Attributes) (bool, *apierrors.StatusError) {
|
||||
var matches bool
|
||||
for _, r := range h.Rules {
|
||||
m := RuleMatcher{Rule: r, Attr: attr}
|
||||
if m.Matches() {
|
||||
|
@ -354,9 +424,17 @@ func (a *GenericAdmissionWebhook) callHook(ctx context.Context, h *v1alpha1.Webh
|
|||
}
|
||||
}
|
||||
if !matches {
|
||||
return nil
|
||||
return false, nil
|
||||
}
|
||||
|
||||
excluded, err := a.exemptedByNamespaceSelector(h, attr)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return !excluded, nil
|
||||
}
|
||||
|
||||
func (a *GenericAdmissionWebhook) callHook(ctx context.Context, h *v1alpha1.Webhook, attr admission.Attributes) error {
|
||||
// Make the webhook request
|
||||
request := createAdmissionReview(attr)
|
||||
client, err := a.hookClient(h)
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
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 webhook
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/apis/example"
|
||||
examplev1 "k8s.io/apiserver/pkg/apis/example/v1"
|
||||
example2v1 "k8s.io/apiserver/pkg/apis/example2/v1"
|
||||
)
|
||||
|
||||
func initiateScheme() *runtime.Scheme {
|
||||
s := runtime.NewScheme()
|
||||
example.AddToScheme(s)
|
||||
examplev1.AddToScheme(s)
|
||||
example2v1.AddToScheme(s)
|
||||
return s
|
||||
}
|
||||
|
||||
func TestConvertToGVK(t *testing.T) {
|
||||
scheme := initiateScheme()
|
||||
w := GenericAdmissionWebhook{
|
||||
convertor: scheme,
|
||||
creator: scheme,
|
||||
}
|
||||
table := map[string]struct {
|
||||
obj runtime.Object
|
||||
gvk schema.GroupVersionKind
|
||||
expectedObj runtime.Object
|
||||
}{
|
||||
"convert example#Pod to example/v1#Pod": {
|
||||
obj: &example.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod1",
|
||||
Labels: map[string]string{
|
||||
"key": "value",
|
||||
},
|
||||
},
|
||||
Spec: example.PodSpec{
|
||||
RestartPolicy: example.RestartPolicy("never"),
|
||||
},
|
||||
},
|
||||
gvk: examplev1.SchemeGroupVersion.WithKind("Pod"),
|
||||
expectedObj: &examplev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod1",
|
||||
Labels: map[string]string{
|
||||
"key": "value",
|
||||
},
|
||||
},
|
||||
Spec: examplev1.PodSpec{
|
||||
RestartPolicy: examplev1.RestartPolicy("never"),
|
||||
},
|
||||
},
|
||||
},
|
||||
"convert example#replicaset to example2/v1#replicaset": {
|
||||
obj: &example.ReplicaSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "rs1",
|
||||
Labels: map[string]string{
|
||||
"key": "value",
|
||||
},
|
||||
},
|
||||
Spec: example.ReplicaSetSpec{
|
||||
Replicas: 1,
|
||||
},
|
||||
},
|
||||
gvk: example2v1.SchemeGroupVersion.WithKind("ReplicaSet"),
|
||||
expectedObj: &example2v1.ReplicaSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "rs1",
|
||||
Labels: map[string]string{
|
||||
"key": "value",
|
||||
},
|
||||
},
|
||||
Spec: example2v1.ReplicaSetSpec{
|
||||
Replicas: func() *int32 { var i int32; i = 1; return &i }(),
|
||||
},
|
||||
},
|
||||
},
|
||||
"no conversion for Unstructured object whose gvk matches the desired gvk": {
|
||||
obj: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "mygroup.k8s.io/v1",
|
||||
"kind": "Flunder",
|
||||
"data": map[string]interface{}{
|
||||
"Key": "Value",
|
||||
},
|
||||
},
|
||||
},
|
||||
gvk: schema.GroupVersionKind{Group: "mygroup.k8s.io", Version: "v1", Kind: "Flunder"},
|
||||
expectedObj: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "mygroup.k8s.io/v1",
|
||||
"kind": "Flunder",
|
||||
"data": map[string]interface{}{
|
||||
"Key": "Value",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, test := range table {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
actual, err := w.convertToGVK(test.obj, test.gvk)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !reflect.DeepEqual(actual, test.expectedObj) {
|
||||
t.Errorf("\nexpected:\n%#v\ngot:\n %#v\n", test.expectedObj, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package install installs the certificates API group, making it available as
|
||||
// Package install installs the example API group, making it available as
|
||||
// an option to all of the API encoding/decoding machinery.
|
||||
package install
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ func Resource(resource string) schema.GroupResource {
|
|||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&Pod{},
|
||||
&ReplicaSet{},
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -136,3 +136,35 @@ type PodList struct {
|
|||
|
||||
Items []Pod
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ReplicaSet ensures that a specified number of pod replicas are running at any given time.
|
||||
type ReplicaSet struct {
|
||||
metav1.TypeMeta
|
||||
// +optional
|
||||
metav1.ObjectMeta
|
||||
|
||||
// Spec defines the desired behavior of this ReplicaSet.
|
||||
// +optional
|
||||
Spec ReplicaSetSpec
|
||||
|
||||
// Status is the current status of this ReplicaSet. This data may be
|
||||
// out of date by some window of time.
|
||||
// +optional
|
||||
Status ReplicaSetStatus
|
||||
}
|
||||
|
||||
// ReplicaSetSpec is the specification of a ReplicaSet.
|
||||
// As the internal representation of a ReplicaSet, it must have
|
||||
// a Template set.
|
||||
type ReplicaSetSpec struct {
|
||||
// Replicas is the number of desired replicas.
|
||||
Replicas int32
|
||||
}
|
||||
|
||||
// ReplicaSetStatus represents the current status of a ReplicaSet.
|
||||
type ReplicaSetStatus struct {
|
||||
// Replicas is the number of actual replicas.
|
||||
Replicas int32
|
||||
}
|
||||
|
|
|
@ -178,3 +178,64 @@ func (in *PodStatus) DeepCopy() *PodStatus {
|
|||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ReplicaSet) DeepCopyInto(out *ReplicaSet) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
out.Status = in.Status
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicaSet.
|
||||
func (in *ReplicaSet) DeepCopy() *ReplicaSet {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ReplicaSet)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ReplicaSet) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ReplicaSetSpec) DeepCopyInto(out *ReplicaSetSpec) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicaSetSpec.
|
||||
func (in *ReplicaSetSpec) DeepCopy() *ReplicaSetSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ReplicaSetSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ReplicaSetStatus) DeepCopyInto(out *ReplicaSetStatus) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicaSetStatus.
|
||||
func (in *ReplicaSetStatus) DeepCopy() *ReplicaSetStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ReplicaSetStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"register.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
],
|
||||
importpath = "k8s.io/apiserver/pkg/apis/example2",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/apis/example:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//staging/src/k8s.io/apiserver/pkg/apis/example2/install:all-srcs",
|
||||
"//staging/src/k8s.io/apiserver/pkg/apis/example2/v1:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +groupName=example2.k8s.io
|
||||
//
|
||||
// package example2 contains an example API whose internal version is defined in
|
||||
// another group ("example"). This happens if a type is moved to a different
|
||||
// group. It's not recommended to move types across groups, though Kubernetes
|
||||
// have a few cases due to historical reasons. This package is for tests.
|
||||
package example2 // import "k8s.io/apiserver/pkg/apis/example2"
|
|
@ -0,0 +1,45 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["install.go"],
|
||||
importpath = "k8s.io/apiserver/pkg/apis/example2/install",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery/announced:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery/registered:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/apis/example:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/apis/example2:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/apis/example2/v1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["roundtrip_test.go"],
|
||||
importpath = "k8s.io/apiserver/pkg/apis/example2/install",
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/testing/roundtrip:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/apis/example/fuzzer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
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 install installs the example2 API group, making it available as
|
||||
// an option to all of the API encoding/decoding machinery.
|
||||
package install
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/apimachinery/announced"
|
||||
"k8s.io/apimachinery/pkg/apimachinery/registered"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/apis/example"
|
||||
"k8s.io/apiserver/pkg/apis/example2"
|
||||
example2v1 "k8s.io/apiserver/pkg/apis/example2/v1"
|
||||
)
|
||||
|
||||
// Install registers the API group and adds types to a scheme
|
||||
func Install(groupFactoryRegistry announced.APIGroupFactoryRegistry, registry *registered.APIRegistrationManager, scheme *runtime.Scheme) {
|
||||
if err := announced.NewGroupMetaFactory(
|
||||
&announced.GroupMetaFactoryArgs{
|
||||
GroupName: example2.GroupName,
|
||||
VersionPreferenceOrder: []string{example2v1.SchemeGroupVersion.Version},
|
||||
AddInternalObjectsToScheme: example.AddToScheme,
|
||||
},
|
||||
announced.VersionToSchemeFunc{
|
||||
example2v1.SchemeGroupVersion.Version: example2v1.AddToScheme,
|
||||
},
|
||||
).Announce(groupFactoryRegistry).RegisterAndEnable(registry, scheme); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
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 install
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/testing/roundtrip"
|
||||
examplefuzzer "k8s.io/apiserver/pkg/apis/example/fuzzer"
|
||||
)
|
||||
|
||||
func TestRoundTrip(t *testing.T) {
|
||||
roundtrip.RoundTripTestForAPIGroup(t, Install, examplefuzzer.Funcs)
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
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 example2
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/apis/example"
|
||||
)
|
||||
|
||||
var (
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// GroupName is the group name use in this package
|
||||
const GroupName = "example2.apiserver.k8s.io"
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
|
||||
|
||||
// Kind takes an unqualified kind and returns a Group qualified GroupKind
|
||||
func Kind(kind string) schema.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
// Adds the list of known types to the given scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&example.ReplicaSet{},
|
||||
)
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"conversion.go",
|
||||
"defaults.go",
|
||||
"doc.go",
|
||||
"generated.pb.go",
|
||||
"register.go",
|
||||
"types.go",
|
||||
"types_swagger_doc_generated.go",
|
||||
"zz_generated.conversion.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
"zz_generated.defaults.go",
|
||||
],
|
||||
importpath = "k8s.io/apiserver/pkg/apis/example2/v1",
|
||||
deps = [
|
||||
"//vendor/github.com/gogo/protobuf/proto:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/apis/example:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "go_default_library_protos",
|
||||
srcs = ["generated.proto"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
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 (
|
||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
example "k8s.io/apiserver/pkg/apis/example"
|
||||
)
|
||||
|
||||
func addConversionFuncs(scheme *runtime.Scheme) error {
|
||||
// Add non-generated conversion functions to handle the *int32 -> int32
|
||||
// conversion. A pointer is useful in the versioned type so we can default
|
||||
// it, but a plain int32 is more convenient in the internal type. These
|
||||
// functions are the same as the autogenerated ones in every other way.
|
||||
err := scheme.AddConversionFuncs(
|
||||
Convert_example_ReplicaSetSpec_To_v1_ReplicaSetSpec,
|
||||
Convert_v1_ReplicaSetSpec_To_example_ReplicaSetSpec,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_example_ReplicaSetSpec_To_v1_ReplicaSetSpec(in *example.ReplicaSetSpec, out *ReplicaSetSpec, s conversion.Scope) error {
|
||||
out.Replicas = new(int32)
|
||||
*out.Replicas = int32(in.Replicas)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_ReplicaSetSpec_To_example_ReplicaSetSpec(in *ReplicaSetSpec, out *example.ReplicaSetSpec, s conversion.Scope) error {
|
||||
if in.Replicas != nil {
|
||||
out.Replicas = *in.Replicas
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
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 (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
||||
// return RegisterDefaults(scheme)
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:conversion-gen=k8s.io/apiserver/pkg/apis/example2
|
||||
// +k8s:conversion-gen=k8s.io/apiserver/pkg/apis/example
|
||||
// +k8s:openapi-gen=false
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
|
||||
// +groupName=example2.apiserver.k8s.io
|
||||
package v1 // import "k8s.io/apiserver/pkg/apis/example2/v1"
|
|
@ -0,0 +1,682 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by protoc-gen-gogo.
|
||||
// source: k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/apis/example2/v1/generated.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package v1 is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/apis/example2/v1/generated.proto
|
||||
|
||||
It has these top-level messages:
|
||||
ReplicaSet
|
||||
ReplicaSetSpec
|
||||
ReplicaSetStatus
|
||||
*/
|
||||
package v1
|
||||
|
||||
import proto "github.com/gogo/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
import strings "strings"
|
||||
import reflect "reflect"
|
||||
|
||||
import io "io"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
func (m *ReplicaSet) Reset() { *m = ReplicaSet{} }
|
||||
func (*ReplicaSet) ProtoMessage() {}
|
||||
func (*ReplicaSet) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{0} }
|
||||
|
||||
func (m *ReplicaSetSpec) Reset() { *m = ReplicaSetSpec{} }
|
||||
func (*ReplicaSetSpec) ProtoMessage() {}
|
||||
func (*ReplicaSetSpec) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{1} }
|
||||
|
||||
func (m *ReplicaSetStatus) Reset() { *m = ReplicaSetStatus{} }
|
||||
func (*ReplicaSetStatus) ProtoMessage() {}
|
||||
func (*ReplicaSetStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{2} }
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*ReplicaSet)(nil), "k8s.io.apiserver.pkg.apis.example2.v1.ReplicaSet")
|
||||
proto.RegisterType((*ReplicaSetSpec)(nil), "k8s.io.apiserver.pkg.apis.example2.v1.ReplicaSetSpec")
|
||||
proto.RegisterType((*ReplicaSetStatus)(nil), "k8s.io.apiserver.pkg.apis.example2.v1.ReplicaSetStatus")
|
||||
}
|
||||
func (m *ReplicaSet) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalTo(dAtA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *ReplicaSet) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
dAtA[i] = 0xa
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.ObjectMeta.Size()))
|
||||
n1, err := m.ObjectMeta.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n1
|
||||
dAtA[i] = 0x12
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.Spec.Size()))
|
||||
n2, err := m.Spec.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n2
|
||||
dAtA[i] = 0x1a
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.Status.Size()))
|
||||
n3, err := m.Status.MarshalTo(dAtA[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i += n3
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (m *ReplicaSetSpec) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalTo(dAtA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *ReplicaSetSpec) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.Replicas != nil {
|
||||
dAtA[i] = 0x8
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(*m.Replicas))
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (m *ReplicaSetStatus) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalTo(dAtA)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *ReplicaSetStatus) MarshalTo(dAtA []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
dAtA[i] = 0x8
|
||||
i++
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(m.Replicas))
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func encodeFixed64Generated(dAtA []byte, offset int, v uint64) int {
|
||||
dAtA[offset] = uint8(v)
|
||||
dAtA[offset+1] = uint8(v >> 8)
|
||||
dAtA[offset+2] = uint8(v >> 16)
|
||||
dAtA[offset+3] = uint8(v >> 24)
|
||||
dAtA[offset+4] = uint8(v >> 32)
|
||||
dAtA[offset+5] = uint8(v >> 40)
|
||||
dAtA[offset+6] = uint8(v >> 48)
|
||||
dAtA[offset+7] = uint8(v >> 56)
|
||||
return offset + 8
|
||||
}
|
||||
func encodeFixed32Generated(dAtA []byte, offset int, v uint32) int {
|
||||
dAtA[offset] = uint8(v)
|
||||
dAtA[offset+1] = uint8(v >> 8)
|
||||
dAtA[offset+2] = uint8(v >> 16)
|
||||
dAtA[offset+3] = uint8(v >> 24)
|
||||
return offset + 4
|
||||
}
|
||||
func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int {
|
||||
for v >= 1<<7 {
|
||||
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
dAtA[offset] = uint8(v)
|
||||
return offset + 1
|
||||
}
|
||||
func (m *ReplicaSet) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
l = m.ObjectMeta.Size()
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
l = m.Spec.Size()
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
l = m.Status.Size()
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *ReplicaSetSpec) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
if m.Replicas != nil {
|
||||
n += 1 + sovGenerated(uint64(*m.Replicas))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *ReplicaSetStatus) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
n += 1 + sovGenerated(uint64(m.Replicas))
|
||||
return n
|
||||
}
|
||||
|
||||
func sovGenerated(x uint64) (n int) {
|
||||
for {
|
||||
n++
|
||||
x >>= 7
|
||||
if x == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
func sozGenerated(x uint64) (n int) {
|
||||
return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (this *ReplicaSet) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
s := strings.Join([]string{`&ReplicaSet{`,
|
||||
`ObjectMeta:` + strings.Replace(strings.Replace(this.ObjectMeta.String(), "ObjectMeta", "k8s_io_apimachinery_pkg_apis_meta_v1.ObjectMeta", 1), `&`, ``, 1) + `,`,
|
||||
`Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ReplicaSetSpec", "ReplicaSetSpec", 1), `&`, ``, 1) + `,`,
|
||||
`Status:` + strings.Replace(strings.Replace(this.Status.String(), "ReplicaSetStatus", "ReplicaSetStatus", 1), `&`, ``, 1) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func (this *ReplicaSetSpec) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
s := strings.Join([]string{`&ReplicaSetSpec{`,
|
||||
`Replicas:` + valueToStringGenerated(this.Replicas) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func (this *ReplicaSetStatus) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
s := strings.Join([]string{`&ReplicaSetStatus{`,
|
||||
`Replicas:` + fmt.Sprintf("%v", this.Replicas) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func valueToStringGenerated(v interface{}) string {
|
||||
rv := reflect.ValueOf(v)
|
||||
if rv.IsNil() {
|
||||
return "nil"
|
||||
}
|
||||
pv := reflect.Indirect(rv).Interface()
|
||||
return fmt.Sprintf("*%v", pv)
|
||||
}
|
||||
func (m *ReplicaSet) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: ReplicaSet: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: ReplicaSet: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *ReplicaSetSpec) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: ReplicaSetSpec: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: ReplicaSetSpec: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Replicas", wireType)
|
||||
}
|
||||
var v int32
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= (int32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.Replicas = &v
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *ReplicaSetStatus) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: ReplicaSetStatus: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: ReplicaSetStatus: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Replicas", wireType)
|
||||
}
|
||||
m.Replicas = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.Replicas |= (int32(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipGenerated(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if dAtA[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
return iNdEx, nil
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
iNdEx += length
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthGenerated
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 3:
|
||||
for {
|
||||
var innerWire uint64
|
||||
var start int = iNdEx
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
innerWire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
innerWireType := int(innerWire & 0x7)
|
||||
if innerWireType == 4 {
|
||||
break
|
||||
}
|
||||
next, err := skipGenerated(dAtA[start:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
iNdEx = start + next
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 4:
|
||||
return iNdEx, nil
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
return iNdEx, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow")
|
||||
)
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/apis/example2/v1/generated.proto", fileDescriptorGenerated)
|
||||
}
|
||||
|
||||
var fileDescriptorGenerated = []byte{
|
||||
// 421 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x91, 0xcf, 0x8e, 0xd3, 0x30,
|
||||
0x10, 0x87, 0x93, 0xb2, 0xac, 0x2a, 0xb3, 0x5a, 0xad, 0x72, 0xaa, 0x7a, 0x70, 0x51, 0x24, 0xa4,
|
||||
0x1e, 0xc0, 0x26, 0xcb, 0x5f, 0x71, 0x42, 0xb9, 0x03, 0x52, 0xf6, 0x80, 0xc4, 0x05, 0x1c, 0x77,
|
||||
0x48, 0x4d, 0x9a, 0xd8, 0xb2, 0x9d, 0x08, 0x6e, 0x3c, 0x02, 0x8f, 0xc1, 0xa3, 0xf4, 0xb8, 0xc7,
|
||||
0x3d, 0x55, 0x34, 0xbc, 0x08, 0xaa, 0x13, 0x12, 0xb1, 0xed, 0x0a, 0xb8, 0xe5, 0x67, 0xcf, 0xf7,
|
||||
0xcd, 0x64, 0x8c, 0x5e, 0xe7, 0xcf, 0x0d, 0x11, 0x92, 0xe6, 0x55, 0x0a, 0xba, 0x04, 0x0b, 0x86,
|
||||
0xd6, 0x50, 0x2e, 0xa4, 0xa6, 0xdd, 0x05, 0x53, 0xc2, 0x80, 0xae, 0x41, 0x53, 0x95, 0x67, 0x2e,
|
||||
0x51, 0xf8, 0xcc, 0x0a, 0xb5, 0x82, 0x73, 0x5a, 0x47, 0x34, 0x83, 0x12, 0x34, 0xb3, 0xb0, 0x20,
|
||||
0x4a, 0x4b, 0x2b, 0x83, 0x7b, 0x2d, 0x46, 0x7a, 0x8c, 0xa8, 0x3c, 0x73, 0x89, 0xfc, 0xc6, 0x48,
|
||||
0x1d, 0x4d, 0x1f, 0x64, 0xc2, 0x2e, 0xab, 0x94, 0x70, 0x59, 0xd0, 0x4c, 0x66, 0x92, 0x3a, 0x3a,
|
||||
0xad, 0x3e, 0xba, 0xe4, 0x82, 0xfb, 0x6a, 0xad, 0xd3, 0x70, 0x18, 0x86, 0x72, 0xa9, 0xe1, 0x40,
|
||||
0xe7, 0xe9, 0xe3, 0xa1, 0xa6, 0x60, 0x7c, 0x29, 0x4a, 0xd0, 0x5f, 0x86, 0x99, 0x0b, 0xb0, 0xec,
|
||||
0x10, 0x45, 0x6f, 0xa2, 0x74, 0x55, 0x5a, 0x51, 0xc0, 0x1e, 0xf0, 0xf4, 0x6f, 0x80, 0xe1, 0x4b,
|
||||
0x28, 0xd8, 0x1e, 0xf7, 0xe8, 0x26, 0xae, 0xb2, 0x62, 0x45, 0x45, 0x69, 0x8d, 0xd5, 0xd7, 0xa1,
|
||||
0xf0, 0xfb, 0x08, 0xa1, 0x04, 0xd4, 0x4a, 0x70, 0x76, 0x01, 0x36, 0xf8, 0x80, 0xc6, 0xbb, 0xff,
|
||||
0x58, 0x30, 0xcb, 0x26, 0xfe, 0x5d, 0x7f, 0x7e, 0xe7, 0xfc, 0x21, 0x19, 0xf6, 0xdd, 0x6b, 0x87,
|
||||
0x95, 0xef, 0xaa, 0x49, 0x1d, 0x91, 0x37, 0xe9, 0x27, 0xe0, 0xf6, 0x15, 0x58, 0x16, 0x07, 0xeb,
|
||||
0xcd, 0xcc, 0x6b, 0x36, 0x33, 0x34, 0x9c, 0x25, 0xbd, 0x35, 0x78, 0x8b, 0x8e, 0x8c, 0x02, 0x3e,
|
||||
0x19, 0x39, 0xfb, 0x13, 0xf2, 0x4f, 0xaf, 0x49, 0x86, 0x11, 0x2f, 0x14, 0xf0, 0xf8, 0xa4, 0x6b,
|
||||
0x71, 0xb4, 0x4b, 0x89, 0x13, 0x06, 0xef, 0xd1, 0xb1, 0xb1, 0xcc, 0x56, 0x66, 0x72, 0xcb, 0xa9,
|
||||
0x9f, 0xfd, 0xbf, 0xda, 0xe1, 0xf1, 0x69, 0x27, 0x3f, 0x6e, 0x73, 0xd2, 0x69, 0xc3, 0x17, 0xe8,
|
||||
0xf4, 0xcf, 0x31, 0x82, 0x39, 0x1a, 0xeb, 0xf6, 0xc4, 0xb8, 0x6d, 0xdd, 0x8e, 0x4f, 0x9a, 0xcd,
|
||||
0x6c, 0xdc, 0x55, 0x99, 0xa4, 0xbf, 0x0d, 0x5f, 0xa2, 0xb3, 0xeb, 0x7d, 0x82, 0xfb, 0x7b, 0xf4,
|
||||
0x59, 0xd7, 0xf9, 0x80, 0x21, 0x9e, 0xaf, 0xb7, 0xd8, 0xbb, 0xdc, 0x62, 0xef, 0x6a, 0x8b, 0xbd,
|
||||
0xaf, 0x0d, 0xf6, 0xd7, 0x0d, 0xf6, 0x2f, 0x1b, 0xec, 0x5f, 0x35, 0xd8, 0xff, 0xd1, 0x60, 0xff,
|
||||
0xdb, 0x4f, 0xec, 0xbd, 0x1b, 0xd5, 0xd1, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x69, 0x4a, 0x84,
|
||||
0xe4, 0x71, 0x03, 0x00, 0x00,
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
// This file was autogenerated by go-to-protobuf. Do not edit it manually!
|
||||
|
||||
syntax = 'proto2';
|
||||
|
||||
package k8s.io.apiserver.pkg.apis.example2.v1;
|
||||
|
||||
import "k8s.io/api/core/v1/generated.proto";
|
||||
import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto";
|
||||
import "k8s.io/apimachinery/pkg/runtime/generated.proto";
|
||||
import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto";
|
||||
import "k8s.io/apimachinery/pkg/util/intstr/generated.proto";
|
||||
|
||||
// Package-wide variables from generator "generated".
|
||||
option go_package = "v1";
|
||||
|
||||
// ReplicaSet ensures that a specified number of pod replicas are running at any given time.
|
||||
message ReplicaSet {
|
||||
// If the Labels of a ReplicaSet are empty, they are defaulted to
|
||||
// be the same as the Pod(s) that the ReplicaSet manages.
|
||||
// Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
|
||||
// +optional
|
||||
optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
|
||||
|
||||
// Spec defines the specification of the desired behavior of the ReplicaSet.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
|
||||
// +optional
|
||||
optional ReplicaSetSpec spec = 2;
|
||||
|
||||
// Status is the most recently observed status of the ReplicaSet.
|
||||
// This data may be out of date by some window of time.
|
||||
// Populated by the system.
|
||||
// Read-only.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
|
||||
// +optional
|
||||
optional ReplicaSetStatus status = 3;
|
||||
}
|
||||
|
||||
// ReplicaSetSpec is the specification of a ReplicaSet.
|
||||
message ReplicaSetSpec {
|
||||
// Replicas is the number of desired replicas.
|
||||
// This is a pointer to distinguish between explicit zero and unspecified.
|
||||
// Defaults to 1.
|
||||
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller
|
||||
// +optional
|
||||
optional int32 replicas = 1;
|
||||
}
|
||||
|
||||
// ReplicaSetStatus represents the current status of a ReplicaSet.
|
||||
message ReplicaSetStatus {
|
||||
// Replicas is the most recently oberved number of replicas.
|
||||
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller
|
||||
optional int32 replicas = 1;
|
||||
}
|
||||
|
|
@ -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 (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName is the group name use in this package
|
||||
const GroupName = "example2.apiserver.k8s.io"
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"}
|
||||
|
||||
// Kind takes an unqualified kind and returns a Group qualified GroupKind
|
||||
func Kind(kind string) schema.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.
|
||||
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
|
||||
SchemeBuilder runtime.SchemeBuilder
|
||||
localSchemeBuilder = &SchemeBuilder
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addKnownTypes, addConversionFuncs, addDefaultingFuncs)
|
||||
}
|
||||
|
||||
// Adds the list of known types to the given scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&ReplicaSet{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
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:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ReplicaSet ensures that a specified number of pod replicas are running at any given time.
|
||||
type ReplicaSet struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// If the Labels of a ReplicaSet are empty, they are defaulted to
|
||||
// be the same as the Pod(s) that the ReplicaSet manages.
|
||||
// Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
|
||||
// Spec defines the specification of the desired behavior of the ReplicaSet.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
|
||||
// +optional
|
||||
Spec ReplicaSetSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
|
||||
|
||||
// Status is the most recently observed status of the ReplicaSet.
|
||||
// This data may be out of date by some window of time.
|
||||
// Populated by the system.
|
||||
// Read-only.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
|
||||
// +optional
|
||||
Status ReplicaSetStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
|
||||
}
|
||||
|
||||
// ReplicaSetSpec is the specification of a ReplicaSet.
|
||||
type ReplicaSetSpec struct {
|
||||
// Replicas is the number of desired replicas.
|
||||
// This is a pointer to distinguish between explicit zero and unspecified.
|
||||
// Defaults to 1.
|
||||
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller
|
||||
// +optional
|
||||
Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"`
|
||||
}
|
||||
|
||||
// ReplicaSetStatus represents the current status of a ReplicaSet.
|
||||
type ReplicaSetStatus struct {
|
||||
// Replicas is the most recently oberved number of replicas.
|
||||
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller
|
||||
Replicas int32 `json:"replicas" protobuf:"varint,1,opt,name=replicas"`
|
||||
}
|
17
staging/src/k8s.io/apiserver/pkg/apis/example2/v1/types_swagger_doc_generated.go
generated
Normal file
17
staging/src/k8s.io/apiserver/pkg/apis/example2/v1/types_swagger_doc_generated.go
generated
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
Copyright 2016 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
|
111
staging/src/k8s.io/apiserver/pkg/apis/example2/v1/zz_generated.conversion.go
generated
Normal file
111
staging/src/k8s.io/apiserver/pkg/apis/example2/v1/zz_generated.conversion.go
generated
Normal file
|
@ -0,0 +1,111 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by conversion-gen. Do not edit it manually!
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
example "k8s.io/apiserver/pkg/apis/example"
|
||||
)
|
||||
|
||||
func init() {
|
||||
localSchemeBuilder.Register(RegisterConversions)
|
||||
}
|
||||
|
||||
// RegisterConversions adds conversion functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterConversions(scheme *runtime.Scheme) error {
|
||||
return scheme.AddGeneratedConversionFuncs(
|
||||
Convert_v1_ReplicaSet_To_example_ReplicaSet,
|
||||
Convert_example_ReplicaSet_To_v1_ReplicaSet,
|
||||
Convert_v1_ReplicaSetSpec_To_example_ReplicaSetSpec,
|
||||
Convert_example_ReplicaSetSpec_To_v1_ReplicaSetSpec,
|
||||
Convert_v1_ReplicaSetStatus_To_example_ReplicaSetStatus,
|
||||
Convert_example_ReplicaSetStatus_To_v1_ReplicaSetStatus,
|
||||
)
|
||||
}
|
||||
|
||||
func autoConvert_v1_ReplicaSet_To_example_ReplicaSet(in *ReplicaSet, out *example.ReplicaSet, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_v1_ReplicaSetSpec_To_example_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_v1_ReplicaSetStatus_To_example_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_ReplicaSet_To_example_ReplicaSet is an autogenerated conversion function.
|
||||
func Convert_v1_ReplicaSet_To_example_ReplicaSet(in *ReplicaSet, out *example.ReplicaSet, s conversion.Scope) error {
|
||||
return autoConvert_v1_ReplicaSet_To_example_ReplicaSet(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_example_ReplicaSet_To_v1_ReplicaSet(in *example.ReplicaSet, out *ReplicaSet, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_example_ReplicaSetSpec_To_v1_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_example_ReplicaSetStatus_To_v1_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_example_ReplicaSet_To_v1_ReplicaSet is an autogenerated conversion function.
|
||||
func Convert_example_ReplicaSet_To_v1_ReplicaSet(in *example.ReplicaSet, out *ReplicaSet, s conversion.Scope) error {
|
||||
return autoConvert_example_ReplicaSet_To_v1_ReplicaSet(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_ReplicaSetSpec_To_example_ReplicaSetSpec(in *ReplicaSetSpec, out *example.ReplicaSetSpec, s conversion.Scope) error {
|
||||
if err := meta_v1.Convert_Pointer_int32_To_int32(&in.Replicas, &out.Replicas, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_example_ReplicaSetSpec_To_v1_ReplicaSetSpec(in *example.ReplicaSetSpec, out *ReplicaSetSpec, s conversion.Scope) error {
|
||||
if err := meta_v1.Convert_int32_To_Pointer_int32(&in.Replicas, &out.Replicas, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_v1_ReplicaSetStatus_To_example_ReplicaSetStatus(in *ReplicaSetStatus, out *example.ReplicaSetStatus, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_ReplicaSetStatus_To_example_ReplicaSetStatus is an autogenerated conversion function.
|
||||
func Convert_v1_ReplicaSetStatus_To_example_ReplicaSetStatus(in *ReplicaSetStatus, out *example.ReplicaSetStatus, s conversion.Scope) error {
|
||||
return autoConvert_v1_ReplicaSetStatus_To_example_ReplicaSetStatus(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_example_ReplicaSetStatus_To_v1_ReplicaSetStatus(in *example.ReplicaSetStatus, out *ReplicaSetStatus, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_example_ReplicaSetStatus_To_v1_ReplicaSetStatus is an autogenerated conversion function.
|
||||
func Convert_example_ReplicaSetStatus_To_v1_ReplicaSetStatus(in *example.ReplicaSetStatus, out *ReplicaSetStatus, s conversion.Scope) error {
|
||||
return autoConvert_example_ReplicaSetStatus_To_v1_ReplicaSetStatus(in, out, s)
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ReplicaSet) DeepCopyInto(out *ReplicaSet) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
out.Status = in.Status
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicaSet.
|
||||
func (in *ReplicaSet) DeepCopy() *ReplicaSet {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ReplicaSet)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ReplicaSet) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ReplicaSetSpec) DeepCopyInto(out *ReplicaSetSpec) {
|
||||
*out = *in
|
||||
if in.Replicas != nil {
|
||||
in, out := &in.Replicas, &out.Replicas
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicaSetSpec.
|
||||
func (in *ReplicaSetSpec) DeepCopy() *ReplicaSetSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ReplicaSetSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ReplicaSetStatus) DeepCopyInto(out *ReplicaSetStatus) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReplicaSetStatus.
|
||||
func (in *ReplicaSetStatus) DeepCopy() *ReplicaSetStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ReplicaSetStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by defaulter-gen. Do not edit it manually!
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// RegisterDefaults adds defaulters functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
// All generated defaulters are covering - they call all nested defaulters.
|
||||
func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
|
||||
|
||||
package example2
|
|
@ -60,6 +60,7 @@ go_library(
|
|||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/storage/names:go_default_library",
|
||||
"//vendor/k8s.io/client-go/discovery:go_default_library",
|
||||
"//vendor/k8s.io/client-go/dynamic:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/cert:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/retry:go_default_library",
|
||||
|
|
|
@ -24,10 +24,15 @@ import (
|
|||
"k8s.io/api/core/v1"
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
rbacv1beta1 "k8s.io/api/rbac/v1beta1"
|
||||
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
crdclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
"k8s.io/apiextensions-apiserver/test/integration/testserver"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/dynamic"
|
||||
utilversion "k8s.io/kubernetes/pkg/util/version"
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
|
||||
|
@ -47,6 +52,11 @@ const (
|
|||
skippedNamespaceName = "exempted-namesapce"
|
||||
disallowedPodName = "disallowed-pod"
|
||||
disallowedConfigMapName = "disallowed-configmap"
|
||||
crdName = "e2e-test-webhook-crd"
|
||||
crdKind = "E2e-test-webhook-crd"
|
||||
crdWebhookConfigName = "e2e-test-webhook-config-crd"
|
||||
crdAPIGroup = "webhook-crd-test.k8s.io"
|
||||
crdAPIVersion = "v1"
|
||||
)
|
||||
|
||||
var serverWebhookVersion = utilversion.MustParseSemantic("v1.8.0")
|
||||
|
@ -60,7 +70,7 @@ var _ = SIGDescribe("AdmissionWebhook", func() {
|
|||
It("Should be able to deny pod and configmap creation", func() {
|
||||
// Make sure the relevant provider supports admission webhook
|
||||
framework.SkipUnlessServerVersionGTE(serverWebhookVersion, f.ClientSet.Discovery())
|
||||
framework.SkipUnlessProviderIs("gce", "gke")
|
||||
framework.SkipUnlessProviderIs("gce", "gke", "local")
|
||||
|
||||
_, err := f.ClientSet.AdmissionregistrationV1alpha1().ValidatingWebhookConfigurations().List(metav1.ListOptions{})
|
||||
if errors.IsNotFound(err) {
|
||||
|
@ -74,10 +84,29 @@ var _ = SIGDescribe("AdmissionWebhook", func() {
|
|||
// Note that in 1.9 we will have backwards incompatible change to
|
||||
// admission webhooks, so the image will be updated to 1.9 sometime in
|
||||
// the development 1.9 cycle.
|
||||
deployWebhookAndService(f, "gcr.io/kubernetes-e2e-test-images/k8s-sample-admission-webhook-amd64:1.8v2", context)
|
||||
deployWebhookAndService(f, "gcr.io/kubernetes-e2e-test-images/k8s-sample-admission-webhook-amd64:1.8v3", context)
|
||||
registerWebhook(f, context)
|
||||
testWebhook(f)
|
||||
})
|
||||
|
||||
It("Should be able to deny custom resource creation", func() {
|
||||
// Make sure the relevant provider supports admission webhook
|
||||
framework.SkipUnlessServerVersionGTE(serverWebhookVersion, f.ClientSet.Discovery())
|
||||
framework.SkipUnlessProviderIs("gce", "gke", "local")
|
||||
_, err := f.ClientSet.AdmissionregistrationV1alpha1().ValidatingWebhookConfigurations().List(metav1.ListOptions{})
|
||||
if errors.IsNotFound(err) {
|
||||
framework.Skipf("dynamic configuration of webhooks requires the alpha admissionregistration.k8s.io group to be enabled")
|
||||
}
|
||||
By("Setting up server cert")
|
||||
namespaceName := f.Namespace.Name
|
||||
context := setupServerCert(namespaceName, serviceName)
|
||||
createAuthReaderRoleBinding(f, namespaceName)
|
||||
deployWebhookAndService(f, "gcr.io/kubernetes-e2e-test-images/k8s-sample-admission-webhook-amd64:1.8v3", context)
|
||||
crdCleanup, dynamicClient := createCRD(f)
|
||||
defer crdCleanup()
|
||||
registerWebhookForCRD(f, context)
|
||||
testCRDWebhook(f, dynamicClient)
|
||||
})
|
||||
})
|
||||
|
||||
func createAuthReaderRoleBinding(f *framework.Framework, namespace string) {
|
||||
|
@ -105,12 +134,15 @@ func createAuthReaderRoleBinding(f *framework.Framework, namespace string) {
|
|||
},
|
||||
},
|
||||
})
|
||||
framework.ExpectNoError(err, "creating role binding %s:webhook to access configMap", namespace)
|
||||
if err != nil && errors.IsAlreadyExists(err) {
|
||||
framework.Logf("role binding %s already exists", roleBindingName)
|
||||
} else {
|
||||
framework.ExpectNoError(err, "creating role binding %s:webhook to access configMap", namespace)
|
||||
}
|
||||
}
|
||||
|
||||
func deployWebhookAndService(f *framework.Framework, image string, context *certContext) {
|
||||
By("Deploying the webhook pod")
|
||||
|
||||
client := f.ClientSet
|
||||
|
||||
// Creating the secret that contains the webhook's cert.
|
||||
|
@ -283,7 +315,7 @@ func registerWebhook(f *framework.Framework, context *certContext) {
|
|||
framework.ExpectNoError(err, "registering webhook config %s with namespace %s", webhookConfigName, namespace)
|
||||
|
||||
// The webhook configuration is honored in 1s.
|
||||
time.Sleep(2 * time.Second)
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
||||
|
||||
func testWebhook(f *framework.Framework) {
|
||||
|
@ -293,20 +325,21 @@ func testWebhook(f *framework.Framework) {
|
|||
pod := nonCompliantPod(f)
|
||||
_, err := client.CoreV1().Pods(f.Namespace.Name).Create(pod)
|
||||
Expect(err).NotTo(BeNil())
|
||||
expectedErrMsg := "the pod contains unwanted container name"
|
||||
if !strings.Contains(err.Error(), expectedErrMsg) {
|
||||
framework.Failf("expect error contains %q, got %q", expectedErrMsg, err.Error())
|
||||
expectedErrMsg1 := "the pod contains unwanted container name"
|
||||
if !strings.Contains(err.Error(), expectedErrMsg1) {
|
||||
framework.Failf("expect error contains %q, got %q", expectedErrMsg1, err.Error())
|
||||
}
|
||||
expectedErrMsg2 := "the pod contains unwanted label"
|
||||
if !strings.Contains(err.Error(), expectedErrMsg2) {
|
||||
framework.Failf("expect error contains %q, got %q", expectedErrMsg2, err.Error())
|
||||
}
|
||||
// TODO: Test if webhook can detect pod with non-compliant metadata.
|
||||
// Currently metadata is lost because webhook uses the external version of
|
||||
// the objects, and the apiserver sends the internal objects.
|
||||
|
||||
By("create a configmap that should be denied by the webhook")
|
||||
// Creating the configmap, the request should be rejected
|
||||
configmap := nonCompliantConfigMap(f)
|
||||
_, err = client.CoreV1().ConfigMaps(f.Namespace.Name).Create(configmap)
|
||||
Expect(err).NotTo(BeNil())
|
||||
expectedErrMsg = "the configmap contains unwanted key and value"
|
||||
expectedErrMsg := "the configmap contains unwanted key and value"
|
||||
if !strings.Contains(err.Error(), expectedErrMsg) {
|
||||
framework.Failf("expect error contains %q, got %q", expectedErrMsg, err.Error())
|
||||
}
|
||||
|
@ -340,7 +373,7 @@ func nonCompliantPod(f *framework.Framework) *v1.Pod {
|
|||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: disallowedPodName,
|
||||
Labels: map[string]string{
|
||||
"webhook-e2e-test": "disallow",
|
||||
"webhook-e2e-test": "webhook-disallow",
|
||||
},
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
|
@ -368,6 +401,7 @@ func nonCompliantConfigMap(f *framework.Framework) *v1.ConfigMap {
|
|||
func cleanWebhookTest(f *framework.Framework) {
|
||||
client := f.ClientSet
|
||||
_ = client.AdmissionregistrationV1alpha1().ValidatingWebhookConfigurations().Delete(webhookConfigName, nil)
|
||||
_ = client.AdmissionregistrationV1alpha1().ValidatingWebhookConfigurations().Delete(crdWebhookConfigName, nil)
|
||||
namespaceName := f.Namespace.Name
|
||||
_ = client.CoreV1().Services(namespaceName).Delete(serviceName, nil)
|
||||
_ = client.ExtensionsV1beta1().Deployments(namespaceName).Delete(deploymentName, nil)
|
||||
|
@ -376,3 +410,114 @@ func cleanWebhookTest(f *framework.Framework) {
|
|||
_ = client.CoreV1().ConfigMaps(skippedNamespaceName).Delete(disallowedConfigMapName, nil)
|
||||
_ = client.CoreV1().Namespaces().Delete(skippedNamespaceName, nil)
|
||||
}
|
||||
|
||||
// newCRDForAdmissionWebhookTest generates a CRD
|
||||
func newCRDForAdmissionWebhookTest() *apiextensionsv1beta1.CustomResourceDefinition {
|
||||
return &apiextensionsv1beta1.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: crdName + "s." + crdAPIGroup},
|
||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
||||
Group: crdAPIGroup,
|
||||
Version: crdAPIVersion,
|
||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
||||
Plural: crdName + "s",
|
||||
Singular: crdName,
|
||||
Kind: crdKind,
|
||||
ListKind: crdName + "List",
|
||||
},
|
||||
Scope: apiextensionsv1beta1.NamespaceScoped,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func createCRD(f *framework.Framework) (func(), dynamic.ResourceInterface) {
|
||||
config, err := framework.LoadConfig()
|
||||
if err != nil {
|
||||
framework.Failf("failed to load config: %v", err)
|
||||
}
|
||||
|
||||
apiExtensionClient, err := crdclientset.NewForConfig(config)
|
||||
if err != nil {
|
||||
framework.Failf("failed to initialize apiExtensionClient: %v", err)
|
||||
}
|
||||
|
||||
crd := newCRDForAdmissionWebhookTest()
|
||||
|
||||
//create CRD and waits for the resource to be recognized and available.
|
||||
dynamicClient, err := testserver.CreateNewCustomResourceDefinitionWatchUnsafe(crd, apiExtensionClient, f.ClientPool)
|
||||
if err != nil {
|
||||
framework.Failf("failed to create CustomResourceDefinition: %v", err)
|
||||
}
|
||||
|
||||
resourceClient := dynamicClient.Resource(&metav1.APIResource{
|
||||
Name: crd.Spec.Names.Plural,
|
||||
Namespaced: true,
|
||||
}, f.Namespace.Name)
|
||||
|
||||
return func() {
|
||||
err = testserver.DeleteCustomResourceDefinition(crd, apiExtensionClient)
|
||||
if err != nil {
|
||||
framework.Failf("failed to delete CustomResourceDefinition: %v", err)
|
||||
}
|
||||
}, resourceClient
|
||||
}
|
||||
|
||||
func registerWebhookForCRD(f *framework.Framework, context *certContext) {
|
||||
client := f.ClientSet
|
||||
By("Registering the crd webhook via the AdmissionRegistration API")
|
||||
|
||||
namespace := f.Namespace.Name
|
||||
_, err := client.AdmissionregistrationV1alpha1().ValidatingWebhookConfigurations().Create(&v1alpha1.ValidatingWebhookConfiguration{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: crdWebhookConfigName,
|
||||
},
|
||||
Webhooks: []v1alpha1.Webhook{
|
||||
{
|
||||
Name: "deny-unwanted-crd-data.k8s.io",
|
||||
Rules: []v1alpha1.RuleWithOperations{{
|
||||
Operations: []v1alpha1.OperationType{v1alpha1.Create},
|
||||
Rule: v1alpha1.Rule{
|
||||
APIGroups: []string{crdAPIGroup},
|
||||
APIVersions: []string{crdAPIVersion},
|
||||
Resources: []string{crdName + "s"},
|
||||
},
|
||||
}},
|
||||
ClientConfig: v1alpha1.WebhookClientConfig{
|
||||
Service: &v1alpha1.ServiceReference{
|
||||
Namespace: namespace,
|
||||
Name: serviceName,
|
||||
Path: strPtr("/crd"),
|
||||
},
|
||||
CABundle: context.signingCert,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
framework.ExpectNoError(err, "registering crd webhook config %s with namespace %s", webhookConfigName, namespace)
|
||||
|
||||
// The webhook configuration is honored in 1s.
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
||||
|
||||
func testCRDWebhook(f *framework.Framework, crdClient dynamic.ResourceInterface) {
|
||||
By("Creating a custom resource that should be denied by the webhook")
|
||||
crd := newCRDForAdmissionWebhookTest()
|
||||
crInstance := &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"kind": crd.Spec.Names.Kind,
|
||||
"apiVersion": crd.Spec.Group + "/" + crd.Spec.Version,
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "cr-instance-1",
|
||||
"namespace": f.Namespace.Name,
|
||||
},
|
||||
"data": map[string]interface{}{
|
||||
"webhook-e2e-test": "webhook-disallow",
|
||||
},
|
||||
},
|
||||
}
|
||||
_, err := crdClient.Create(crInstance)
|
||||
Expect(err).NotTo(BeNil())
|
||||
expectedErrMsg := "the custom resource contains unwanted data"
|
||||
if !strings.Contains(err.Error(), expectedErrMsg) {
|
||||
framework.Failf("expect error contains %q, got %q", expectedErrMsg, err.Error())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,14 +5,18 @@ go_library(
|
|||
srcs = [
|
||||
"config.go",
|
||||
"main.go",
|
||||
"scheme.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/test/images/webhook",
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/api/admission/v1alpha1:go_default_library",
|
||||
"//vendor/k8s.io/api/admissionregistration/v1alpha1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1: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/client-go/kubernetes:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
],
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
build:
|
||||
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o webhook .
|
||||
docker build --no-cache -t gcr.io/kubernetes-e2e-test-images/k8s-sample-admission-webhook-amd64:1.8v2 .
|
||||
docker build --no-cache -t gcr.io/kubernetes-e2e-test-images/k8s-sample-admission-webhook-amd64:1.8v3 .
|
||||
rm -rf webhook
|
||||
push:
|
||||
gcloud docker -- push gcr.io/kubernetes-e2e-test-images/k8s-sample-admission-webhook-amd64:1.8v2
|
||||
gcloud docker -- push gcr.io/kubernetes-e2e-test-images/k8s-sample-admission-webhook-amd64:1.8v3
|
||||
|
|
|
@ -19,13 +19,14 @@ package main
|
|||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/admission/v1alpha1"
|
||||
"k8s.io/api/core/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
|
@ -43,58 +44,56 @@ func (c *Config) addFlags() {
|
|||
"File containing the default x509 private key matching --tls-cert-file.")
|
||||
}
|
||||
|
||||
// only allow pods to pull images from specific registry.
|
||||
func admitPods(data []byte) *v1alpha1.AdmissionReviewStatus {
|
||||
glog.V(2).Info("admitting pods")
|
||||
ar := v1alpha1.AdmissionReview{}
|
||||
if err := json.Unmarshal(data, &ar); err != nil {
|
||||
glog.Error(err)
|
||||
return nil
|
||||
func toAdmissionReviewStatus(err error) *v1alpha1.AdmissionReviewStatus {
|
||||
return &v1alpha1.AdmissionReviewStatus{
|
||||
Result: &metav1.Status{
|
||||
Message: err.Error(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// only allow pods to pull images from specific registry.
|
||||
func admitPods(ar v1alpha1.AdmissionReview) *v1alpha1.AdmissionReviewStatus {
|
||||
glog.V(2).Info("admitting pods")
|
||||
podResource := metav1.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"}
|
||||
if ar.Spec.Resource != podResource {
|
||||
glog.Errorf("expect resource to be %s", podResource)
|
||||
return nil
|
||||
err := fmt.Errorf("expect resource to be %s", podResource)
|
||||
glog.Error(err)
|
||||
return toAdmissionReviewStatus(err)
|
||||
}
|
||||
|
||||
raw := ar.Spec.Object.Raw
|
||||
pod := v1.Pod{}
|
||||
if err := json.Unmarshal(raw, &pod); err != nil {
|
||||
pod := corev1.Pod{}
|
||||
deserializer := codecs.UniversalDeserializer()
|
||||
if _, _, err := deserializer.Decode(raw, nil, &pod); err != nil {
|
||||
glog.Error(err)
|
||||
return nil
|
||||
return toAdmissionReviewStatus(err)
|
||||
}
|
||||
reviewStatus := v1alpha1.AdmissionReviewStatus{}
|
||||
reviewStatus.Allowed = true
|
||||
// Note: the apiserver encodes the api.Pod. Decoding it as a v1.Pod will
|
||||
// lose the metadata. So the following check on labels will not work
|
||||
// until we let the apiserver encodes the versioned object.
|
||||
|
||||
var msg string
|
||||
for k, v := range pod.Labels {
|
||||
if k == "webhook-e2e-test" && v == "webhook-disallow" {
|
||||
reviewStatus.Allowed = false
|
||||
reviewStatus.Result = &metav1.Status{
|
||||
Reason: "the pod contains unwanted label",
|
||||
}
|
||||
msg = msg + "the pod contains unwanted label; "
|
||||
}
|
||||
}
|
||||
for _, container := range pod.Spec.Containers {
|
||||
if strings.Contains(container.Name, "webhook-disallow") {
|
||||
reviewStatus.Allowed = false
|
||||
reviewStatus.Result = &metav1.Status{
|
||||
Message: "the pod contains unwanted container name",
|
||||
}
|
||||
msg = msg + "the pod contains unwanted container name; "
|
||||
}
|
||||
}
|
||||
if !reviewStatus.Allowed {
|
||||
reviewStatus.Result = &metav1.Status{Message: strings.TrimSpace(msg)}
|
||||
}
|
||||
return &reviewStatus
|
||||
}
|
||||
|
||||
// deny configmaps with specific key-value pair.
|
||||
func admitConfigMaps(data []byte) *v1alpha1.AdmissionReviewStatus {
|
||||
func admitConfigMaps(ar v1alpha1.AdmissionReview) *v1alpha1.AdmissionReviewStatus {
|
||||
glog.V(2).Info("admitting configmaps")
|
||||
ar := v1alpha1.AdmissionReview{}
|
||||
if err := json.Unmarshal(data, &ar); err != nil {
|
||||
glog.Error(err)
|
||||
return nil
|
||||
}
|
||||
configMapResource := metav1.GroupVersionResource{Group: "", Version: "v1", Resource: "configmaps"}
|
||||
if ar.Spec.Resource != configMapResource {
|
||||
glog.Errorf("expect resource to be %s", configMapResource)
|
||||
|
@ -102,10 +101,11 @@ func admitConfigMaps(data []byte) *v1alpha1.AdmissionReviewStatus {
|
|||
}
|
||||
|
||||
raw := ar.Spec.Object.Raw
|
||||
configmap := v1.ConfigMap{}
|
||||
if err := json.Unmarshal(raw, &configmap); err != nil {
|
||||
configmap := corev1.ConfigMap{}
|
||||
deserializer := codecs.UniversalDeserializer()
|
||||
if _, _, err := deserializer.Decode(raw, nil, &configmap); err != nil {
|
||||
glog.Error(err)
|
||||
return nil
|
||||
return toAdmissionReviewStatus(err)
|
||||
}
|
||||
reviewStatus := v1alpha1.AdmissionReviewStatus{}
|
||||
reviewStatus.Allowed = true
|
||||
|
@ -120,7 +120,34 @@ func admitConfigMaps(data []byte) *v1alpha1.AdmissionReviewStatus {
|
|||
return &reviewStatus
|
||||
}
|
||||
|
||||
type admitFunc func(data []byte) *v1alpha1.AdmissionReviewStatus
|
||||
func admitCRD(ar v1alpha1.AdmissionReview) *v1alpha1.AdmissionReviewStatus {
|
||||
glog.V(2).Info("admitting crd")
|
||||
cr := struct {
|
||||
metav1.ObjectMeta
|
||||
Data map[string]string
|
||||
}{}
|
||||
|
||||
raw := ar.Spec.Object.Raw
|
||||
err := json.Unmarshal(raw, &cr)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return toAdmissionReviewStatus(err)
|
||||
}
|
||||
|
||||
reviewStatus := v1alpha1.AdmissionReviewStatus{}
|
||||
reviewStatus.Allowed = true
|
||||
for k, v := range cr.Data {
|
||||
if k == "webhook-e2e-test" && v == "webhook-disallow" {
|
||||
reviewStatus.Allowed = false
|
||||
reviewStatus.Result = &metav1.Status{
|
||||
Reason: "the custom resource contains unwanted data",
|
||||
}
|
||||
}
|
||||
}
|
||||
return &reviewStatus
|
||||
}
|
||||
|
||||
type admitFunc func(v1alpha1.AdmissionReview) *v1alpha1.AdmissionReviewStatus
|
||||
|
||||
func serve(w http.ResponseWriter, r *http.Request, admit admitFunc) {
|
||||
var body []byte
|
||||
|
@ -137,9 +164,16 @@ func serve(w http.ResponseWriter, r *http.Request, admit admitFunc) {
|
|||
return
|
||||
}
|
||||
|
||||
reviewStatus := admit(body)
|
||||
|
||||
var reviewStatus *v1alpha1.AdmissionReviewStatus
|
||||
ar := v1alpha1.AdmissionReview{}
|
||||
deserializer := codecs.UniversalDeserializer()
|
||||
if _, _, err := deserializer.Decode(body, nil, &ar); err != nil {
|
||||
glog.Error(err)
|
||||
reviewStatus = toAdmissionReviewStatus(err)
|
||||
} else {
|
||||
reviewStatus = admit(ar)
|
||||
}
|
||||
|
||||
if reviewStatus != nil {
|
||||
ar.Status = *reviewStatus
|
||||
}
|
||||
|
@ -156,10 +190,15 @@ func serve(w http.ResponseWriter, r *http.Request, admit admitFunc) {
|
|||
func servePods(w http.ResponseWriter, r *http.Request) {
|
||||
serve(w, r, admitPods)
|
||||
}
|
||||
|
||||
func serveConfigmaps(w http.ResponseWriter, r *http.Request) {
|
||||
serve(w, r, admitConfigMaps)
|
||||
}
|
||||
|
||||
func serveCRD(w http.ResponseWriter, r *http.Request) {
|
||||
serve(w, r, admitCRD)
|
||||
}
|
||||
|
||||
func main() {
|
||||
var config Config
|
||||
config.addFlags()
|
||||
|
@ -167,6 +206,7 @@ func main() {
|
|||
|
||||
http.HandleFunc("/pods", servePods)
|
||||
http.HandleFunc("/configmaps", serveConfigmaps)
|
||||
http.HandleFunc("/crd", serveCRD)
|
||||
clientset := getClient()
|
||||
server := &http.Server{
|
||||
Addr: ":443",
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
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 main
|
||||
|
||||
import (
|
||||
admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
)
|
||||
|
||||
var scheme = runtime.NewScheme()
|
||||
var codecs = serializer.NewCodecFactory(scheme)
|
||||
|
||||
func init() {
|
||||
addToScheme(scheme)
|
||||
}
|
||||
|
||||
func addToScheme(scheme *runtime.Scheme) {
|
||||
corev1.AddToScheme(scheme)
|
||||
admissionregistrationv1alpha1.AddToScheme(scheme)
|
||||
}
|
Loading…
Reference in New Issue