Bumping k8s dependencies to 1.13
This commit is contained in:
984
vendor/k8s.io/apiextensions-apiserver/Godeps/Godeps.json
generated
vendored
984
vendor/k8s.io/apiextensions-apiserver/Godeps/Godeps.json
generated
vendored
File diff suppressed because it is too large
Load Diff
2
vendor/k8s.io/apiextensions-apiserver/examples/client-go/pkg/apis/cr/v1/doc.go
generated
vendored
2
vendor/k8s.io/apiextensions-apiserver/examples/client-go/pkg/apis/cr/v1/doc.go
generated
vendored
@@ -15,7 +15,7 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +groupName=cr.example.apiextensions.k8s.io
|
||||
|
||||
// Package v1 is the v1 version of the API.
|
||||
// +groupName=cr.example.apiextensions.k8s.io
|
||||
package v1
|
||||
|
@@ -119,7 +119,7 @@ func (c *FakeExamples) DeleteCollection(options *v1.DeleteOptions, listOptions v
|
||||
// Patch applies the patch and returns the patched example.
|
||||
func (c *FakeExamples) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *crv1.Example, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(examplesResource, c.ns, name, data, subresources...), &crv1.Example{})
|
||||
Invokes(testing.NewPatchSubresourceAction(examplesResource, c.ns, name, pt, data, subresources...), &crv1.Example{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
|
@@ -27,6 +27,7 @@ import (
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer.
|
||||
type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer
|
||||
|
||||
// SharedInformerFactory a small interface to allow for adding an informer without an import cycle
|
||||
@@ -35,4 +36,5 @@ type SharedInformerFactory interface {
|
||||
InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
|
||||
}
|
||||
|
||||
// TweakListOptionsFunc is a function that transforms a v1.ListOptions.
|
||||
type TweakListOptionsFunc func(*v1.ListOptions)
|
||||
|
9
vendor/k8s.io/apiextensions-apiserver/pkg/apis/OWNERS
generated
vendored
Normal file
9
vendor/k8s.io/apiextensions-apiserver/pkg/apis/OWNERS
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
# Disable inheritance as this is an api owners file
|
||||
options:
|
||||
no_parent_owners: true
|
||||
approvers:
|
||||
- api-approvers
|
||||
reviewers:
|
||||
- api-reviewers
|
||||
labels:
|
||||
- kind/api-change
|
2
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/doc.go
generated
vendored
2
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/doc.go
generated
vendored
@@ -15,7 +15,7 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +groupName=apiextensions.k8s.io
|
||||
|
||||
// Package apiextensions is the internal version of the API.
|
||||
// +groupName=apiextensions.k8s.io
|
||||
package apiextensions // import "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
|
5
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer/fuzzer.go
generated
vendored
5
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer/fuzzer.go
generated
vendored
@@ -61,6 +61,11 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
|
||||
{Name: "Age", Type: "date", Description: swaggerMetadataDescriptions["creationTimestamp"], JSONPath: ".metadata.creationTimestamp"},
|
||||
}
|
||||
}
|
||||
if obj.Conversion == nil {
|
||||
obj.Conversion = &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.NoneConverter,
|
||||
}
|
||||
}
|
||||
},
|
||||
func(obj *apiextensions.CustomResourceDefinition, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(obj)
|
||||
|
88
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types.go
generated
vendored
88
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types.go
generated
vendored
@@ -20,6 +20,16 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// ConversionStrategyType describes different conversion types.
|
||||
type ConversionStrategyType string
|
||||
|
||||
const (
|
||||
// NoneConverter is a converter that only sets apiversion of the CR and leave everything else unchanged.
|
||||
NoneConverter ConversionStrategyType = "None"
|
||||
// WebhookConverter is a converter that calls to an external webhook to convert the CR.
|
||||
WebhookConverter ConversionStrategyType = "Webhook"
|
||||
)
|
||||
|
||||
// CustomResourceDefinitionSpec describes how a user wants their resource to appear
|
||||
type CustomResourceDefinitionSpec struct {
|
||||
// Group is the group this resource belongs in
|
||||
@@ -51,8 +61,86 @@ type CustomResourceDefinitionSpec struct {
|
||||
Versions []CustomResourceDefinitionVersion
|
||||
// AdditionalPrinterColumns are additional columns shown e.g. in kubectl next to the name. Defaults to a created-at column.
|
||||
AdditionalPrinterColumns []CustomResourceColumnDefinition
|
||||
|
||||
// `conversion` defines conversion settings for the CRD.
|
||||
Conversion *CustomResourceConversion
|
||||
}
|
||||
|
||||
// CustomResourceConversion describes how to convert different versions of a CR.
|
||||
type CustomResourceConversion struct {
|
||||
// `strategy` specifies the conversion strategy. Allowed values are:
|
||||
// - `None`: The converter only change the apiVersion and would not touch any other field in the CR.
|
||||
// - `Webhook`: API Server will call to an external webhook to do the conversion. Additional information is needed for this option.
|
||||
Strategy ConversionStrategyType
|
||||
|
||||
// `webhookClientConfig` is the instructions for how to call the webhook if strategy is `Webhook`.
|
||||
WebhookClientConfig *WebhookClientConfig
|
||||
}
|
||||
|
||||
// WebhookClientConfig contains the information to make a TLS
|
||||
// connection with the webhook. It has the same field as admissionregistration.internal.WebhookClientConfig.
|
||||
type WebhookClientConfig struct {
|
||||
// `url` gives the location of the webhook, in standard URL form
|
||||
// (`scheme://host:port/path`). Exactly one of `url` or `service`
|
||||
// must be specified.
|
||||
//
|
||||
// The `host` should not refer to a service running in the cluster; use
|
||||
// the `service` field instead. The host might be resolved via external
|
||||
// DNS in some apiservers (e.g., `kube-apiserver` cannot resolve
|
||||
// in-cluster DNS as that would be a layering violation). `host` may
|
||||
// also be an IP address.
|
||||
//
|
||||
// Please note that using `localhost` or `127.0.0.1` as a `host` is
|
||||
// risky unless you take great care to run this webhook on all hosts
|
||||
// which run an apiserver which might need to make calls to this
|
||||
// webhook. Such installs are likely to be non-portable, i.e., not easy
|
||||
// to turn up in a new cluster.
|
||||
//
|
||||
// The scheme must be "https"; the URL must begin with "https://".
|
||||
//
|
||||
// A path is optional, and if present may be any string permissible in
|
||||
// a URL. You may use the path to pass an arbitrary string to the
|
||||
// webhook, for example, a cluster identifier.
|
||||
//
|
||||
// Attempting to use a user or basic auth e.g. "user:password@" is not
|
||||
// allowed. Fragments ("#...") and query parameters ("?...") are not
|
||||
// allowed, either.
|
||||
//
|
||||
// +optional
|
||||
URL *string
|
||||
|
||||
// `service` is a reference to the service for this webhook. Either
|
||||
// `service` or `url` must be specified.
|
||||
//
|
||||
// If the webhook is running within the cluster, then you should use `service`.
|
||||
//
|
||||
// Port 443 will be used if it is open, otherwise it is an error.
|
||||
//
|
||||
// +optional
|
||||
Service *ServiceReference
|
||||
|
||||
// `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
|
||||
// If unspecified, system trust roots on the apiserver are used.
|
||||
// +optional
|
||||
CABundle []byte
|
||||
}
|
||||
|
||||
// ServiceReference holds a reference to Service.legacy.k8s.io
|
||||
type ServiceReference struct {
|
||||
// `namespace` is the namespace of the service.
|
||||
// Required
|
||||
Namespace string
|
||||
// `name` is the name of the service.
|
||||
// Required
|
||||
Name string
|
||||
|
||||
// `path` is an optional URL path which will be sent in any request to
|
||||
// this service.
|
||||
// +optional
|
||||
Path *string
|
||||
}
|
||||
|
||||
// CustomResourceDefinitionVersion describes a version for CRD.
|
||||
type CustomResourceDefinitionVersion struct {
|
||||
// Name is the version name, e.g. “v1”, “v2beta1”, etc.
|
||||
Name string
|
||||
|
5
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/defaults.go
generated
vendored
5
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/defaults.go
generated
vendored
@@ -71,4 +71,9 @@ func SetDefaults_CustomResourceDefinitionSpec(obj *CustomResourceDefinitionSpec)
|
||||
{Name: "Age", Type: "date", Description: swaggerMetadataDescriptions["creationTimestamp"], JSONPath: ".metadata.creationTimestamp"},
|
||||
}
|
||||
}
|
||||
if obj.Conversion == nil {
|
||||
obj.Conversion = &CustomResourceConversion{
|
||||
Strategy: NoneConverter,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
4
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/doc.go
generated
vendored
4
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/doc.go
generated
vendored
@@ -17,8 +17,8 @@ limitations under the License.
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:conversion-gen=k8s.io/apiextensions-apiserver/pkg/apis/apiextensions
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +k8s:openapi-gen=true
|
||||
// +groupName=apiextensions.k8s.io
|
||||
|
||||
// Package v1beta1 is the v1beta1 version of the API.
|
||||
// +groupName=apiextensions.k8s.io
|
||||
// +k8s:openapi-gen=true
|
||||
package v1beta1 // import "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
|
2355
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go
generated
vendored
2355
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go
generated
vendored
File diff suppressed because it is too large
Load Diff
127
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto
generated
vendored
127
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto
generated
vendored
@@ -28,6 +28,51 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto";
|
||||
// Package-wide variables from generator "generated".
|
||||
option go_package = "v1beta1";
|
||||
|
||||
// ConversionRequest describes the conversion request parameters.
|
||||
message ConversionRequest {
|
||||
// `uid` is an identifier for the individual request/response. It allows us to distinguish instances of requests which are
|
||||
// otherwise identical (parallel requests, requests when earlier requests did not modify etc)
|
||||
// The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request.
|
||||
// It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging.
|
||||
optional string uid = 1;
|
||||
|
||||
// `desiredAPIVersion` is the version to convert given objects to. e.g. "myapi.example.com/v1"
|
||||
optional string desiredAPIVersion = 2;
|
||||
|
||||
// `objects` is the list of CR objects to be converted.
|
||||
repeated k8s.io.apimachinery.pkg.runtime.RawExtension objects = 3;
|
||||
}
|
||||
|
||||
// ConversionResponse describes a conversion response.
|
||||
message ConversionResponse {
|
||||
// `uid` is an identifier for the individual request/response.
|
||||
// This should be copied over from the corresponding AdmissionRequest.
|
||||
optional string uid = 1;
|
||||
|
||||
// `convertedObjects` is the list of converted version of `request.objects` if the `result` is successful otherwise empty.
|
||||
// The webhook is expected to set apiVersion of these objects to the ConversionRequest.desiredAPIVersion. The list
|
||||
// must also has the same size as input list with the same objects in the same order(i.e. equal UIDs and object meta)
|
||||
repeated k8s.io.apimachinery.pkg.runtime.RawExtension convertedObjects = 2;
|
||||
|
||||
// `result` contains the result of conversion with extra details if the conversion failed. `result.status` determines if
|
||||
// the conversion failed or succeeded. The `result.status` field is required and represent the success or failure of the
|
||||
// conversion. A successful conversion must set `result.status` to `Success`. A failed conversion must set
|
||||
// `result.status` to `Failure` and provide more details in `result.message` and return http status 200. The `result.message`
|
||||
// will be used to construct an error message for the end user.
|
||||
optional k8s.io.apimachinery.pkg.apis.meta.v1.Status result = 3;
|
||||
}
|
||||
|
||||
// ConversionReview describes a conversion request/response.
|
||||
message ConversionReview {
|
||||
// `request` describes the attributes for the conversion request.
|
||||
// +optional
|
||||
optional ConversionRequest request = 1;
|
||||
|
||||
// `response` describes the attributes for the conversion response.
|
||||
// +optional
|
||||
optional ConversionResponse response = 2;
|
||||
}
|
||||
|
||||
// CustomResourceColumnDefinition specifies a column for server side printing.
|
||||
message CustomResourceColumnDefinition {
|
||||
// name is a human readable name for the column.
|
||||
@@ -57,6 +102,19 @@ message CustomResourceColumnDefinition {
|
||||
optional string JSONPath = 6;
|
||||
}
|
||||
|
||||
// CustomResourceConversion describes how to convert different versions of a CR.
|
||||
message CustomResourceConversion {
|
||||
// `strategy` specifies the conversion strategy. Allowed values are:
|
||||
// - `None`: The converter only change the apiVersion and would not touch any other field in the CR.
|
||||
// - `Webhook`: API Server will call to an external webhook to do the conversion. Additional information is needed for this option.
|
||||
optional string strategy = 1;
|
||||
|
||||
// `webhookClientConfig` is the instructions for how to call the webhook if strategy is `Webhook`. This field is
|
||||
// alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature.
|
||||
// +optional
|
||||
optional WebhookClientConfig webhookClientConfig = 2;
|
||||
}
|
||||
|
||||
// CustomResourceDefinition represents a resource that should be exposed on the API server. Its name MUST be in the format
|
||||
// <.spec.name>.<.spec.group>.
|
||||
message CustomResourceDefinition {
|
||||
@@ -169,6 +227,10 @@ message CustomResourceDefinitionSpec {
|
||||
// AdditionalPrinterColumns are additional columns shown e.g. in kubectl next to the name. Defaults to a created-at column.
|
||||
// +optional
|
||||
repeated CustomResourceColumnDefinition additionalPrinterColumns = 8;
|
||||
|
||||
// `conversion` defines conversion settings for the CRD.
|
||||
// +optional
|
||||
optional CustomResourceConversion conversion = 9;
|
||||
}
|
||||
|
||||
// CustomResourceDefinitionStatus indicates the state of the CustomResourceDefinition
|
||||
@@ -189,6 +251,7 @@ message CustomResourceDefinitionStatus {
|
||||
repeated string storedVersions = 3;
|
||||
}
|
||||
|
||||
// CustomResourceDefinitionVersion describes a version for CRD.
|
||||
message CustomResourceDefinitionVersion {
|
||||
// Name is the version name, e.g. “v1”, “v2beta1”, etc.
|
||||
optional string name = 1;
|
||||
@@ -363,3 +426,67 @@ message JSONSchemaPropsOrStringArray {
|
||||
repeated string property = 2;
|
||||
}
|
||||
|
||||
// ServiceReference holds a reference to Service.legacy.k8s.io
|
||||
message ServiceReference {
|
||||
// `namespace` is the namespace of the service.
|
||||
// Required
|
||||
optional string namespace = 1;
|
||||
|
||||
// `name` is the name of the service.
|
||||
// Required
|
||||
optional string name = 2;
|
||||
|
||||
// `path` is an optional URL path which will be sent in any request to
|
||||
// this service.
|
||||
// +optional
|
||||
optional string path = 3;
|
||||
}
|
||||
|
||||
// WebhookClientConfig contains the information to make a TLS
|
||||
// connection with the webhook. It has the same field as admissionregistration.v1beta1.WebhookClientConfig.
|
||||
message WebhookClientConfig {
|
||||
// `url` gives the location of the webhook, in standard URL form
|
||||
// (`scheme://host:port/path`). Exactly one of `url` or `service`
|
||||
// must be specified.
|
||||
//
|
||||
// The `host` should not refer to a service running in the cluster; use
|
||||
// the `service` field instead. The host might be resolved via external
|
||||
// DNS in some apiservers (e.g., `kube-apiserver` cannot resolve
|
||||
// in-cluster DNS as that would be a layering violation). `host` may
|
||||
// also be an IP address.
|
||||
//
|
||||
// Please note that using `localhost` or `127.0.0.1` as a `host` is
|
||||
// risky unless you take great care to run this webhook on all hosts
|
||||
// which run an apiserver which might need to make calls to this
|
||||
// webhook. Such installs are likely to be non-portable, i.e., not easy
|
||||
// to turn up in a new cluster.
|
||||
//
|
||||
// The scheme must be "https"; the URL must begin with "https://".
|
||||
//
|
||||
// A path is optional, and if present may be any string permissible in
|
||||
// a URL. You may use the path to pass an arbitrary string to the
|
||||
// webhook, for example, a cluster identifier.
|
||||
//
|
||||
// Attempting to use a user or basic auth e.g. "user:password@" is not
|
||||
// allowed. Fragments ("#...") and query parameters ("?...") are not
|
||||
// allowed, either.
|
||||
//
|
||||
// +optional
|
||||
optional string url = 3;
|
||||
|
||||
// `service` is a reference to the service for this webhook. Either
|
||||
// `service` or `url` must be specified.
|
||||
//
|
||||
// If the webhook is running within the cluster, then you should use `service`.
|
||||
//
|
||||
// Port 443 will be used if it is open, otherwise it is an error.
|
||||
//
|
||||
// +optional
|
||||
optional ServiceReference service = 1;
|
||||
|
||||
// `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
|
||||
// If unspecified, system trust roots on the apiserver are used.
|
||||
// +optional
|
||||
optional bytes caBundle = 2;
|
||||
}
|
||||
|
||||
|
1
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/register.go
generated
vendored
1
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/register.go
generated
vendored
@@ -48,6 +48,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&CustomResourceDefinition{},
|
||||
&CustomResourceDefinitionList{},
|
||||
&ConversionReview{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
|
136
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types.go
generated
vendored
136
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types.go
generated
vendored
@@ -18,6 +18,18 @@ package v1beta1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
// ConversionStrategyType describes different conversion types.
|
||||
type ConversionStrategyType string
|
||||
|
||||
const (
|
||||
// NoneConverter is a converter that only sets apiversion of the CR and leave everything else unchanged.
|
||||
NoneConverter ConversionStrategyType = "None"
|
||||
// WebhookConverter is a converter that calls to an external webhook to convert the CR.
|
||||
WebhookConverter ConversionStrategyType = "Webhook"
|
||||
)
|
||||
|
||||
// CustomResourceDefinitionSpec describes how a user wants their resource to appear
|
||||
@@ -56,8 +68,89 @@ type CustomResourceDefinitionSpec struct {
|
||||
// AdditionalPrinterColumns are additional columns shown e.g. in kubectl next to the name. Defaults to a created-at column.
|
||||
// +optional
|
||||
AdditionalPrinterColumns []CustomResourceColumnDefinition `json:"additionalPrinterColumns,omitempty" protobuf:"bytes,8,rep,name=additionalPrinterColumns"`
|
||||
|
||||
// `conversion` defines conversion settings for the CRD.
|
||||
// +optional
|
||||
Conversion *CustomResourceConversion `json:"conversion,omitempty" protobuf:"bytes,9,opt,name=conversion"`
|
||||
}
|
||||
|
||||
// CustomResourceConversion describes how to convert different versions of a CR.
|
||||
type CustomResourceConversion struct {
|
||||
// `strategy` specifies the conversion strategy. Allowed values are:
|
||||
// - `None`: The converter only change the apiVersion and would not touch any other field in the CR.
|
||||
// - `Webhook`: API Server will call to an external webhook to do the conversion. Additional information is needed for this option.
|
||||
Strategy ConversionStrategyType `json:"strategy" protobuf:"bytes,1,name=strategy"`
|
||||
|
||||
// `webhookClientConfig` is the instructions for how to call the webhook if strategy is `Webhook`. This field is
|
||||
// alpha-level and is only honored by servers that enable the CustomResourceWebhookConversion feature.
|
||||
// +optional
|
||||
WebhookClientConfig *WebhookClientConfig `json:"webhookClientConfig,omitempty" protobuf:"bytes,2,name=webhookClientConfig"`
|
||||
}
|
||||
|
||||
// WebhookClientConfig contains the information to make a TLS
|
||||
// connection with the webhook. It has the same field as admissionregistration.v1beta1.WebhookClientConfig.
|
||||
type WebhookClientConfig struct {
|
||||
// `url` gives the location of the webhook, in standard URL form
|
||||
// (`scheme://host:port/path`). Exactly one of `url` or `service`
|
||||
// must be specified.
|
||||
//
|
||||
// The `host` should not refer to a service running in the cluster; use
|
||||
// the `service` field instead. The host might be resolved via external
|
||||
// DNS in some apiservers (e.g., `kube-apiserver` cannot resolve
|
||||
// in-cluster DNS as that would be a layering violation). `host` may
|
||||
// also be an IP address.
|
||||
//
|
||||
// Please note that using `localhost` or `127.0.0.1` as a `host` is
|
||||
// risky unless you take great care to run this webhook on all hosts
|
||||
// which run an apiserver which might need to make calls to this
|
||||
// webhook. Such installs are likely to be non-portable, i.e., not easy
|
||||
// to turn up in a new cluster.
|
||||
//
|
||||
// The scheme must be "https"; the URL must begin with "https://".
|
||||
//
|
||||
// A path is optional, and if present may be any string permissible in
|
||||
// a URL. You may use the path to pass an arbitrary string to the
|
||||
// webhook, for example, a cluster identifier.
|
||||
//
|
||||
// Attempting to use a user or basic auth e.g. "user:password@" is not
|
||||
// allowed. Fragments ("#...") and query parameters ("?...") are not
|
||||
// allowed, either.
|
||||
//
|
||||
// +optional
|
||||
URL *string `json:"url,omitempty" protobuf:"bytes,3,opt,name=url"`
|
||||
|
||||
// `service` is a reference to the service for this webhook. Either
|
||||
// `service` or `url` must be specified.
|
||||
//
|
||||
// If the webhook is running within the cluster, then you should use `service`.
|
||||
//
|
||||
// Port 443 will be used if it is open, otherwise it is an error.
|
||||
//
|
||||
// +optional
|
||||
Service *ServiceReference `json:"service,omitempty" protobuf:"bytes,1,opt,name=service"`
|
||||
|
||||
// `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
|
||||
// If unspecified, system trust roots on the apiserver are used.
|
||||
// +optional
|
||||
CABundle []byte `json:"caBundle,omitempty" protobuf:"bytes,2,opt,name=caBundle"`
|
||||
}
|
||||
|
||||
// ServiceReference holds a reference to Service.legacy.k8s.io
|
||||
type ServiceReference struct {
|
||||
// `namespace` is the namespace of the service.
|
||||
// Required
|
||||
Namespace string `json:"namespace" protobuf:"bytes,1,opt,name=namespace"`
|
||||
// `name` is the name of the service.
|
||||
// Required
|
||||
Name string `json:"name" protobuf:"bytes,2,opt,name=name"`
|
||||
|
||||
// `path` is an optional URL path which will be sent in any request to
|
||||
// this service.
|
||||
// +optional
|
||||
Path *string `json:"path,omitempty" protobuf:"bytes,3,opt,name=path"`
|
||||
}
|
||||
|
||||
// CustomResourceDefinitionVersion describes a version for CRD.
|
||||
type CustomResourceDefinitionVersion struct {
|
||||
// Name is the version name, e.g. “v1”, “v2beta1”, etc.
|
||||
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
|
||||
@@ -263,3 +356,46 @@ type CustomResourceSubresourceScale struct {
|
||||
// +optional
|
||||
LabelSelectorPath *string `json:"labelSelectorPath,omitempty" protobuf:"bytes,3,opt,name=labelSelectorPath"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ConversionReview describes a conversion request/response.
|
||||
type ConversionReview struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// `request` describes the attributes for the conversion request.
|
||||
// +optional
|
||||
Request *ConversionRequest `json:"request,omitempty" protobuf:"bytes,1,opt,name=request"`
|
||||
// `response` describes the attributes for the conversion response.
|
||||
// +optional
|
||||
Response *ConversionResponse `json:"response,omitempty" protobuf:"bytes,2,opt,name=response"`
|
||||
}
|
||||
|
||||
// ConversionRequest describes the conversion request parameters.
|
||||
type ConversionRequest struct {
|
||||
// `uid` is an identifier for the individual request/response. It allows us to distinguish instances of requests which are
|
||||
// otherwise identical (parallel requests, requests when earlier requests did not modify etc)
|
||||
// The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request.
|
||||
// It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging.
|
||||
UID types.UID `json:"uid" protobuf:"bytes,1,name=uid"`
|
||||
// `desiredAPIVersion` is the version to convert given objects to. e.g. "myapi.example.com/v1"
|
||||
DesiredAPIVersion string `json:"desiredAPIVersion" protobuf:"bytes,2,name=desiredAPIVersion"`
|
||||
// `objects` is the list of CR objects to be converted.
|
||||
Objects []runtime.RawExtension `json:"objects" protobuf:"bytes,3,rep,name=objects"`
|
||||
}
|
||||
|
||||
// ConversionResponse describes a conversion response.
|
||||
type ConversionResponse struct {
|
||||
// `uid` is an identifier for the individual request/response.
|
||||
// This should be copied over from the corresponding AdmissionRequest.
|
||||
UID types.UID `json:"uid" protobuf:"bytes,1,name=uid"`
|
||||
// `convertedObjects` is the list of converted version of `request.objects` if the `result` is successful otherwise empty.
|
||||
// The webhook is expected to set apiVersion of these objects to the ConversionRequest.desiredAPIVersion. The list
|
||||
// must also has the same size as input list with the same objects in the same order(i.e. equal UIDs and object meta)
|
||||
ConvertedObjects []runtime.RawExtension `json:"convertedObjects" protobuf:"bytes,2,rep,name=convertedObjects"`
|
||||
// `result` contains the result of conversion with extra details if the conversion failed. `result.status` determines if
|
||||
// the conversion failed or succeeded. The `result.status` field is required and represent the success or failure of the
|
||||
// conversion. A successful conversion must set `result.status` to `Success`. A failed conversion must set
|
||||
// `result.status` to `Failure` and provide more details in `result.message` and return http status 200. The `result.message`
|
||||
// will be used to construct an error message for the end user.
|
||||
Result metav1.Status `json:"result" protobuf:"bytes,3,name=result"`
|
||||
}
|
||||
|
@@ -45,6 +45,16 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*CustomResourceConversion)(nil), (*apiextensions.CustomResourceConversion)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta1_CustomResourceConversion_To_apiextensions_CustomResourceConversion(a.(*CustomResourceConversion), b.(*apiextensions.CustomResourceConversion), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*apiextensions.CustomResourceConversion)(nil), (*CustomResourceConversion)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_apiextensions_CustomResourceConversion_To_v1beta1_CustomResourceConversion(a.(*apiextensions.CustomResourceConversion), b.(*CustomResourceConversion), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*CustomResourceDefinition)(nil), (*apiextensions.CustomResourceDefinition)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta1_CustomResourceDefinition_To_apiextensions_CustomResourceDefinition(a.(*CustomResourceDefinition), b.(*apiextensions.CustomResourceDefinition), scope)
|
||||
}); err != nil {
|
||||
@@ -215,6 +225,26 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*ServiceReference)(nil), (*apiextensions.ServiceReference)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta1_ServiceReference_To_apiextensions_ServiceReference(a.(*ServiceReference), b.(*apiextensions.ServiceReference), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*apiextensions.ServiceReference)(nil), (*ServiceReference)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_apiextensions_ServiceReference_To_v1beta1_ServiceReference(a.(*apiextensions.ServiceReference), b.(*ServiceReference), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*WebhookClientConfig)(nil), (*apiextensions.WebhookClientConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta1_WebhookClientConfig_To_apiextensions_WebhookClientConfig(a.(*WebhookClientConfig), b.(*apiextensions.WebhookClientConfig), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*apiextensions.WebhookClientConfig)(nil), (*WebhookClientConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_apiextensions_WebhookClientConfig_To_v1beta1_WebhookClientConfig(a.(*apiextensions.WebhookClientConfig), b.(*WebhookClientConfig), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddConversionFunc((*apiextensions.JSONSchemaProps)(nil), (*JSONSchemaProps)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_apiextensions_JSONSchemaProps_To_v1beta1_JSONSchemaProps(a.(*apiextensions.JSONSchemaProps), b.(*JSONSchemaProps), scope)
|
||||
}); err != nil {
|
||||
@@ -263,6 +293,28 @@ func Convert_apiextensions_CustomResourceColumnDefinition_To_v1beta1_CustomResou
|
||||
return autoConvert_apiextensions_CustomResourceColumnDefinition_To_v1beta1_CustomResourceColumnDefinition(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_CustomResourceConversion_To_apiextensions_CustomResourceConversion(in *CustomResourceConversion, out *apiextensions.CustomResourceConversion, s conversion.Scope) error {
|
||||
out.Strategy = apiextensions.ConversionStrategyType(in.Strategy)
|
||||
out.WebhookClientConfig = (*apiextensions.WebhookClientConfig)(unsafe.Pointer(in.WebhookClientConfig))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1beta1_CustomResourceConversion_To_apiextensions_CustomResourceConversion is an autogenerated conversion function.
|
||||
func Convert_v1beta1_CustomResourceConversion_To_apiextensions_CustomResourceConversion(in *CustomResourceConversion, out *apiextensions.CustomResourceConversion, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_CustomResourceConversion_To_apiextensions_CustomResourceConversion(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_apiextensions_CustomResourceConversion_To_v1beta1_CustomResourceConversion(in *apiextensions.CustomResourceConversion, out *CustomResourceConversion, s conversion.Scope) error {
|
||||
out.Strategy = ConversionStrategyType(in.Strategy)
|
||||
out.WebhookClientConfig = (*WebhookClientConfig)(unsafe.Pointer(in.WebhookClientConfig))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_apiextensions_CustomResourceConversion_To_v1beta1_CustomResourceConversion is an autogenerated conversion function.
|
||||
func Convert_apiextensions_CustomResourceConversion_To_v1beta1_CustomResourceConversion(in *apiextensions.CustomResourceConversion, out *CustomResourceConversion, s conversion.Scope) error {
|
||||
return autoConvert_apiextensions_CustomResourceConversion_To_v1beta1_CustomResourceConversion(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_CustomResourceDefinition_To_apiextensions_CustomResourceDefinition(in *CustomResourceDefinition, out *apiextensions.CustomResourceDefinition, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_v1beta1_CustomResourceDefinitionSpec_To_apiextensions_CustomResourceDefinitionSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
@@ -414,6 +466,7 @@ func autoConvert_v1beta1_CustomResourceDefinitionSpec_To_apiextensions_CustomRes
|
||||
out.Subresources = (*apiextensions.CustomResourceSubresources)(unsafe.Pointer(in.Subresources))
|
||||
out.Versions = *(*[]apiextensions.CustomResourceDefinitionVersion)(unsafe.Pointer(&in.Versions))
|
||||
out.AdditionalPrinterColumns = *(*[]apiextensions.CustomResourceColumnDefinition)(unsafe.Pointer(&in.AdditionalPrinterColumns))
|
||||
out.Conversion = (*apiextensions.CustomResourceConversion)(unsafe.Pointer(in.Conversion))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -441,6 +494,7 @@ func autoConvert_apiextensions_CustomResourceDefinitionSpec_To_v1beta1_CustomRes
|
||||
out.Subresources = (*CustomResourceSubresources)(unsafe.Pointer(in.Subresources))
|
||||
out.Versions = *(*[]CustomResourceDefinitionVersion)(unsafe.Pointer(&in.Versions))
|
||||
out.AdditionalPrinterColumns = *(*[]CustomResourceColumnDefinition)(unsafe.Pointer(&in.AdditionalPrinterColumns))
|
||||
out.Conversion = (*CustomResourceConversion)(unsafe.Pointer(in.Conversion))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1123,3 +1177,51 @@ func autoConvert_apiextensions_JSONSchemaPropsOrStringArray_To_v1beta1_JSONSchem
|
||||
func Convert_apiextensions_JSONSchemaPropsOrStringArray_To_v1beta1_JSONSchemaPropsOrStringArray(in *apiextensions.JSONSchemaPropsOrStringArray, out *JSONSchemaPropsOrStringArray, s conversion.Scope) error {
|
||||
return autoConvert_apiextensions_JSONSchemaPropsOrStringArray_To_v1beta1_JSONSchemaPropsOrStringArray(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_ServiceReference_To_apiextensions_ServiceReference(in *ServiceReference, out *apiextensions.ServiceReference, s conversion.Scope) error {
|
||||
out.Namespace = in.Namespace
|
||||
out.Name = in.Name
|
||||
out.Path = (*string)(unsafe.Pointer(in.Path))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1beta1_ServiceReference_To_apiextensions_ServiceReference is an autogenerated conversion function.
|
||||
func Convert_v1beta1_ServiceReference_To_apiextensions_ServiceReference(in *ServiceReference, out *apiextensions.ServiceReference, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_ServiceReference_To_apiextensions_ServiceReference(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_apiextensions_ServiceReference_To_v1beta1_ServiceReference(in *apiextensions.ServiceReference, out *ServiceReference, s conversion.Scope) error {
|
||||
out.Namespace = in.Namespace
|
||||
out.Name = in.Name
|
||||
out.Path = (*string)(unsafe.Pointer(in.Path))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_apiextensions_ServiceReference_To_v1beta1_ServiceReference is an autogenerated conversion function.
|
||||
func Convert_apiextensions_ServiceReference_To_v1beta1_ServiceReference(in *apiextensions.ServiceReference, out *ServiceReference, s conversion.Scope) error {
|
||||
return autoConvert_apiextensions_ServiceReference_To_v1beta1_ServiceReference(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_WebhookClientConfig_To_apiextensions_WebhookClientConfig(in *WebhookClientConfig, out *apiextensions.WebhookClientConfig, s conversion.Scope) error {
|
||||
out.URL = (*string)(unsafe.Pointer(in.URL))
|
||||
out.Service = (*apiextensions.ServiceReference)(unsafe.Pointer(in.Service))
|
||||
out.CABundle = *(*[]byte)(unsafe.Pointer(&in.CABundle))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1beta1_WebhookClientConfig_To_apiextensions_WebhookClientConfig is an autogenerated conversion function.
|
||||
func Convert_v1beta1_WebhookClientConfig_To_apiextensions_WebhookClientConfig(in *WebhookClientConfig, out *apiextensions.WebhookClientConfig, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_WebhookClientConfig_To_apiextensions_WebhookClientConfig(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_apiextensions_WebhookClientConfig_To_v1beta1_WebhookClientConfig(in *apiextensions.WebhookClientConfig, out *WebhookClientConfig, s conversion.Scope) error {
|
||||
out.URL = (*string)(unsafe.Pointer(in.URL))
|
||||
out.Service = (*ServiceReference)(unsafe.Pointer(in.Service))
|
||||
out.CABundle = *(*[]byte)(unsafe.Pointer(&in.CABundle))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_apiextensions_WebhookClientConfig_To_v1beta1_WebhookClientConfig is an autogenerated conversion function.
|
||||
func Convert_apiextensions_WebhookClientConfig_To_v1beta1_WebhookClientConfig(in *apiextensions.WebhookClientConfig, out *WebhookClientConfig, s conversion.Scope) error {
|
||||
return autoConvert_apiextensions_WebhookClientConfig_To_v1beta1_WebhookClientConfig(in, out, s)
|
||||
}
|
||||
|
@@ -24,6 +24,88 @@ 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 *ConversionRequest) DeepCopyInto(out *ConversionRequest) {
|
||||
*out = *in
|
||||
if in.Objects != nil {
|
||||
in, out := &in.Objects, &out.Objects
|
||||
*out = make([]runtime.RawExtension, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConversionRequest.
|
||||
func (in *ConversionRequest) DeepCopy() *ConversionRequest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ConversionRequest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ConversionResponse) DeepCopyInto(out *ConversionResponse) {
|
||||
*out = *in
|
||||
if in.ConvertedObjects != nil {
|
||||
in, out := &in.ConvertedObjects, &out.ConvertedObjects
|
||||
*out = make([]runtime.RawExtension, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
in.Result.DeepCopyInto(&out.Result)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConversionResponse.
|
||||
func (in *ConversionResponse) DeepCopy() *ConversionResponse {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ConversionResponse)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ConversionReview) DeepCopyInto(out *ConversionReview) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.Request != nil {
|
||||
in, out := &in.Request, &out.Request
|
||||
*out = new(ConversionRequest)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Response != nil {
|
||||
in, out := &in.Response, &out.Response
|
||||
*out = new(ConversionResponse)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConversionReview.
|
||||
func (in *ConversionReview) DeepCopy() *ConversionReview {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ConversionReview)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ConversionReview) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CustomResourceColumnDefinition) DeepCopyInto(out *CustomResourceColumnDefinition) {
|
||||
*out = *in
|
||||
@@ -40,6 +122,27 @@ func (in *CustomResourceColumnDefinition) DeepCopy() *CustomResourceColumnDefini
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CustomResourceConversion) DeepCopyInto(out *CustomResourceConversion) {
|
||||
*out = *in
|
||||
if in.WebhookClientConfig != nil {
|
||||
in, out := &in.WebhookClientConfig, &out.WebhookClientConfig
|
||||
*out = new(WebhookClientConfig)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceConversion.
|
||||
func (in *CustomResourceConversion) DeepCopy() *CustomResourceConversion {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CustomResourceConversion)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CustomResourceDefinition) DeepCopyInto(out *CustomResourceDefinition) {
|
||||
*out = *in
|
||||
@@ -168,6 +271,11 @@ func (in *CustomResourceDefinitionSpec) DeepCopyInto(out *CustomResourceDefiniti
|
||||
*out = make([]CustomResourceColumnDefinition, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Conversion != nil {
|
||||
in, out := &in.Conversion, &out.Conversion
|
||||
*out = new(CustomResourceConversion)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -468,3 +576,55 @@ func (in *JSONSchemaPropsOrStringArray) DeepCopy() *JSONSchemaPropsOrStringArray
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ServiceReference) DeepCopyInto(out *ServiceReference) {
|
||||
*out = *in
|
||||
if in.Path != nil {
|
||||
in, out := &in.Path, &out.Path
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceReference.
|
||||
func (in *ServiceReference) DeepCopy() *ServiceReference {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ServiceReference)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WebhookClientConfig) DeepCopyInto(out *WebhookClientConfig) {
|
||||
*out = *in
|
||||
if in.URL != nil {
|
||||
in, out := &in.URL, &out.URL
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Service != nil {
|
||||
in, out := &in.Service, &out.Service
|
||||
*out = new(ServiceReference)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.CABundle != nil {
|
||||
in, out := &in.CABundle, &out.CABundle
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookClientConfig.
|
||||
func (in *WebhookClientConfig) DeepCopy() *WebhookClientConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WebhookClientConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
57
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go
generated
vendored
57
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go
generated
vendored
@@ -18,6 +18,7 @@ package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"k8s.io/apiserver/pkg/util/webhook"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
@@ -110,13 +111,7 @@ func ValidateCustomResourceDefinitionSpec(spec *apiextensions.CustomResourceDefi
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("group"), spec.Group, "should be a domain with at least one dot"))
|
||||
}
|
||||
|
||||
switch spec.Scope {
|
||||
case "":
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("scope"), ""))
|
||||
case apiextensions.ClusterScoped, apiextensions.NamespaceScoped:
|
||||
default:
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("scope"), spec.Scope, []string{string(apiextensions.ClusterScoped), string(apiextensions.NamespaceScoped)}))
|
||||
}
|
||||
allErrs = append(allErrs, validateEnumStrings(fldPath.Child("scope"), string(spec.Scope), []string{string(apiextensions.ClusterScoped), string(apiextensions.NamespaceScoped)}, true)...)
|
||||
|
||||
storageFlagCount := 0
|
||||
versionsMap := map[string]bool{}
|
||||
@@ -187,6 +182,54 @@ func ValidateCustomResourceDefinitionSpec(spec *apiextensions.CustomResourceDefi
|
||||
}
|
||||
}
|
||||
|
||||
allErrs = append(allErrs, ValidateCustomResourceConversion(spec.Conversion, fldPath.Child("conversion"))...)
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateEnumStrings(fldPath *field.Path, value string, accepted []string, required bool) field.ErrorList {
|
||||
if value == "" {
|
||||
if required {
|
||||
return field.ErrorList{field.Required(fldPath, "")}
|
||||
}
|
||||
return field.ErrorList{}
|
||||
}
|
||||
for _, a := range accepted {
|
||||
if a == value {
|
||||
return field.ErrorList{}
|
||||
}
|
||||
}
|
||||
return field.ErrorList{field.NotSupported(fldPath, value, accepted)}
|
||||
}
|
||||
|
||||
// ValidateCustomResourceConversion statically validates
|
||||
func ValidateCustomResourceConversion(conversion *apiextensions.CustomResourceConversion, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if conversion == nil {
|
||||
return allErrs
|
||||
}
|
||||
allErrs = append(allErrs, validateEnumStrings(fldPath.Child("strategy"), string(conversion.Strategy), []string{string(apiextensions.NoneConverter), string(apiextensions.WebhookConverter)}, true)...)
|
||||
if conversion.Strategy == apiextensions.WebhookConverter {
|
||||
if conversion.WebhookClientConfig == nil {
|
||||
if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("webhookClientConfig"), "required when strategy is set to Webhook"))
|
||||
} else {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("webhookClientConfig"), "required when strategy is set to Webhook, but not allowed because the CustomResourceWebhookConversion feature is disabled"))
|
||||
}
|
||||
} else {
|
||||
cc := conversion.WebhookClientConfig
|
||||
switch {
|
||||
case (cc.URL == nil) == (cc.Service == nil):
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("webhookClientConfig"), "exactly one of url or service is required"))
|
||||
case cc.URL != nil:
|
||||
allErrs = append(allErrs, webhook.ValidateWebhookURL(fldPath.Child("webhookClientConfig").Child("url"), *cc.URL, true)...)
|
||||
case cc.Service != nil:
|
||||
allErrs = append(allErrs, webhook.ValidateWebhookService(fldPath.Child("webhookClientConfig").Child("service"), cc.Service.Name, cc.Service.Namespace, cc.Service.Path)...)
|
||||
}
|
||||
}
|
||||
} else if conversion.WebhookClientConfig != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("webhookClientConfig"), "should not be set when strategy is not set to Webhook"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
|
226
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go
generated
vendored
226
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go
generated
vendored
@@ -49,6 +49,8 @@ func (v validationMatch) matches(err *field.Error) bool {
|
||||
return err.Type == v.errorType && err.Field == v.path.String()
|
||||
}
|
||||
|
||||
func strPtr(s string) *string { return &s }
|
||||
|
||||
func TestValidateCustomResourceDefinition(t *testing.T) {
|
||||
singleVersionList := []apiextensions.CustomResourceDefinitionVersion{
|
||||
{
|
||||
@@ -62,6 +64,205 @@ func TestValidateCustomResourceDefinition(t *testing.T) {
|
||||
resource *apiextensions.CustomResourceDefinition
|
||||
errors []validationMatch
|
||||
}{
|
||||
{
|
||||
name: "webhookconfig: blank URL",
|
||||
resource: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
Scope: apiextensions.ResourceScope("Cluster"),
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
Kind: "Plural",
|
||||
ListKind: "PluralList",
|
||||
},
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "version",
|
||||
Served: true,
|
||||
Storage: true,
|
||||
},
|
||||
{
|
||||
Name: "version2",
|
||||
Served: true,
|
||||
Storage: false,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("Webhook"),
|
||||
WebhookClientConfig: &apiextensions.WebhookClientConfig{
|
||||
URL: strPtr("https://example.com/webhook"),
|
||||
Service: &apiextensions.ServiceReference{
|
||||
Name: "n",
|
||||
Namespace: "ns",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
},
|
||||
},
|
||||
errors: []validationMatch{
|
||||
required("spec", "conversion", "webhookClientConfig"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "webhookconfig: both service and URL provided",
|
||||
resource: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
Scope: apiextensions.ResourceScope("Cluster"),
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
Kind: "Plural",
|
||||
ListKind: "PluralList",
|
||||
},
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "version",
|
||||
Served: true,
|
||||
Storage: true,
|
||||
},
|
||||
{
|
||||
Name: "version2",
|
||||
Served: true,
|
||||
Storage: false,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("Webhook"),
|
||||
WebhookClientConfig: &apiextensions.WebhookClientConfig{
|
||||
URL: strPtr(""),
|
||||
},
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
},
|
||||
},
|
||||
errors: []validationMatch{
|
||||
invalid("spec", "conversion", "webhookClientConfig", "url"),
|
||||
invalid("spec", "conversion", "webhookClientConfig", "url"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "webhookconfig_should_not_be_set",
|
||||
resource: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
Scope: apiextensions.ResourceScope("Cluster"),
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
Kind: "Plural",
|
||||
ListKind: "PluralList",
|
||||
},
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "version",
|
||||
Served: true,
|
||||
Storage: true,
|
||||
},
|
||||
{
|
||||
Name: "version2",
|
||||
Served: true,
|
||||
Storage: false,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("None"),
|
||||
WebhookClientConfig: &apiextensions.WebhookClientConfig{
|
||||
URL: strPtr("https://example.com/webhook"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
},
|
||||
},
|
||||
errors: []validationMatch{
|
||||
forbidden("spec", "conversion", "webhookClientConfig"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "missing_webhookconfig",
|
||||
resource: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
Scope: apiextensions.ResourceScope("Cluster"),
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
Kind: "Plural",
|
||||
ListKind: "PluralList",
|
||||
},
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "version",
|
||||
Served: true,
|
||||
Storage: true,
|
||||
},
|
||||
{
|
||||
Name: "version2",
|
||||
Served: true,
|
||||
Storage: false,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("Webhook"),
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
},
|
||||
},
|
||||
errors: []validationMatch{
|
||||
required("spec", "conversion", "webhookClientConfig"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid_conversion_strategy",
|
||||
resource: &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"},
|
||||
Spec: apiextensions.CustomResourceDefinitionSpec{
|
||||
Group: "group.com",
|
||||
Scope: apiextensions.ResourceScope("Cluster"),
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
Kind: "Plural",
|
||||
ListKind: "PluralList",
|
||||
},
|
||||
Versions: []apiextensions.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "version",
|
||||
Served: true,
|
||||
Storage: true,
|
||||
},
|
||||
{
|
||||
Name: "version2",
|
||||
Served: true,
|
||||
Storage: false,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("non_existing_conversion"),
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
},
|
||||
},
|
||||
errors: []validationMatch{
|
||||
unsupported("spec", "conversion", "strategy"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no_storage_version",
|
||||
resource: &apiextensions.CustomResourceDefinition{
|
||||
@@ -87,6 +288,9 @@ func TestValidateCustomResourceDefinition(t *testing.T) {
|
||||
Storage: false,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("None"),
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
@@ -121,6 +325,9 @@ func TestValidateCustomResourceDefinition(t *testing.T) {
|
||||
Storage: true,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("None"),
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
@@ -156,6 +363,9 @@ func TestValidateCustomResourceDefinition(t *testing.T) {
|
||||
Storage: true,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("None"),
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{"version"},
|
||||
@@ -185,6 +395,9 @@ func TestValidateCustomResourceDefinition(t *testing.T) {
|
||||
Storage: true,
|
||||
},
|
||||
},
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("None"),
|
||||
},
|
||||
},
|
||||
Status: apiextensions.CustomResourceDefinitionStatus{
|
||||
StoredVersions: []string{},
|
||||
@@ -283,6 +496,9 @@ func TestValidateCustomResourceDefinition(t *testing.T) {
|
||||
Group: "group.c(*&om",
|
||||
Version: "version",
|
||||
Versions: singleVersionList,
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("None"),
|
||||
},
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
@@ -316,7 +532,10 @@ func TestValidateCustomResourceDefinition(t *testing.T) {
|
||||
Group: "group.com",
|
||||
Version: "version",
|
||||
Versions: singleVersionList,
|
||||
Scope: apiextensions.NamespaceScoped,
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("None"),
|
||||
},
|
||||
Scope: apiextensions.NamespaceScoped,
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
@@ -348,7 +567,10 @@ func TestValidateCustomResourceDefinition(t *testing.T) {
|
||||
Group: "group.com",
|
||||
Version: "version",
|
||||
Versions: singleVersionList,
|
||||
Scope: apiextensions.NamespaceScoped,
|
||||
Conversion: &apiextensions.CustomResourceConversion{
|
||||
Strategy: apiextensions.ConversionStrategyType("None"),
|
||||
},
|
||||
Scope: apiextensions.NamespaceScoped,
|
||||
Names: apiextensions.CustomResourceDefinitionNames{
|
||||
Plural: "plural",
|
||||
Singular: "singular",
|
||||
|
78
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/zz_generated.deepcopy.go
generated
vendored
78
vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/zz_generated.deepcopy.go
generated
vendored
@@ -40,6 +40,27 @@ func (in *CustomResourceColumnDefinition) DeepCopy() *CustomResourceColumnDefini
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CustomResourceConversion) DeepCopyInto(out *CustomResourceConversion) {
|
||||
*out = *in
|
||||
if in.WebhookClientConfig != nil {
|
||||
in, out := &in.WebhookClientConfig, &out.WebhookClientConfig
|
||||
*out = new(WebhookClientConfig)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceConversion.
|
||||
func (in *CustomResourceConversion) DeepCopy() *CustomResourceConversion {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CustomResourceConversion)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CustomResourceDefinition) DeepCopyInto(out *CustomResourceDefinition) {
|
||||
*out = *in
|
||||
@@ -168,6 +189,11 @@ func (in *CustomResourceDefinitionSpec) DeepCopyInto(out *CustomResourceDefiniti
|
||||
*out = make([]CustomResourceColumnDefinition, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Conversion != nil {
|
||||
in, out := &in.Conversion, &out.Conversion
|
||||
*out = new(CustomResourceConversion)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -447,3 +473,55 @@ func (in *JSONSchemaPropsOrStringArray) DeepCopy() *JSONSchemaPropsOrStringArray
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ServiceReference) DeepCopyInto(out *ServiceReference) {
|
||||
*out = *in
|
||||
if in.Path != nil {
|
||||
in, out := &in.Path, &out.Path
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceReference.
|
||||
func (in *ServiceReference) DeepCopy() *ServiceReference {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ServiceReference)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WebhookClientConfig) DeepCopyInto(out *WebhookClientConfig) {
|
||||
*out = *in
|
||||
if in.URL != nil {
|
||||
in, out := &in.URL, &out.URL
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Service != nil {
|
||||
in, out := &in.Service, &out.Service
|
||||
*out = new(ServiceReference)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.CABundle != nil {
|
||||
in, out := &in.CABundle, &out.CABundle
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookClientConfig.
|
||||
func (in *WebhookClientConfig) DeepCopy() *WebhookClientConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WebhookClientConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
4
vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go
generated
vendored
4
vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go
generated
vendored
@@ -477,6 +477,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource
|
||||
|
||||
storages[v.Name] = customresource.NewStorage(
|
||||
schema.GroupResource{Group: crd.Spec.Group, Resource: crd.Status.AcceptedNames.Plural},
|
||||
schema.GroupVersionKind{Group: crd.Spec.Group, Version: v.Name, Kind: crd.Status.AcceptedNames.Kind},
|
||||
schema.GroupVersionKind{Group: crd.Spec.Group, Version: v.Name, Kind: crd.Status.AcceptedNames.ListKind},
|
||||
customresource.NewStrategy(
|
||||
typer,
|
||||
@@ -525,6 +526,9 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource
|
||||
Resource: schema.GroupVersionResource{Group: crd.Spec.Group, Version: v.Name, Resource: crd.Status.AcceptedNames.Plural},
|
||||
Kind: kind,
|
||||
|
||||
// a handler for a specific group-version of a custom resource uses that version as the in-memory representation
|
||||
HubGroupVersion: kind.GroupVersion(),
|
||||
|
||||
MetaGroupVersion: metav1.SchemeGroupVersion,
|
||||
|
||||
TableConvertor: storages[v.Name].CustomResource,
|
||||
|
@@ -123,7 +123,7 @@ func (c *FakeCustomResourceDefinitions) DeleteCollection(options *v1.DeleteOptio
|
||||
// Patch applies the patch and returns the patched customResourceDefinition.
|
||||
func (c *FakeCustomResourceDefinitions) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.CustomResourceDefinition, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(customresourcedefinitionsResource, name, data, subresources...), &v1beta1.CustomResourceDefinition{})
|
||||
Invokes(testing.NewRootPatchSubresourceAction(customresourcedefinitionsResource, name, pt, data, subresources...), &v1beta1.CustomResourceDefinition{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -123,7 +123,7 @@ func (c *FakeCustomResourceDefinitions) DeleteCollection(options *v1.DeleteOptio
|
||||
// Patch applies the patch and returns the patched customResourceDefinition.
|
||||
func (c *FakeCustomResourceDefinitions) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *apiextensions.CustomResourceDefinition, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(customresourcedefinitionsResource, name, data, subresources...), &apiextensions.CustomResourceDefinition{})
|
||||
Invokes(testing.NewRootPatchSubresourceAction(customresourcedefinitionsResource, name, pt, data, subresources...), &apiextensions.CustomResourceDefinition{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@ import (
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// NewInformerFunc takes clientset.Interface and time.Duration to return a SharedIndexInformer.
|
||||
type NewInformerFunc func(clientset.Interface, time.Duration) cache.SharedIndexInformer
|
||||
|
||||
// SharedInformerFactory a small interface to allow for adding an informer without an import cycle
|
||||
@@ -35,4 +36,5 @@ type SharedInformerFactory interface {
|
||||
InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
|
||||
}
|
||||
|
||||
// TweakListOptionsFunc is a function that transforms a v1.ListOptions.
|
||||
type TweakListOptionsFunc func(*v1.ListOptions)
|
||||
|
@@ -27,6 +27,7 @@ import (
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// NewInformerFunc takes internalclientset.Interface and time.Duration to return a SharedIndexInformer.
|
||||
type NewInformerFunc func(internalclientset.Interface, time.Duration) cache.SharedIndexInformer
|
||||
|
||||
// SharedInformerFactory a small interface to allow for adding an informer without an import cycle
|
||||
@@ -35,4 +36,5 @@ type SharedInformerFactory interface {
|
||||
InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
|
||||
}
|
||||
|
||||
// TweakListOptionsFunc is a function that transforms a v1.ListOptions.
|
||||
type TweakListOptionsFunc func(*v1.ListOptions)
|
||||
|
11
vendor/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go
generated
vendored
11
vendor/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go
generated
vendored
@@ -40,6 +40,12 @@ const (
|
||||
//
|
||||
// CustomResourceSubresources defines the subresources for CustomResources
|
||||
CustomResourceSubresources utilfeature.Feature = "CustomResourceSubresources"
|
||||
|
||||
// owner: @mbohlool
|
||||
// alpha: v1.13
|
||||
//
|
||||
// CustomResourceWebhookConversion defines the webhook conversion for Custom Resources.
|
||||
CustomResourceWebhookConversion utilfeature.Feature = "CustomResourceWebhookConversion"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -50,6 +56,7 @@ func init() {
|
||||
// To add a new feature, define a key for it above and add it here. The features will be
|
||||
// available throughout Kubernetes binaries.
|
||||
var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureSpec{
|
||||
CustomResourceValidation: {Default: true, PreRelease: utilfeature.Beta},
|
||||
CustomResourceSubresources: {Default: true, PreRelease: utilfeature.Beta},
|
||||
CustomResourceValidation: {Default: true, PreRelease: utilfeature.Beta},
|
||||
CustomResourceSubresources: {Default: true, PreRelease: utilfeature.Beta},
|
||||
CustomResourceWebhookConversion: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
}
|
||||
|
13
vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd.go
generated
vendored
13
vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd.go
generated
vendored
@@ -40,8 +40,8 @@ type CustomResourceStorage struct {
|
||||
Scale *ScaleREST
|
||||
}
|
||||
|
||||
func NewStorage(resource schema.GroupResource, listKind schema.GroupVersionKind, strategy customResourceStrategy, optsGetter generic.RESTOptionsGetter, categories []string, tableConvertor rest.TableConvertor) CustomResourceStorage {
|
||||
customResourceREST, customResourceStatusREST := newREST(resource, listKind, strategy, optsGetter, categories, tableConvertor)
|
||||
func NewStorage(resource schema.GroupResource, kind, listKind schema.GroupVersionKind, strategy customResourceStrategy, optsGetter generic.RESTOptionsGetter, categories []string, tableConvertor rest.TableConvertor) CustomResourceStorage {
|
||||
customResourceREST, customResourceStatusREST := newREST(resource, kind, listKind, strategy, optsGetter, categories, tableConvertor)
|
||||
|
||||
s := CustomResourceStorage{
|
||||
CustomResource: customResourceREST,
|
||||
@@ -75,9 +75,14 @@ type REST struct {
|
||||
}
|
||||
|
||||
// newREST returns a RESTStorage object that will work against API services.
|
||||
func newREST(resource schema.GroupResource, listKind schema.GroupVersionKind, strategy customResourceStrategy, optsGetter generic.RESTOptionsGetter, categories []string, tableConvertor rest.TableConvertor) (*REST, *StatusREST) {
|
||||
func newREST(resource schema.GroupResource, kind, listKind schema.GroupVersionKind, strategy customResourceStrategy, optsGetter generic.RESTOptionsGetter, categories []string, tableConvertor rest.TableConvertor) (*REST, *StatusREST) {
|
||||
store := &genericregistry.Store{
|
||||
NewFunc: func() runtime.Object { return &unstructured.Unstructured{} },
|
||||
NewFunc: func() runtime.Object {
|
||||
// set the expected group/version/kind in the new object as a signal to the versioning decoder
|
||||
ret := &unstructured.Unstructured{}
|
||||
ret.SetGroupVersionKind(kind)
|
||||
return ret
|
||||
},
|
||||
NewListFunc: func() runtime.Object {
|
||||
// lists are never stored, only manufactured, so stomp in the right kind
|
||||
ret := &unstructured.UnstructuredList{}
|
||||
|
1
vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd_test.go
generated
vendored
1
vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd_test.go
generated
vendored
@@ -91,6 +91,7 @@ func newStorage(t *testing.T) (customresource.CustomResourceStorage, *etcdtestin
|
||||
|
||||
storage := customresource.NewStorage(
|
||||
schema.GroupResource{Group: "mygroup.example.com", Resource: "noxus"},
|
||||
kind,
|
||||
schema.GroupVersionKind{Group: "mygroup.example.com", Version: "v1beta1", Kind: "NoxuItemList"},
|
||||
customresource.NewStrategy(
|
||||
typer,
|
||||
|
51
vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy.go
generated
vendored
51
vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy.go
generated
vendored
@@ -87,45 +87,46 @@ func (a customResourceStrategy) PrepareForCreate(ctx context.Context, obj runtim
|
||||
|
||||
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
|
||||
func (a customResourceStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) || a.status == nil {
|
||||
return
|
||||
}
|
||||
|
||||
newCustomResourceObject := obj.(*unstructured.Unstructured)
|
||||
oldCustomResourceObject := old.(*unstructured.Unstructured)
|
||||
|
||||
newCustomResource := newCustomResourceObject.UnstructuredContent()
|
||||
oldCustomResource := oldCustomResourceObject.UnstructuredContent()
|
||||
|
||||
// update is not allowed to set status
|
||||
_, ok1 := newCustomResource["status"]
|
||||
_, ok2 := oldCustomResource["status"]
|
||||
switch {
|
||||
case ok2:
|
||||
newCustomResource["status"] = oldCustomResource["status"]
|
||||
case ok1:
|
||||
delete(newCustomResource, "status")
|
||||
// If the /status subresource endpoint is installed, update is not allowed to set status.
|
||||
if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && a.status != nil {
|
||||
_, ok1 := newCustomResource["status"]
|
||||
_, ok2 := oldCustomResource["status"]
|
||||
switch {
|
||||
case ok2:
|
||||
newCustomResource["status"] = oldCustomResource["status"]
|
||||
case ok1:
|
||||
delete(newCustomResource, "status")
|
||||
}
|
||||
}
|
||||
|
||||
// Any changes to the spec increment the generation number, any changes to the
|
||||
// status should reflect the generation number of the corresponding object. We push
|
||||
// the burden of managing the status onto the clients because we can't (in general)
|
||||
// know here what version of spec the writer of the status has seen. It may seem like
|
||||
// we can at first -- since obj contains spec -- but in the future we will probably make
|
||||
// status its own object, and even if we don't, writes may be the result of a
|
||||
// read-update-write loop, so the contents of spec may not actually be the spec that
|
||||
// the CustomResource has *seen*.
|
||||
newSpec, ok1 := newCustomResource["spec"]
|
||||
oldSpec, ok2 := oldCustomResource["spec"]
|
||||
|
||||
// spec is changed, created or deleted
|
||||
if (ok1 && ok2 && !apiequality.Semantic.DeepEqual(oldSpec, newSpec)) || (ok1 && !ok2) || (!ok1 && ok2) {
|
||||
// except for the changes to `metadata`, any other changes
|
||||
// cause the generation to increment.
|
||||
newCopyContent := copyNonMetadata(newCustomResource)
|
||||
oldCopyContent := copyNonMetadata(oldCustomResource)
|
||||
if !apiequality.Semantic.DeepEqual(newCopyContent, oldCopyContent) {
|
||||
oldAccessor, _ := meta.Accessor(oldCustomResourceObject)
|
||||
newAccessor, _ := meta.Accessor(newCustomResourceObject)
|
||||
newAccessor.SetGeneration(oldAccessor.GetGeneration() + 1)
|
||||
}
|
||||
}
|
||||
|
||||
func copyNonMetadata(original map[string]interface{}) map[string]interface{} {
|
||||
ret := make(map[string]interface{})
|
||||
for key, val := range original {
|
||||
if key == "metadata" {
|
||||
continue
|
||||
}
|
||||
ret[key] = val
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Validate validates a new CustomResource.
|
||||
func (a customResourceStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
|
||||
return a.validator.Validate(ctx, obj, a.scale)
|
||||
|
257
vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy_test.go
generated
vendored
Normal file
257
vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy_test.go
generated
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
Copyright 2018 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 customresource
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
func generation1() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"generation": int64(1),
|
||||
}
|
||||
}
|
||||
|
||||
func generation2() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"generation": int64(2),
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrategyPrepareForUpdate(t *testing.T) {
|
||||
strategy := customResourceStrategy{}
|
||||
tcs := []struct {
|
||||
name string
|
||||
old *unstructured.Unstructured
|
||||
obj *unstructured.Unstructured
|
||||
statusEnabled bool
|
||||
expected *unstructured.Unstructured
|
||||
}{
|
||||
{
|
||||
name: "/status is enabled, spec changes increment generation",
|
||||
statusEnabled: true,
|
||||
old: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": generation1(),
|
||||
"spec": "old",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
obj: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": generation1(),
|
||||
"spec": "new",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
expected: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": generation2(),
|
||||
"spec": "new",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "/status is enabled, status changes do not increment generation, status changes removed",
|
||||
statusEnabled: true,
|
||||
old: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": generation1(),
|
||||
"spec": "old",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
obj: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": generation1(),
|
||||
"spec": "old",
|
||||
"status": "new",
|
||||
},
|
||||
},
|
||||
expected: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": generation1(),
|
||||
"spec": "old",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "/status is enabled, metadata changes do not increment generation",
|
||||
statusEnabled: true,
|
||||
old: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": map[string]interface{}{
|
||||
"generation": int64(1),
|
||||
"other": "old",
|
||||
},
|
||||
"spec": "old",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
obj: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": map[string]interface{}{
|
||||
"generation": int64(1),
|
||||
"other": "new",
|
||||
},
|
||||
"spec": "old",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
expected: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": map[string]interface{}{
|
||||
"generation": int64(1),
|
||||
"other": "new",
|
||||
},
|
||||
"spec": "old",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "/status is disabled, spec changes increment generation",
|
||||
statusEnabled: false,
|
||||
old: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": generation1(),
|
||||
"spec": "old",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
obj: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": generation1(),
|
||||
"spec": "new",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
expected: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": generation2(),
|
||||
"spec": "new",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "/status is disabled, status changes increment generation",
|
||||
statusEnabled: false,
|
||||
old: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": generation1(),
|
||||
"spec": "old",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
obj: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": generation1(),
|
||||
"spec": "old",
|
||||
"status": "new",
|
||||
},
|
||||
},
|
||||
expected: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": generation2(),
|
||||
"spec": "old",
|
||||
"status": "new",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "/status is disabled, other top-level field changes increment generation",
|
||||
statusEnabled: false,
|
||||
old: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": generation1(),
|
||||
"spec": "old",
|
||||
"image": "old",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
obj: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": generation1(),
|
||||
"spec": "old",
|
||||
"image": "new",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
expected: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": generation2(),
|
||||
"spec": "old",
|
||||
"image": "new",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "/status is disabled, metadata changes do not increment generation",
|
||||
statusEnabled: false,
|
||||
old: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": map[string]interface{}{
|
||||
"generation": int64(1),
|
||||
"other": "old",
|
||||
},
|
||||
"spec": "old",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
obj: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": map[string]interface{}{
|
||||
"generation": int64(1),
|
||||
"other": "new",
|
||||
},
|
||||
"spec": "old",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
expected: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"metadata": map[string]interface{}{
|
||||
"generation": int64(1),
|
||||
"other": "new",
|
||||
},
|
||||
"spec": "old",
|
||||
"status": "old",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
if tc.statusEnabled {
|
||||
strategy.status = &apiextensions.CustomResourceSubresourceStatus{}
|
||||
} else {
|
||||
strategy.status = nil
|
||||
}
|
||||
strategy.PrepareForUpdate(context.TODO(), tc.obj, tc.old)
|
||||
if !reflect.DeepEqual(tc.obj, tc.expected) {
|
||||
t.Errorf("test %q failed: expected: %v, got %v", tc.name, tc.expected, tc.obj)
|
||||
}
|
||||
}
|
||||
}
|
15
vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go
generated
vendored
15
vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go
generated
vendored
@@ -20,6 +20,9 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation"
|
||||
apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features"
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
@@ -29,10 +32,6 @@ import (
|
||||
"k8s.io/apiserver/pkg/storage"
|
||||
"k8s.io/apiserver/pkg/storage/names"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation"
|
||||
apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features"
|
||||
)
|
||||
|
||||
// strategy implements behavior for CustomResources.
|
||||
@@ -62,6 +61,9 @@ func (strategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) {
|
||||
crd.Spec.Subresources = nil
|
||||
}
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) && crd.Spec.Conversion != nil {
|
||||
crd.Spec.Conversion.WebhookClientConfig = nil
|
||||
}
|
||||
|
||||
for _, v := range crd.Spec.Versions {
|
||||
if v.Storage {
|
||||
@@ -99,6 +101,11 @@ func (strategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
|
||||
newCRD.Spec.Subresources = nil
|
||||
oldCRD.Spec.Subresources = nil
|
||||
}
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceWebhookConversion) && newCRD.Spec.Conversion != nil {
|
||||
if oldCRD.Spec.Conversion == nil || newCRD.Spec.Conversion.WebhookClientConfig == nil {
|
||||
newCRD.Spec.Conversion.WebhookClientConfig = nil
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range newCRD.Spec.Versions {
|
||||
if v.Storage {
|
||||
|
4
vendor/k8s.io/apiextensions-apiserver/test/integration/subresources_test.go
generated
vendored
4
vendor/k8s.io/apiextensions-apiserver/test/integration/subresources_test.go
generated
vendored
@@ -51,6 +51,10 @@ func NewNoxuSubresourcesCRD(scope apiextensionsv1beta1.ResourceScope) *apiextens
|
||||
ShortNames: []string{"foo", "bar", "abc", "def"},
|
||||
ListKind: "NoxuItemList",
|
||||
},
|
||||
Versions: []apiextensionsv1beta1.CustomResourceDefinitionVersion{
|
||||
{Name: "v1beta1", Served: true, Storage: false},
|
||||
{Name: "v1", Served: true, Storage: true},
|
||||
},
|
||||
Scope: scope,
|
||||
Subresources: &apiextensionsv1beta1.CustomResourceSubresources{
|
||||
Status: &apiextensionsv1beta1.CustomResourceSubresourceStatus{},
|
||||
|
102
vendor/k8s.io/apiextensions-apiserver/test/integration/versioning_test.go
generated
vendored
102
vendor/k8s.io/apiextensions-apiserver/test/integration/versioning_test.go
generated
vendored
@@ -17,14 +17,116 @@ limitations under the License.
|
||||
package integration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
|
||||
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
"k8s.io/apiextensions-apiserver/test/integration/fixtures"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestInternalVersionIsHandlerVersion(t *testing.T) {
|
||||
tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer tearDown()
|
||||
|
||||
noxuDefinition := fixtures.NewMultipleVersionNoxuCRD(apiextensionsv1beta1.NamespaceScoped)
|
||||
|
||||
assert.Equal(t, "v1beta1", noxuDefinition.Spec.Versions[0].Name)
|
||||
assert.Equal(t, "v1beta2", noxuDefinition.Spec.Versions[1].Name)
|
||||
assert.True(t, noxuDefinition.Spec.Versions[1].Storage)
|
||||
|
||||
noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ns := "not-the-default"
|
||||
|
||||
noxuNamespacedResourceClientV1beta1 := newNamespacedCustomResourceVersionedClient(ns, dynamicClient, noxuDefinition, "v1beta1") // use the non-storage version v1beta1
|
||||
|
||||
t.Logf("Creating foo")
|
||||
noxuInstanceToCreate := fixtures.NewNoxuInstance(ns, "foo")
|
||||
_, err = noxuNamespacedResourceClientV1beta1.Create(noxuInstanceToCreate, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// update validation via update because the cache priming in CreateNewCustomResourceDefinition will fail otherwise
|
||||
t.Logf("Updating CRD to validate apiVersion")
|
||||
noxuDefinition, err = updateCustomResourceDefinitionWithRetry(apiExtensionClient, noxuDefinition.Name, func(crd *apiextensionsv1beta1.CustomResourceDefinition) {
|
||||
crd.Spec.Validation = &apiextensionsv1beta1.CustomResourceValidation{
|
||||
OpenAPIV3Schema: &apiextensionsv1beta1.JSONSchemaProps{
|
||||
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
|
||||
"apiVersion": {
|
||||
Pattern: "^mygroup.example.com/v1beta1$", // this means we can only patch via the v1beta1 handler version
|
||||
},
|
||||
},
|
||||
Required: []string{"apiVersion"},
|
||||
},
|
||||
}
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
time.Sleep(time.Second)
|
||||
|
||||
// patches via handler version v1beta1 should succeed (validation allows that API version)
|
||||
{
|
||||
t.Logf("patch of handler version v1beta1 (non-storage version) should succeed")
|
||||
i := 0
|
||||
err = wait.PollImmediate(time.Millisecond*100, wait.ForeverTestTimeout, func() (bool, error) {
|
||||
patch := []byte(fmt.Sprintf(`{"i": %d}`, i))
|
||||
i++
|
||||
|
||||
_, err := noxuNamespacedResourceClientV1beta1.Patch("foo", types.MergePatchType, patch, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
// work around "grpc: the client connection is closing" error
|
||||
// TODO: fix the grpc error
|
||||
if err, ok := err.(*errors.StatusError); ok && err.Status().Code == http.StatusInternalServerError {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
// patches via handler version matching storage version should fail (validation does not allow that API version)
|
||||
{
|
||||
t.Logf("patch of handler version v1beta2 (storage version) should fail")
|
||||
i := 0
|
||||
noxuNamespacedResourceClientV1beta2 := newNamespacedCustomResourceVersionedClient(ns, dynamicClient, noxuDefinition, "v1beta2") // use the storage version v1beta2
|
||||
err = wait.PollImmediate(time.Millisecond*100, wait.ForeverTestTimeout, func() (bool, error) {
|
||||
patch := []byte(fmt.Sprintf(`{"i": %d}`, i))
|
||||
i++
|
||||
|
||||
_, err := noxuNamespacedResourceClientV1beta2.Patch("foo", types.MergePatchType, patch, metav1.UpdateOptions{})
|
||||
assert.NotNil(t, err)
|
||||
|
||||
// work around "grpc: the client connection is closing" error
|
||||
// TODO: fix the grpc error
|
||||
if err, ok := err.(*errors.StatusError); ok && err.Status().Code == http.StatusInternalServerError {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
assert.Contains(t, err.Error(), "apiVersion")
|
||||
return true, nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersionedNamspacedScopedCRD(t *testing.T) {
|
||||
tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user