diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 150400f5efd..7890c978c86 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -13154,398 +13154,6 @@ "type": "object", "x-kubernetes-map-type": "atomic" }, - "io.k8s.api.rbac.v1alpha1.AggregationRule": { - "description": "AggregationRule describes how to locate ClusterRoles to aggregate into the ClusterRole", - "properties": { - "clusterRoleSelectors": { - "description": "ClusterRoleSelectors holds a list of selectors which will be used to find ClusterRoles and create the rules. If any of the selectors match, then the ClusterRole's permissions will be added", - "items": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector" - }, - "type": "array" - } - }, - "type": "object" - }, - "io.k8s.api.rbac.v1alpha1.ClusterRole": { - "description": "ClusterRole is a cluster level, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding or ClusterRoleBinding. Deprecated in v1.17 in favor of rbac.authorization.k8s.io/v1 ClusterRole, and will no longer be served in v1.22.", - "properties": { - "aggregationRule": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.AggregationRule", - "description": "AggregationRule is an optional field that describes how to build the Rules for this ClusterRole. If AggregationRule is set, then the Rules are controller managed and direct changes to Rules will be stomped by the controller." - }, - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta", - "description": "Standard object's metadata." - }, - "rules": { - "description": "Rules holds all the PolicyRules for this ClusterRole", - "items": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.PolicyRule" - }, - "type": "array" - } - }, - "type": "object", - "x-kubernetes-group-version-kind": [ - { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRole", - "version": "v1alpha1" - } - ] - }, - "io.k8s.api.rbac.v1alpha1.ClusterRoleBinding": { - "description": "ClusterRoleBinding references a ClusterRole, but not contain it. It can reference a ClusterRole in the global namespace, and adds who information via Subject. Deprecated in v1.17 in favor of rbac.authorization.k8s.io/v1 ClusterRoleBinding, and will no longer be served in v1.22.", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta", - "description": "Standard object's metadata." - }, - "roleRef": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.RoleRef", - "description": "RoleRef can only reference a ClusterRole in the global namespace. If the RoleRef cannot be resolved, the Authorizer must return an error." - }, - "subjects": { - "description": "Subjects holds references to the objects the role applies to.", - "items": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.Subject" - }, - "type": "array" - } - }, - "required": [ - "roleRef" - ], - "type": "object", - "x-kubernetes-group-version-kind": [ - { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRoleBinding", - "version": "v1alpha1" - } - ] - }, - "io.k8s.api.rbac.v1alpha1.ClusterRoleBindingList": { - "description": "ClusterRoleBindingList is a collection of ClusterRoleBindings. Deprecated in v1.17 in favor of rbac.authorization.k8s.io/v1 ClusterRoleBindings, and will no longer be served in v1.22.", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "items": { - "description": "Items is a list of ClusterRoleBindings", - "items": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRoleBinding" - }, - "type": "array" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta", - "description": "Standard object's metadata." - } - }, - "required": [ - "items" - ], - "type": "object", - "x-kubernetes-group-version-kind": [ - { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRoleBindingList", - "version": "v1alpha1" - } - ] - }, - "io.k8s.api.rbac.v1alpha1.ClusterRoleList": { - "description": "ClusterRoleList is a collection of ClusterRoles. Deprecated in v1.17 in favor of rbac.authorization.k8s.io/v1 ClusterRoles, and will no longer be served in v1.22.", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "items": { - "description": "Items is a list of ClusterRoles", - "items": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRole" - }, - "type": "array" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta", - "description": "Standard object's metadata." - } - }, - "required": [ - "items" - ], - "type": "object", - "x-kubernetes-group-version-kind": [ - { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRoleList", - "version": "v1alpha1" - } - ] - }, - "io.k8s.api.rbac.v1alpha1.PolicyRule": { - "description": "PolicyRule holds information that describes a policy rule, but does not contain information about who the rule applies to or which namespace the rule applies to.", - "properties": { - "apiGroups": { - "description": "APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed.", - "items": { - "type": "string" - }, - "type": "array" - }, - "nonResourceURLs": { - "description": "NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding. Rules can either apply to API resources (such as \"pods\" or \"secrets\") or non-resource URL paths (such as \"/api\"), but not both.", - "items": { - "type": "string" - }, - "type": "array" - }, - "resourceNames": { - "description": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.", - "items": { - "type": "string" - }, - "type": "array" - }, - "resources": { - "description": "Resources is a list of resources this rule applies to. '*' represents all resources.", - "items": { - "type": "string" - }, - "type": "array" - }, - "verbs": { - "description": "Verbs is a list of Verbs that apply to ALL the ResourceKinds and AttributeRestrictions contained in this rule. '*' represents all verbs.", - "items": { - "type": "string" - }, - "type": "array" - } - }, - "required": [ - "verbs" - ], - "type": "object" - }, - "io.k8s.api.rbac.v1alpha1.Role": { - "description": "Role is a namespaced, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding. Deprecated in v1.17 in favor of rbac.authorization.k8s.io/v1 Role, and will no longer be served in v1.22.", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta", - "description": "Standard object's metadata." - }, - "rules": { - "description": "Rules holds all the PolicyRules for this Role", - "items": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.PolicyRule" - }, - "type": "array" - } - }, - "type": "object", - "x-kubernetes-group-version-kind": [ - { - "group": "rbac.authorization.k8s.io", - "kind": "Role", - "version": "v1alpha1" - } - ] - }, - "io.k8s.api.rbac.v1alpha1.RoleBinding": { - "description": "RoleBinding references a role, but does not contain it. It can reference a Role in the same namespace or a ClusterRole in the global namespace. It adds who information via Subjects and namespace information by which namespace it exists in. RoleBindings in a given namespace only have effect in that namespace. Deprecated in v1.17 in favor of rbac.authorization.k8s.io/v1 RoleBinding, and will no longer be served in v1.22.", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta", - "description": "Standard object's metadata." - }, - "roleRef": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.RoleRef", - "description": "RoleRef can reference a Role in the current namespace or a ClusterRole in the global namespace. If the RoleRef cannot be resolved, the Authorizer must return an error." - }, - "subjects": { - "description": "Subjects holds references to the objects the role applies to.", - "items": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.Subject" - }, - "type": "array" - } - }, - "required": [ - "roleRef" - ], - "type": "object", - "x-kubernetes-group-version-kind": [ - { - "group": "rbac.authorization.k8s.io", - "kind": "RoleBinding", - "version": "v1alpha1" - } - ] - }, - "io.k8s.api.rbac.v1alpha1.RoleBindingList": { - "description": "RoleBindingList is a collection of RoleBindings Deprecated in v1.17 in favor of rbac.authorization.k8s.io/v1 RoleBindingList, and will no longer be served in v1.22.", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "items": { - "description": "Items is a list of RoleBindings", - "items": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.RoleBinding" - }, - "type": "array" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta", - "description": "Standard object's metadata." - } - }, - "required": [ - "items" - ], - "type": "object", - "x-kubernetes-group-version-kind": [ - { - "group": "rbac.authorization.k8s.io", - "kind": "RoleBindingList", - "version": "v1alpha1" - } - ] - }, - "io.k8s.api.rbac.v1alpha1.RoleList": { - "description": "RoleList is a collection of Roles. Deprecated in v1.17 in favor of rbac.authorization.k8s.io/v1 RoleList, and will no longer be served in v1.22.", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "items": { - "description": "Items is a list of Roles", - "items": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.Role" - }, - "type": "array" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta", - "description": "Standard object's metadata." - } - }, - "required": [ - "items" - ], - "type": "object", - "x-kubernetes-group-version-kind": [ - { - "group": "rbac.authorization.k8s.io", - "kind": "RoleList", - "version": "v1alpha1" - } - ] - }, - "io.k8s.api.rbac.v1alpha1.RoleRef": { - "description": "RoleRef contains information that points to the role being used", - "properties": { - "apiGroup": { - "description": "APIGroup is the group for the resource being referenced", - "type": "string" - }, - "kind": { - "description": "Kind is the type of resource being referenced", - "type": "string" - }, - "name": { - "description": "Name is the name of resource being referenced", - "type": "string" - } - }, - "required": [ - "apiGroup", - "kind", - "name" - ], - "type": "object" - }, - "io.k8s.api.rbac.v1alpha1.Subject": { - "description": "Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names.", - "properties": { - "apiVersion": { - "description": "APIVersion holds the API group and version of the referenced subject. Defaults to \"v1\" for ServiceAccount subjects. Defaults to \"rbac.authorization.k8s.io/v1alpha1\" for User and Group subjects.", - "type": "string" - }, - "kind": { - "description": "Kind of object being referenced. Values defined by this API group are \"User\", \"Group\", and \"ServiceAccount\". If the Authorizer does not recognized the kind value, the Authorizer should report an error.", - "type": "string" - }, - "name": { - "description": "Name of the object being referenced.", - "type": "string" - }, - "namespace": { - "description": "Namespace of the referenced object. If the object kind is non-namespace, such as \"User\" or \"Group\", and this value is not empty the Authorizer should report an error.", - "type": "string" - } - }, - "required": [ - "kind", - "name" - ], - "type": "object" - }, "io.k8s.api.scheduling.v1.PriorityClass": { "description": "PriorityClass defines mapping from a priority class name to the priority integer value. The value can be any valid integer.", "properties": { @@ -13626,86 +13234,6 @@ } ] }, - "io.k8s.api.scheduling.v1alpha1.PriorityClass": { - "description": "DEPRECATED - This group version of PriorityClass is deprecated by scheduling.k8s.io/v1/PriorityClass. PriorityClass defines mapping from a priority class name to the priority integer value. The value can be any valid integer.", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "description": { - "description": "description is an arbitrary string that usually provides guidelines on when this priority class should be used.", - "type": "string" - }, - "globalDefault": { - "description": "globalDefault specifies whether this PriorityClass should be considered as the default priority for pods that do not have any priority class. Only one PriorityClass can be marked as `globalDefault`. However, if more than one PriorityClasses exists with their `globalDefault` field set to true, the smallest value of such global default PriorityClasses will be used as the default priority.", - "type": "boolean" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta", - "description": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" - }, - "preemptionPolicy": { - "description": "PreemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset. This field is beta-level, gated by the NonPreemptingPriority feature-gate.", - "type": "string" - }, - "value": { - "description": "The value of this priority class. This is the actual priority that pods receive when they have the name of this class in their pod spec.", - "format": "int32", - "type": "integer" - } - }, - "required": [ - "value" - ], - "type": "object", - "x-kubernetes-group-version-kind": [ - { - "group": "scheduling.k8s.io", - "kind": "PriorityClass", - "version": "v1alpha1" - } - ] - }, - "io.k8s.api.scheduling.v1alpha1.PriorityClassList": { - "description": "PriorityClassList is a collection of priority classes.", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "items": { - "description": "items is the list of PriorityClasses", - "items": { - "$ref": "#/definitions/io.k8s.api.scheduling.v1alpha1.PriorityClass" - }, - "type": "array" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta", - "description": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" - } - }, - "required": [ - "items" - ], - "type": "object", - "x-kubernetes-group-version-kind": [ - { - "group": "scheduling.k8s.io", - "kind": "PriorityClassList", - "version": "v1alpha1" - } - ] - }, "io.k8s.api.storage.v1.CSIDriver": { "description": "CSIDriver captures information about a Container Storage Interface (CSI) volume driver deployed on the cluster. Kubernetes attach detach controller uses this object to determine whether attach is required. Kubelet uses this object to determine whether pod information needs to be passed on mount. CSIDriver objects are non-namespaced.", "properties": { @@ -14292,156 +13820,6 @@ } ] }, - "io.k8s.api.storage.v1alpha1.VolumeAttachment": { - "description": "VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.\n\nVolumeAttachment objects are non-namespaced.", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta", - "description": "Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" - }, - "spec": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeAttachmentSpec", - "description": "Specification of the desired attach/detach volume behavior. Populated by the Kubernetes system." - }, - "status": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeAttachmentStatus", - "description": "Status of the VolumeAttachment request. Populated by the entity completing the attach or detach operation, i.e. the external-attacher." - } - }, - "required": [ - "spec" - ], - "type": "object", - "x-kubernetes-group-version-kind": [ - { - "group": "storage.k8s.io", - "kind": "VolumeAttachment", - "version": "v1alpha1" - } - ] - }, - "io.k8s.api.storage.v1alpha1.VolumeAttachmentList": { - "description": "VolumeAttachmentList is a collection of VolumeAttachment objects.", - "properties": { - "apiVersion": { - "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - "type": "string" - }, - "items": { - "description": "Items is the list of VolumeAttachments", - "items": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeAttachment" - }, - "type": "array" - }, - "kind": { - "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta", - "description": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" - } - }, - "required": [ - "items" - ], - "type": "object", - "x-kubernetes-group-version-kind": [ - { - "group": "storage.k8s.io", - "kind": "VolumeAttachmentList", - "version": "v1alpha1" - } - ] - }, - "io.k8s.api.storage.v1alpha1.VolumeAttachmentSource": { - "description": "VolumeAttachmentSource represents a volume that should be attached. Right now only PersistenVolumes can be attached via external attacher, in future we may allow also inline volumes in pods. Exactly one member can be set.", - "properties": { - "inlineVolumeSpec": { - "$ref": "#/definitions/io.k8s.api.core.v1.PersistentVolumeSpec", - "description": "inlineVolumeSpec contains all the information necessary to attach a persistent volume defined by a pod's inline VolumeSource. This field is populated only for the CSIMigration feature. It contains translated fields from a pod's inline VolumeSource to a PersistentVolumeSpec. This field is alpha-level and is only honored by servers that enabled the CSIMigration feature." - }, - "persistentVolumeName": { - "description": "Name of the persistent volume to attach.", - "type": "string" - } - }, - "type": "object" - }, - "io.k8s.api.storage.v1alpha1.VolumeAttachmentSpec": { - "description": "VolumeAttachmentSpec is the specification of a VolumeAttachment request.", - "properties": { - "attacher": { - "description": "Attacher indicates the name of the volume driver that MUST handle this request. This is the name returned by GetPluginName().", - "type": "string" - }, - "nodeName": { - "description": "The node that the volume should be attached to.", - "type": "string" - }, - "source": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeAttachmentSource", - "description": "Source represents the volume that should be attached." - } - }, - "required": [ - "attacher", - "source", - "nodeName" - ], - "type": "object" - }, - "io.k8s.api.storage.v1alpha1.VolumeAttachmentStatus": { - "description": "VolumeAttachmentStatus is the status of a VolumeAttachment request.", - "properties": { - "attachError": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeError", - "description": "The last error encountered during attach operation, if any. This field must only be set by the entity completing the attach operation, i.e. the external-attacher." - }, - "attached": { - "description": "Indicates the volume is successfully attached. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "type": "boolean" - }, - "attachmentMetadata": { - "additionalProperties": { - "type": "string" - }, - "description": "Upon successful attach, this field is populated with any information returned by the attach operation that must be passed into subsequent WaitForAttach or Mount calls. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "type": "object" - }, - "detachError": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeError", - "description": "The last error encountered during detach operation, if any. This field must only be set by the entity completing the detach operation, i.e. the external-attacher." - } - }, - "required": [ - "attached" - ], - "type": "object" - }, - "io.k8s.api.storage.v1alpha1.VolumeError": { - "description": "VolumeError captures an error encountered during a volume operation.", - "properties": { - "message": { - "description": "String detailing the error encountered during Attach or Detach operation. This string maybe logged, so it should not contain sensitive information.", - "type": "string" - }, - "time": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Time", - "description": "Time the error was encountered." - } - }, - "type": "object" - }, "io.k8s.api.storage.v1beta1.CSIStorageCapacity": { "description": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler if the CSIStorageCapacity beta feature gate is enabled there and a CSI driver opts into capacity-aware scheduling with CSIDriver.StorageCapacity.", "properties": { @@ -78194,3775 +77572,6 @@ } ] }, - "/apis/rbac.authorization.k8s.io/v1alpha1/": { - "get": { - "consumes": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "description": "get available resources", - "operationId": "getRbacAuthorizationV1alpha1APIResources", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.APIResourceList" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ] - } - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/clusterrolebindings": { - "delete": { - "consumes": [ - "*/*" - ], - "description": "delete collection of ClusterRoleBinding", - "operationId": "deleteRbacAuthorizationV1alpha1CollectionClusterRoleBinding", - "parameters": [ - { - "in": "body", - "name": "body", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" - } - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", - "in": "query", - "name": "gracePeriodSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", - "in": "query", - "name": "orphanDependents", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", - "in": "query", - "name": "propagationPolicy", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "deletecollection", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRoleBinding", - "version": "v1alpha1" - } - }, - "get": { - "consumes": [ - "*/*" - ], - "description": "list or watch objects of kind ClusterRoleBinding", - "operationId": "listRbacAuthorizationV1alpha1ClusterRoleBinding", - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRoleBindingList" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "list", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRoleBinding", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - } - ], - "post": { - "consumes": [ - "*/*" - ], - "description": "create a ClusterRoleBinding", - "operationId": "createRbacAuthorizationV1alpha1ClusterRoleBinding", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRoleBinding" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRoleBinding" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRoleBinding" - } - }, - "202": { - "description": "Accepted", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRoleBinding" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "post", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRoleBinding", - "version": "v1alpha1" - } - } - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/clusterrolebindings/{name}": { - "delete": { - "consumes": [ - "*/*" - ], - "description": "delete a ClusterRoleBinding", - "operationId": "deleteRbacAuthorizationV1alpha1ClusterRoleBinding", - "parameters": [ - { - "in": "body", - "name": "body", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", - "in": "query", - "name": "gracePeriodSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", - "in": "query", - "name": "orphanDependents", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", - "in": "query", - "name": "propagationPolicy", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "202": { - "description": "Accepted", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "delete", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRoleBinding", - "version": "v1alpha1" - } - }, - "get": { - "consumes": [ - "*/*" - ], - "description": "read the specified ClusterRoleBinding", - "operationId": "readRbacAuthorizationV1alpha1ClusterRoleBinding", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRoleBinding" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "get", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRoleBinding", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "name of the ClusterRoleBinding", - "in": "path", - "name": "name", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - } - ], - "patch": { - "consumes": [ - "application/json-patch+json", - "application/merge-patch+json", - "application/strategic-merge-patch+json", - "application/apply-patch+yaml" - ], - "description": "partially update the specified ClusterRoleBinding", - "operationId": "patchRbacAuthorizationV1alpha1ClusterRoleBinding", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch).", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - }, - { - "description": "Force is going to \"force\" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests.", - "in": "query", - "name": "force", - "type": "boolean", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRoleBinding" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRoleBinding" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "patch", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRoleBinding", - "version": "v1alpha1" - } - }, - "put": { - "consumes": [ - "*/*" - ], - "description": "replace the specified ClusterRoleBinding", - "operationId": "replaceRbacAuthorizationV1alpha1ClusterRoleBinding", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRoleBinding" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRoleBinding" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRoleBinding" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "put", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRoleBinding", - "version": "v1alpha1" - } - } - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/clusterroles": { - "delete": { - "consumes": [ - "*/*" - ], - "description": "delete collection of ClusterRole", - "operationId": "deleteRbacAuthorizationV1alpha1CollectionClusterRole", - "parameters": [ - { - "in": "body", - "name": "body", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" - } - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", - "in": "query", - "name": "gracePeriodSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", - "in": "query", - "name": "orphanDependents", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", - "in": "query", - "name": "propagationPolicy", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "deletecollection", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRole", - "version": "v1alpha1" - } - }, - "get": { - "consumes": [ - "*/*" - ], - "description": "list or watch objects of kind ClusterRole", - "operationId": "listRbacAuthorizationV1alpha1ClusterRole", - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRoleList" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "list", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRole", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - } - ], - "post": { - "consumes": [ - "*/*" - ], - "description": "create a ClusterRole", - "operationId": "createRbacAuthorizationV1alpha1ClusterRole", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRole" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRole" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRole" - } - }, - "202": { - "description": "Accepted", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRole" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "post", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRole", - "version": "v1alpha1" - } - } - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/clusterroles/{name}": { - "delete": { - "consumes": [ - "*/*" - ], - "description": "delete a ClusterRole", - "operationId": "deleteRbacAuthorizationV1alpha1ClusterRole", - "parameters": [ - { - "in": "body", - "name": "body", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", - "in": "query", - "name": "gracePeriodSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", - "in": "query", - "name": "orphanDependents", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", - "in": "query", - "name": "propagationPolicy", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "202": { - "description": "Accepted", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "delete", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRole", - "version": "v1alpha1" - } - }, - "get": { - "consumes": [ - "*/*" - ], - "description": "read the specified ClusterRole", - "operationId": "readRbacAuthorizationV1alpha1ClusterRole", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRole" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "get", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRole", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "name of the ClusterRole", - "in": "path", - "name": "name", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - } - ], - "patch": { - "consumes": [ - "application/json-patch+json", - "application/merge-patch+json", - "application/strategic-merge-patch+json", - "application/apply-patch+yaml" - ], - "description": "partially update the specified ClusterRole", - "operationId": "patchRbacAuthorizationV1alpha1ClusterRole", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch).", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - }, - { - "description": "Force is going to \"force\" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests.", - "in": "query", - "name": "force", - "type": "boolean", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRole" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRole" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "patch", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRole", - "version": "v1alpha1" - } - }, - "put": { - "consumes": [ - "*/*" - ], - "description": "replace the specified ClusterRole", - "operationId": "replaceRbacAuthorizationV1alpha1ClusterRole", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRole" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRole" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.ClusterRole" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "put", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRole", - "version": "v1alpha1" - } - } - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/namespaces/{namespace}/rolebindings": { - "delete": { - "consumes": [ - "*/*" - ], - "description": "delete collection of RoleBinding", - "operationId": "deleteRbacAuthorizationV1alpha1CollectionNamespacedRoleBinding", - "parameters": [ - { - "in": "body", - "name": "body", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" - } - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", - "in": "query", - "name": "gracePeriodSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", - "in": "query", - "name": "orphanDependents", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", - "in": "query", - "name": "propagationPolicy", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "deletecollection", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "RoleBinding", - "version": "v1alpha1" - } - }, - "get": { - "consumes": [ - "*/*" - ], - "description": "list or watch objects of kind RoleBinding", - "operationId": "listRbacAuthorizationV1alpha1NamespacedRoleBinding", - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.RoleBindingList" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "list", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "RoleBinding", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "object name and auth scope, such as for teams and projects", - "in": "path", - "name": "namespace", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - } - ], - "post": { - "consumes": [ - "*/*" - ], - "description": "create a RoleBinding", - "operationId": "createRbacAuthorizationV1alpha1NamespacedRoleBinding", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.RoleBinding" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.RoleBinding" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.RoleBinding" - } - }, - "202": { - "description": "Accepted", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.RoleBinding" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "post", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "RoleBinding", - "version": "v1alpha1" - } - } - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/namespaces/{namespace}/rolebindings/{name}": { - "delete": { - "consumes": [ - "*/*" - ], - "description": "delete a RoleBinding", - "operationId": "deleteRbacAuthorizationV1alpha1NamespacedRoleBinding", - "parameters": [ - { - "in": "body", - "name": "body", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", - "in": "query", - "name": "gracePeriodSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", - "in": "query", - "name": "orphanDependents", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", - "in": "query", - "name": "propagationPolicy", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "202": { - "description": "Accepted", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "delete", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "RoleBinding", - "version": "v1alpha1" - } - }, - "get": { - "consumes": [ - "*/*" - ], - "description": "read the specified RoleBinding", - "operationId": "readRbacAuthorizationV1alpha1NamespacedRoleBinding", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.RoleBinding" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "get", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "RoleBinding", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "name of the RoleBinding", - "in": "path", - "name": "name", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "object name and auth scope, such as for teams and projects", - "in": "path", - "name": "namespace", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - } - ], - "patch": { - "consumes": [ - "application/json-patch+json", - "application/merge-patch+json", - "application/strategic-merge-patch+json", - "application/apply-patch+yaml" - ], - "description": "partially update the specified RoleBinding", - "operationId": "patchRbacAuthorizationV1alpha1NamespacedRoleBinding", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch).", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - }, - { - "description": "Force is going to \"force\" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests.", - "in": "query", - "name": "force", - "type": "boolean", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.RoleBinding" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.RoleBinding" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "patch", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "RoleBinding", - "version": "v1alpha1" - } - }, - "put": { - "consumes": [ - "*/*" - ], - "description": "replace the specified RoleBinding", - "operationId": "replaceRbacAuthorizationV1alpha1NamespacedRoleBinding", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.RoleBinding" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.RoleBinding" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.RoleBinding" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "put", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "RoleBinding", - "version": "v1alpha1" - } - } - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/namespaces/{namespace}/roles": { - "delete": { - "consumes": [ - "*/*" - ], - "description": "delete collection of Role", - "operationId": "deleteRbacAuthorizationV1alpha1CollectionNamespacedRole", - "parameters": [ - { - "in": "body", - "name": "body", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" - } - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", - "in": "query", - "name": "gracePeriodSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", - "in": "query", - "name": "orphanDependents", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", - "in": "query", - "name": "propagationPolicy", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "deletecollection", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "Role", - "version": "v1alpha1" - } - }, - "get": { - "consumes": [ - "*/*" - ], - "description": "list or watch objects of kind Role", - "operationId": "listRbacAuthorizationV1alpha1NamespacedRole", - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.RoleList" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "list", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "Role", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "object name and auth scope, such as for teams and projects", - "in": "path", - "name": "namespace", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - } - ], - "post": { - "consumes": [ - "*/*" - ], - "description": "create a Role", - "operationId": "createRbacAuthorizationV1alpha1NamespacedRole", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.Role" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.Role" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.Role" - } - }, - "202": { - "description": "Accepted", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.Role" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "post", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "Role", - "version": "v1alpha1" - } - } - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/namespaces/{namespace}/roles/{name}": { - "delete": { - "consumes": [ - "*/*" - ], - "description": "delete a Role", - "operationId": "deleteRbacAuthorizationV1alpha1NamespacedRole", - "parameters": [ - { - "in": "body", - "name": "body", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", - "in": "query", - "name": "gracePeriodSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", - "in": "query", - "name": "orphanDependents", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", - "in": "query", - "name": "propagationPolicy", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "202": { - "description": "Accepted", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "delete", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "Role", - "version": "v1alpha1" - } - }, - "get": { - "consumes": [ - "*/*" - ], - "description": "read the specified Role", - "operationId": "readRbacAuthorizationV1alpha1NamespacedRole", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.Role" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "get", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "Role", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "name of the Role", - "in": "path", - "name": "name", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "object name and auth scope, such as for teams and projects", - "in": "path", - "name": "namespace", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - } - ], - "patch": { - "consumes": [ - "application/json-patch+json", - "application/merge-patch+json", - "application/strategic-merge-patch+json", - "application/apply-patch+yaml" - ], - "description": "partially update the specified Role", - "operationId": "patchRbacAuthorizationV1alpha1NamespacedRole", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch).", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - }, - { - "description": "Force is going to \"force\" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests.", - "in": "query", - "name": "force", - "type": "boolean", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.Role" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.Role" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "patch", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "Role", - "version": "v1alpha1" - } - }, - "put": { - "consumes": [ - "*/*" - ], - "description": "replace the specified Role", - "operationId": "replaceRbacAuthorizationV1alpha1NamespacedRole", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.Role" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.Role" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.Role" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "put", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "Role", - "version": "v1alpha1" - } - } - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/rolebindings": { - "get": { - "consumes": [ - "*/*" - ], - "description": "list or watch objects of kind RoleBinding", - "operationId": "listRbacAuthorizationV1alpha1RoleBindingForAllNamespaces", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.RoleBindingList" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "list", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "RoleBinding", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ] - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/roles": { - "get": { - "consumes": [ - "*/*" - ], - "description": "list or watch objects of kind Role", - "operationId": "listRbacAuthorizationV1alpha1RoleForAllNamespaces", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.rbac.v1alpha1.RoleList" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "list", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "Role", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ] - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/watch/clusterrolebindings": { - "get": { - "consumes": [ - "*/*" - ], - "description": "watch individual changes to a list of ClusterRoleBinding. deprecated: use the 'watch' parameter with a list operation instead.", - "operationId": "watchRbacAuthorizationV1alpha1ClusterRoleBindingList", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "watchlist", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRoleBinding", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ] - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/watch/clusterrolebindings/{name}": { - "get": { - "consumes": [ - "*/*" - ], - "description": "watch changes to an object of kind ClusterRoleBinding. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", - "operationId": "watchRbacAuthorizationV1alpha1ClusterRoleBinding", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "watch", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRoleBinding", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "name of the ClusterRoleBinding", - "in": "path", - "name": "name", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ] - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/watch/clusterroles": { - "get": { - "consumes": [ - "*/*" - ], - "description": "watch individual changes to a list of ClusterRole. deprecated: use the 'watch' parameter with a list operation instead.", - "operationId": "watchRbacAuthorizationV1alpha1ClusterRoleList", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "watchlist", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRole", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ] - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/watch/clusterroles/{name}": { - "get": { - "consumes": [ - "*/*" - ], - "description": "watch changes to an object of kind ClusterRole. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", - "operationId": "watchRbacAuthorizationV1alpha1ClusterRole", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "watch", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "ClusterRole", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "name of the ClusterRole", - "in": "path", - "name": "name", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ] - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/watch/namespaces/{namespace}/rolebindings": { - "get": { - "consumes": [ - "*/*" - ], - "description": "watch individual changes to a list of RoleBinding. deprecated: use the 'watch' parameter with a list operation instead.", - "operationId": "watchRbacAuthorizationV1alpha1NamespacedRoleBindingList", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "watchlist", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "RoleBinding", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "object name and auth scope, such as for teams and projects", - "in": "path", - "name": "namespace", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ] - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/watch/namespaces/{namespace}/rolebindings/{name}": { - "get": { - "consumes": [ - "*/*" - ], - "description": "watch changes to an object of kind RoleBinding. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", - "operationId": "watchRbacAuthorizationV1alpha1NamespacedRoleBinding", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "watch", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "RoleBinding", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "name of the RoleBinding", - "in": "path", - "name": "name", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "object name and auth scope, such as for teams and projects", - "in": "path", - "name": "namespace", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ] - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/watch/namespaces/{namespace}/roles": { - "get": { - "consumes": [ - "*/*" - ], - "description": "watch individual changes to a list of Role. deprecated: use the 'watch' parameter with a list operation instead.", - "operationId": "watchRbacAuthorizationV1alpha1NamespacedRoleList", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "watchlist", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "Role", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "object name and auth scope, such as for teams and projects", - "in": "path", - "name": "namespace", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ] - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/watch/namespaces/{namespace}/roles/{name}": { - "get": { - "consumes": [ - "*/*" - ], - "description": "watch changes to an object of kind Role. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", - "operationId": "watchRbacAuthorizationV1alpha1NamespacedRole", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "watch", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "Role", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "name of the Role", - "in": "path", - "name": "name", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "object name and auth scope, such as for teams and projects", - "in": "path", - "name": "namespace", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ] - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/watch/rolebindings": { - "get": { - "consumes": [ - "*/*" - ], - "description": "watch individual changes to a list of RoleBinding. deprecated: use the 'watch' parameter with a list operation instead.", - "operationId": "watchRbacAuthorizationV1alpha1RoleBindingListForAllNamespaces", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "watchlist", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "RoleBinding", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ] - }, - "/apis/rbac.authorization.k8s.io/v1alpha1/watch/roles": { - "get": { - "consumes": [ - "*/*" - ], - "description": "watch individual changes to a list of Role. deprecated: use the 'watch' parameter with a list operation instead.", - "operationId": "watchRbacAuthorizationV1alpha1RoleListForAllNamespaces", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "rbacAuthorization_v1alpha1" - ], - "x-kubernetes-action": "watchlist", - "x-kubernetes-group-version-kind": { - "group": "rbac.authorization.k8s.io", - "kind": "Role", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ] - }, "/apis/scheduling.k8s.io/": { "get": { "consumes": [ @@ -82836,846 +78445,6 @@ } ] }, - "/apis/scheduling.k8s.io/v1alpha1/": { - "get": { - "consumes": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "description": "get available resources", - "operationId": "getSchedulingV1alpha1APIResources", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.APIResourceList" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "scheduling_v1alpha1" - ] - } - }, - "/apis/scheduling.k8s.io/v1alpha1/priorityclasses": { - "delete": { - "consumes": [ - "*/*" - ], - "description": "delete collection of PriorityClass", - "operationId": "deleteSchedulingV1alpha1CollectionPriorityClass", - "parameters": [ - { - "in": "body", - "name": "body", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" - } - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", - "in": "query", - "name": "gracePeriodSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", - "in": "query", - "name": "orphanDependents", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", - "in": "query", - "name": "propagationPolicy", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "scheduling_v1alpha1" - ], - "x-kubernetes-action": "deletecollection", - "x-kubernetes-group-version-kind": { - "group": "scheduling.k8s.io", - "kind": "PriorityClass", - "version": "v1alpha1" - } - }, - "get": { - "consumes": [ - "*/*" - ], - "description": "list or watch objects of kind PriorityClass", - "operationId": "listSchedulingV1alpha1PriorityClass", - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.scheduling.v1alpha1.PriorityClassList" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "scheduling_v1alpha1" - ], - "x-kubernetes-action": "list", - "x-kubernetes-group-version-kind": { - "group": "scheduling.k8s.io", - "kind": "PriorityClass", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - } - ], - "post": { - "consumes": [ - "*/*" - ], - "description": "create a PriorityClass", - "operationId": "createSchedulingV1alpha1PriorityClass", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.api.scheduling.v1alpha1.PriorityClass" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.scheduling.v1alpha1.PriorityClass" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.scheduling.v1alpha1.PriorityClass" - } - }, - "202": { - "description": "Accepted", - "schema": { - "$ref": "#/definitions/io.k8s.api.scheduling.v1alpha1.PriorityClass" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "scheduling_v1alpha1" - ], - "x-kubernetes-action": "post", - "x-kubernetes-group-version-kind": { - "group": "scheduling.k8s.io", - "kind": "PriorityClass", - "version": "v1alpha1" - } - } - }, - "/apis/scheduling.k8s.io/v1alpha1/priorityclasses/{name}": { - "delete": { - "consumes": [ - "*/*" - ], - "description": "delete a PriorityClass", - "operationId": "deleteSchedulingV1alpha1PriorityClass", - "parameters": [ - { - "in": "body", - "name": "body", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", - "in": "query", - "name": "gracePeriodSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", - "in": "query", - "name": "orphanDependents", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", - "in": "query", - "name": "propagationPolicy", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "202": { - "description": "Accepted", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "scheduling_v1alpha1" - ], - "x-kubernetes-action": "delete", - "x-kubernetes-group-version-kind": { - "group": "scheduling.k8s.io", - "kind": "PriorityClass", - "version": "v1alpha1" - } - }, - "get": { - "consumes": [ - "*/*" - ], - "description": "read the specified PriorityClass", - "operationId": "readSchedulingV1alpha1PriorityClass", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.scheduling.v1alpha1.PriorityClass" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "scheduling_v1alpha1" - ], - "x-kubernetes-action": "get", - "x-kubernetes-group-version-kind": { - "group": "scheduling.k8s.io", - "kind": "PriorityClass", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "name of the PriorityClass", - "in": "path", - "name": "name", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - } - ], - "patch": { - "consumes": [ - "application/json-patch+json", - "application/merge-patch+json", - "application/strategic-merge-patch+json", - "application/apply-patch+yaml" - ], - "description": "partially update the specified PriorityClass", - "operationId": "patchSchedulingV1alpha1PriorityClass", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch).", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - }, - { - "description": "Force is going to \"force\" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests.", - "in": "query", - "name": "force", - "type": "boolean", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.scheduling.v1alpha1.PriorityClass" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.scheduling.v1alpha1.PriorityClass" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "scheduling_v1alpha1" - ], - "x-kubernetes-action": "patch", - "x-kubernetes-group-version-kind": { - "group": "scheduling.k8s.io", - "kind": "PriorityClass", - "version": "v1alpha1" - } - }, - "put": { - "consumes": [ - "*/*" - ], - "description": "replace the specified PriorityClass", - "operationId": "replaceSchedulingV1alpha1PriorityClass", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.api.scheduling.v1alpha1.PriorityClass" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.scheduling.v1alpha1.PriorityClass" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.scheduling.v1alpha1.PriorityClass" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "scheduling_v1alpha1" - ], - "x-kubernetes-action": "put", - "x-kubernetes-group-version-kind": { - "group": "scheduling.k8s.io", - "kind": "PriorityClass", - "version": "v1alpha1" - } - } - }, - "/apis/scheduling.k8s.io/v1alpha1/watch/priorityclasses": { - "get": { - "consumes": [ - "*/*" - ], - "description": "watch individual changes to a list of PriorityClass. deprecated: use the 'watch' parameter with a list operation instead.", - "operationId": "watchSchedulingV1alpha1PriorityClassList", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "scheduling_v1alpha1" - ], - "x-kubernetes-action": "watchlist", - "x-kubernetes-group-version-kind": { - "group": "scheduling.k8s.io", - "kind": "PriorityClass", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ] - }, - "/apis/scheduling.k8s.io/v1alpha1/watch/priorityclasses/{name}": { - "get": { - "consumes": [ - "*/*" - ], - "description": "watch changes to an object of kind PriorityClass. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", - "operationId": "watchSchedulingV1alpha1PriorityClass", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "scheduling_v1alpha1" - ], - "x-kubernetes-action": "watch", - "x-kubernetes-group-version-kind": { - "group": "scheduling.k8s.io", - "kind": "PriorityClass", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "name of the PriorityClass", - "in": "path", - "name": "name", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ] - }, "/apis/storage.k8s.io/": { "get": { "consumes": [ @@ -87901,583 +82670,6 @@ } } }, - "/apis/storage.k8s.io/v1alpha1/volumeattachments": { - "delete": { - "consumes": [ - "*/*" - ], - "description": "delete collection of VolumeAttachment", - "operationId": "deleteStorageV1alpha1CollectionVolumeAttachment", - "parameters": [ - { - "in": "body", - "name": "body", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" - } - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", - "in": "query", - "name": "gracePeriodSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", - "in": "query", - "name": "orphanDependents", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", - "in": "query", - "name": "propagationPolicy", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "storage_v1alpha1" - ], - "x-kubernetes-action": "deletecollection", - "x-kubernetes-group-version-kind": { - "group": "storage.k8s.io", - "kind": "VolumeAttachment", - "version": "v1alpha1" - } - }, - "get": { - "consumes": [ - "*/*" - ], - "description": "list or watch objects of kind VolumeAttachment", - "operationId": "listStorageV1alpha1VolumeAttachment", - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeAttachmentList" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "storage_v1alpha1" - ], - "x-kubernetes-action": "list", - "x-kubernetes-group-version-kind": { - "group": "storage.k8s.io", - "kind": "VolumeAttachment", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - } - ], - "post": { - "consumes": [ - "*/*" - ], - "description": "create a VolumeAttachment", - "operationId": "createStorageV1alpha1VolumeAttachment", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeAttachment" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeAttachment" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeAttachment" - } - }, - "202": { - "description": "Accepted", - "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeAttachment" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "storage_v1alpha1" - ], - "x-kubernetes-action": "post", - "x-kubernetes-group-version-kind": { - "group": "storage.k8s.io", - "kind": "VolumeAttachment", - "version": "v1alpha1" - } - } - }, - "/apis/storage.k8s.io/v1alpha1/volumeattachments/{name}": { - "delete": { - "consumes": [ - "*/*" - ], - "description": "delete a VolumeAttachment", - "operationId": "deleteStorageV1alpha1VolumeAttachment", - "parameters": [ - { - "in": "body", - "name": "body", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", - "in": "query", - "name": "gracePeriodSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", - "in": "query", - "name": "orphanDependents", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", - "in": "query", - "name": "propagationPolicy", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeAttachment" - } - }, - "202": { - "description": "Accepted", - "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeAttachment" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "storage_v1alpha1" - ], - "x-kubernetes-action": "delete", - "x-kubernetes-group-version-kind": { - "group": "storage.k8s.io", - "kind": "VolumeAttachment", - "version": "v1alpha1" - } - }, - "get": { - "consumes": [ - "*/*" - ], - "description": "read the specified VolumeAttachment", - "operationId": "readStorageV1alpha1VolumeAttachment", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeAttachment" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "storage_v1alpha1" - ], - "x-kubernetes-action": "get", - "x-kubernetes-group-version-kind": { - "group": "storage.k8s.io", - "kind": "VolumeAttachment", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "name of the VolumeAttachment", - "in": "path", - "name": "name", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - } - ], - "patch": { - "consumes": [ - "application/json-patch+json", - "application/merge-patch+json", - "application/strategic-merge-patch+json", - "application/apply-patch+yaml" - ], - "description": "partially update the specified VolumeAttachment", - "operationId": "patchStorageV1alpha1VolumeAttachment", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch).", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - }, - { - "description": "Force is going to \"force\" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests.", - "in": "query", - "name": "force", - "type": "boolean", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeAttachment" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeAttachment" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "storage_v1alpha1" - ], - "x-kubernetes-action": "patch", - "x-kubernetes-group-version-kind": { - "group": "storage.k8s.io", - "kind": "VolumeAttachment", - "version": "v1alpha1" - } - }, - "put": { - "consumes": [ - "*/*" - ], - "description": "replace the specified VolumeAttachment", - "operationId": "replaceStorageV1alpha1VolumeAttachment", - "parameters": [ - { - "in": "body", - "name": "body", - "required": true, - "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeAttachment" - } - }, - { - "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", - "in": "query", - "name": "dryRun", - "type": "string", - "uniqueItems": true - }, - { - "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "in": "query", - "name": "fieldManager", - "type": "string", - "uniqueItems": true - } - ], - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeAttachment" - } - }, - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/io.k8s.api.storage.v1alpha1.VolumeAttachment" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "storage_v1alpha1" - ], - "x-kubernetes-action": "put", - "x-kubernetes-group-version-kind": { - "group": "storage.k8s.io", - "kind": "VolumeAttachment", - "version": "v1alpha1" - } - } - }, "/apis/storage.k8s.io/v1alpha1/watch/csistoragecapacities": { "get": { "consumes": [ @@ -88835,236 +83027,6 @@ } ] }, - "/apis/storage.k8s.io/v1alpha1/watch/volumeattachments": { - "get": { - "consumes": [ - "*/*" - ], - "description": "watch individual changes to a list of VolumeAttachment. deprecated: use the 'watch' parameter with a list operation instead.", - "operationId": "watchStorageV1alpha1VolumeAttachmentList", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "storage_v1alpha1" - ], - "x-kubernetes-action": "watchlist", - "x-kubernetes-group-version-kind": { - "group": "storage.k8s.io", - "kind": "VolumeAttachment", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ] - }, - "/apis/storage.k8s.io/v1alpha1/watch/volumeattachments/{name}": { - "get": { - "consumes": [ - "*/*" - ], - "description": "watch changes to an object of kind VolumeAttachment. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", - "operationId": "watchStorageV1alpha1VolumeAttachment", - "produces": [ - "application/json", - "application/yaml", - "application/vnd.kubernetes.protobuf", - "application/json;stream=watch", - "application/vnd.kubernetes.protobuf;stream=watch" - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent" - } - }, - "401": { - "description": "Unauthorized" - } - }, - "schemes": [ - "https" - ], - "tags": [ - "storage_v1alpha1" - ], - "x-kubernetes-action": "watch", - "x-kubernetes-group-version-kind": { - "group": "storage.k8s.io", - "kind": "VolumeAttachment", - "version": "v1alpha1" - } - }, - "parameters": [ - { - "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", - "in": "query", - "name": "allowWatchBookmarks", - "type": "boolean", - "uniqueItems": true - }, - { - "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", - "in": "query", - "name": "continue", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", - "in": "query", - "name": "fieldSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", - "in": "query", - "name": "labelSelector", - "type": "string", - "uniqueItems": true - }, - { - "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", - "in": "query", - "name": "limit", - "type": "integer", - "uniqueItems": true - }, - { - "description": "name of the VolumeAttachment", - "in": "path", - "name": "name", - "required": true, - "type": "string", - "uniqueItems": true - }, - { - "description": "If 'true', then the output is pretty printed.", - "in": "query", - "name": "pretty", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersion", - "type": "string", - "uniqueItems": true - }, - { - "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", - "in": "query", - "name": "resourceVersionMatch", - "type": "string", - "uniqueItems": true - }, - { - "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", - "in": "query", - "name": "timeoutSeconds", - "type": "integer", - "uniqueItems": true - }, - { - "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", - "in": "query", - "name": "watch", - "type": "boolean", - "uniqueItems": true - } - ] - }, "/apis/storage.k8s.io/v1beta1/": { "get": { "consumes": [ diff --git a/cmd/kube-apiserver/app/aggregator.go b/cmd/kube-apiserver/app/aggregator.go index ce90f4080f7..251008b94c5 100644 --- a/cmd/kube-apiserver/app/aggregator.go +++ b/cmd/kube-apiserver/app/aggregator.go @@ -249,9 +249,7 @@ var apiVersionPriorities = map[schema.GroupVersion]priority{ {Group: "events.k8s.io", Version: "v1"}: {group: 17750, version: 15}, {Group: "events.k8s.io", Version: "v1beta1"}: {group: 17750, version: 5}, {Group: "authentication.k8s.io", Version: "v1"}: {group: 17700, version: 15}, - {Group: "authentication.k8s.io", Version: "v1beta1"}: {group: 17700, version: 9}, {Group: "authorization.k8s.io", Version: "v1"}: {group: 17600, version: 15}, - {Group: "authorization.k8s.io", Version: "v1beta1"}: {group: 17600, version: 9}, {Group: "autoscaling", Version: "v1"}: {group: 17500, version: 15}, {Group: "autoscaling", Version: "v2beta1"}: {group: 17500, version: 9}, {Group: "autoscaling", Version: "v2beta2"}: {group: 17500, version: 1}, @@ -259,27 +257,17 @@ var apiVersionPriorities = map[schema.GroupVersion]priority{ {Group: "batch", Version: "v1beta1"}: {group: 17400, version: 9}, {Group: "batch", Version: "v2alpha1"}: {group: 17400, version: 9}, {Group: "certificates.k8s.io", Version: "v1"}: {group: 17300, version: 15}, - {Group: "certificates.k8s.io", Version: "v1beta1"}: {group: 17300, version: 9}, {Group: "networking.k8s.io", Version: "v1"}: {group: 17200, version: 15}, - {Group: "networking.k8s.io", Version: "v1beta1"}: {group: 17200, version: 9}, - {Group: "extensions", Version: "v1beta1"}: {group: 17150, version: 1}, // prioritize below networking.k8s.io, which contains the GA version of Ingress, the only resource remaining in extensions/v1beta1 {Group: "policy", Version: "v1"}: {group: 17100, version: 15}, {Group: "policy", Version: "v1beta1"}: {group: 17100, version: 9}, {Group: "rbac.authorization.k8s.io", Version: "v1"}: {group: 17000, version: 15}, - {Group: "rbac.authorization.k8s.io", Version: "v1beta1"}: {group: 17000, version: 12}, - {Group: "rbac.authorization.k8s.io", Version: "v1alpha1"}: {group: 17000, version: 9}, {Group: "storage.k8s.io", Version: "v1"}: {group: 16800, version: 15}, {Group: "storage.k8s.io", Version: "v1beta1"}: {group: 16800, version: 9}, {Group: "storage.k8s.io", Version: "v1alpha1"}: {group: 16800, version: 1}, {Group: "apiextensions.k8s.io", Version: "v1"}: {group: 16700, version: 15}, - {Group: "apiextensions.k8s.io", Version: "v1beta1"}: {group: 16700, version: 9}, {Group: "admissionregistration.k8s.io", Version: "v1"}: {group: 16700, version: 15}, - {Group: "admissionregistration.k8s.io", Version: "v1beta1"}: {group: 16700, version: 12}, {Group: "scheduling.k8s.io", Version: "v1"}: {group: 16600, version: 15}, - {Group: "scheduling.k8s.io", Version: "v1beta1"}: {group: 16600, version: 12}, - {Group: "scheduling.k8s.io", Version: "v1alpha1"}: {group: 16600, version: 9}, {Group: "coordination.k8s.io", Version: "v1"}: {group: 16500, version: 15}, - {Group: "coordination.k8s.io", Version: "v1beta1"}: {group: 16500, version: 9}, {Group: "node.k8s.io", Version: "v1"}: {group: 16300, version: 15}, {Group: "node.k8s.io", Version: "v1alpha1"}: {group: 16300, version: 1}, {Group: "node.k8s.io", Version: "v1beta1"}: {group: 16300, version: 9}, diff --git a/pkg/apis/admissionregistration/validation/validation.go b/pkg/apis/admissionregistration/validation/validation.go index 9f0832cf9d0..0f887529878 100644 --- a/pkg/apis/admissionregistration/validation/validation.go +++ b/pkg/apis/admissionregistration/validation/validation.go @@ -22,7 +22,6 @@ import ( genericvalidation "k8s.io/apimachinery/pkg/api/validation" metav1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/sets" utilvalidation "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" @@ -201,11 +200,11 @@ func validateAdmissionReviewVersions(versions []string, requireRecognizedAdmissi } // ValidateValidatingWebhookConfiguration validates a webhook before creation. -func ValidateValidatingWebhookConfiguration(e *admissionregistration.ValidatingWebhookConfiguration, requestGV schema.GroupVersion) field.ErrorList { +func ValidateValidatingWebhookConfiguration(e *admissionregistration.ValidatingWebhookConfiguration) field.ErrorList { return validateValidatingWebhookConfiguration(e, validationOptions{ - requireNoSideEffects: requireNoSideEffects(requestGV), + requireNoSideEffects: true, requireRecognizedAdmissionReviewVersion: true, - requireUniqueWebhookNames: requireUniqueWebhookNames(requestGV), + requireUniqueWebhookNames: true, }) } @@ -226,11 +225,11 @@ func validateValidatingWebhookConfiguration(e *admissionregistration.ValidatingW } // ValidateMutatingWebhookConfiguration validates a webhook before creation. -func ValidateMutatingWebhookConfiguration(e *admissionregistration.MutatingWebhookConfiguration, requestGV schema.GroupVersion) field.ErrorList { +func ValidateMutatingWebhookConfiguration(e *admissionregistration.MutatingWebhookConfiguration) field.ErrorList { return validateMutatingWebhookConfiguration(e, validationOptions{ - requireNoSideEffects: requireNoSideEffects(requestGV), + requireNoSideEffects: true, requireRecognizedAdmissionReviewVersion: true, - requireUniqueWebhookNames: requireUniqueWebhookNames(requestGV), + requireUniqueWebhookNames: true, }) } @@ -497,29 +496,19 @@ func validatingHasNoSideEffects(webhooks []admissionregistration.ValidatingWebho } // ValidateValidatingWebhookConfigurationUpdate validates update of validating webhook configuration -func ValidateValidatingWebhookConfigurationUpdate(newC, oldC *admissionregistration.ValidatingWebhookConfiguration, requestGV schema.GroupVersion) field.ErrorList { +func ValidateValidatingWebhookConfigurationUpdate(newC, oldC *admissionregistration.ValidatingWebhookConfiguration) field.ErrorList { return validateValidatingWebhookConfiguration(newC, validationOptions{ - requireNoSideEffects: requireNoSideEffects(requestGV) && validatingHasNoSideEffects(oldC.Webhooks), + requireNoSideEffects: validatingHasNoSideEffects(oldC.Webhooks), requireRecognizedAdmissionReviewVersion: validatingHasAcceptedAdmissionReviewVersions(oldC.Webhooks), - requireUniqueWebhookNames: requireUniqueWebhookNames(requestGV) && validatingHasUniqueWebhookNames(oldC.Webhooks), + requireUniqueWebhookNames: validatingHasUniqueWebhookNames(oldC.Webhooks), }) } // ValidateMutatingWebhookConfigurationUpdate validates update of mutating webhook configuration -func ValidateMutatingWebhookConfigurationUpdate(newC, oldC *admissionregistration.MutatingWebhookConfiguration, requestGV schema.GroupVersion) field.ErrorList { +func ValidateMutatingWebhookConfigurationUpdate(newC, oldC *admissionregistration.MutatingWebhookConfiguration) field.ErrorList { return validateMutatingWebhookConfiguration(newC, validationOptions{ - requireNoSideEffects: requireNoSideEffects(requestGV) && mutatingHasNoSideEffects(oldC.Webhooks), + requireNoSideEffects: mutatingHasNoSideEffects(oldC.Webhooks), requireRecognizedAdmissionReviewVersion: mutatingHasAcceptedAdmissionReviewVersions(oldC.Webhooks), - requireUniqueWebhookNames: requireUniqueWebhookNames(requestGV) && mutatingHasUniqueWebhookNames(oldC.Webhooks), + requireUniqueWebhookNames: mutatingHasUniqueWebhookNames(oldC.Webhooks), }) } - -// requireUniqueWebhookNames returns true for all requests except v1beta1 (for backwards compatibility) -func requireUniqueWebhookNames(requestGV schema.GroupVersion) bool { - return requestGV != (schema.GroupVersion{Group: admissionregistration.GroupName, Version: "v1beta1"}) -} - -// requireNoSideEffects returns true for all requests except v1beta1 (for backwards compatibility) -func requireNoSideEffects(requestGV schema.GroupVersion) bool { - return requestGV != (schema.GroupVersion{Group: admissionregistration.GroupName, Version: "v1beta1"}) -} diff --git a/pkg/apis/admissionregistration/validation/validation_test.go b/pkg/apis/admissionregistration/validation/validation_test.go index 6ffe27337b5..5b84ea21c3b 100644 --- a/pkg/apis/admissionregistration/validation/validation_test.go +++ b/pkg/apis/admissionregistration/validation/validation_test.go @@ -21,7 +21,6 @@ import ( "testing" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/kubernetes/pkg/apis/admissionregistration" ) @@ -46,6 +45,7 @@ func newValidatingWebhookConfiguration(hooks []admissionregistration.ValidatingW } func TestValidateValidatingWebhookConfiguration(t *testing.T) { + noSideEffect := admissionregistration.SideEffectClassNone unknownSideEffect := admissionregistration.SideEffectClassUnknown validClientConfig := admissionregistration.WebhookClientConfig{ URL: strPtr("https://example.com"), @@ -53,7 +53,6 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) { tests := []struct { name string config *admissionregistration.ValidatingWebhookConfiguration - gv schema.GroupVersion expectedError string }{ { @@ -83,11 +82,10 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) { { Name: "webhook.k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, AdmissionReviewVersions: []string{"v1beta1"}, }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, expectedError: ``, }, { @@ -96,11 +94,10 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) { { Name: "webhook.k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, AdmissionReviewVersions: []string{"v1beta1", "invalid-version"}, }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, expectedError: ``, }, { @@ -131,24 +128,23 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) { { Name: "webhook.k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, }, { Name: "k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, }, { Name: "", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, expectedError: `webhooks[1].name: Invalid value: "k8s.io": should be a domain with at least three segments separated by dots, webhooks[2].name: Required value`, }, { - name: "Webhooks must have unique names when not created via v1beta1", + name: "Webhooks must have unique names when created", config: newValidatingWebhookConfiguration([]admissionregistration.ValidatingWebhook{ { Name: "webhook.k8s.io", @@ -161,26 +157,8 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) { SideEffects: &unknownSideEffect, }, }, true), - gv: schema.GroupVersion{Group: "foo", Version: "bar"}, expectedError: `webhooks[1].name: Duplicate value: "webhook.k8s.io"`, }, - { - name: "Webhooks can have duplicate names when created via v1beta1", - config: newValidatingWebhookConfiguration([]admissionregistration.ValidatingWebhook{ - { - Name: "webhook.k8s.io", - ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, - }, - { - Name: "webhook.k8s.io", - ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, - }, - }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, - expectedError: ``, - }, { name: "Operations must not be empty or nil", config: newValidatingWebhookConfiguration([]admissionregistration.ValidatingWebhook{ @@ -271,7 +249,7 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) { { Name: "webhook.k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, Rules: []admissionregistration.RuleWithOperations{ { Operations: []admissionregistration.OperationType{"CREATE"}, @@ -284,7 +262,6 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) { }, }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, }, { name: `resource "*" cannot mix with resources that don't have subresources`, @@ -334,7 +311,7 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) { { Name: "webhook.k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, Rules: []admissionregistration.RuleWithOperations{ { Operations: []admissionregistration.OperationType{"CREATE"}, @@ -347,7 +324,6 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) { }, }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, }, { name: "resource */a cannot mix with x/a", @@ -429,7 +405,7 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) { expectedError: `webhooks[0].sideEffects: Required value: must specify one of None, NoneOnDryRun`, }, { - name: "SideEffects can only be \"Unknown\", \"None\", \"Some\", or \"NoneOnDryRun\" via v1beta1", + name: "SideEffects can only be \"None\" or \"NoneOnDryRun\" when created", config: newValidatingWebhookConfiguration([]admissionregistration.ValidatingWebhook{ { Name: "webhook.k8s.io", @@ -440,22 +416,6 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) { }(), }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, - expectedError: `webhooks[0].sideEffects: Unsupported value: "other": supported values: "None", "NoneOnDryRun", "Some", "Unknown"`, - }, - { - name: "SideEffects can only be \"None\" or \"NoneOnDryRun\" via v1", - config: newValidatingWebhookConfiguration([]admissionregistration.ValidatingWebhook{ - { - Name: "webhook.k8s.io", - ClientConfig: validClientConfig, - SideEffects: func() *admissionregistration.SideEffectClass { - r := admissionregistration.SideEffectClass("other") - return &r - }(), - }, - }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1"}, expectedError: `webhooks[0].sideEffects: Unsupported value: "other": supported values: "None", "NoneOnDryRun"`, }, { @@ -599,10 +559,9 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) { Port: 443, }, }, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, expectedError: ``, }, { @@ -618,10 +577,9 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) { Port: 443, }, }, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, expectedError: ``, }, { @@ -637,7 +595,7 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) { Port: 443, }, }, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, }, }, true), expectedError: `clientConfig.service.path: Invalid value: "//": segment[0] may not be empty`, @@ -775,28 +733,27 @@ func TestValidateValidatingWebhookConfiguration(t *testing.T) { { Name: "webhook.k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, TimeoutSeconds: int32Ptr(1), }, { Name: "webhook2.k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, TimeoutSeconds: int32Ptr(15), }, { Name: "webhook3.k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, TimeoutSeconds: int32Ptr(30), }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - errs := ValidateValidatingWebhookConfiguration(test.config, test.gv) + errs := ValidateValidatingWebhookConfiguration(test.config) err := errs.ToAggregate() if err != nil { if e, a := test.expectedError, err.Error(); !strings.Contains(a, e) || e == "" { @@ -821,7 +778,6 @@ func TestValidateValidatingWebhookConfigurationUpdate(t *testing.T) { name string oldconfig *admissionregistration.ValidatingWebhookConfiguration config *admissionregistration.ValidatingWebhookConfiguration - gv schema.GroupVersion expectedError string }{ { @@ -903,7 +859,7 @@ func TestValidateValidatingWebhookConfigurationUpdate(t *testing.T) { expectedError: `Invalid value: []string{"invalid-v1"}`, }, { - name: "Webhooks must have unique names when not updated via v1beta1", + name: "Webhooks must have unique names when old config has unique names", config: newValidatingWebhookConfiguration([]admissionregistration.ValidatingWebhook{ { Name: "webhook.k8s.io", @@ -923,7 +879,6 @@ func TestValidateValidatingWebhookConfigurationUpdate(t *testing.T) { SideEffects: &unknownSideEffect, }, }, false), - gv: schema.GroupVersion{Group: "foo", Version: "bar"}, expectedError: `webhooks[1].name: Duplicate value: "webhook.k8s.io"`, }, { @@ -952,37 +907,12 @@ func TestValidateValidatingWebhookConfigurationUpdate(t *testing.T) { SideEffects: &unknownSideEffect, }, }, true), - gv: schema.GroupVersion{Group: "foo", Version: "bar"}, - expectedError: ``, - }, - { - name: "Webhooks can have duplicate names when updated via v1beta1", - config: newValidatingWebhookConfiguration([]admissionregistration.ValidatingWebhook{ - { - Name: "webhook.k8s.io", - ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, - }, - { - Name: "webhook.k8s.io", - ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, - }, - }, true), - oldconfig: newValidatingWebhookConfiguration([]admissionregistration.ValidatingWebhook{ - { - Name: "webhook.k8s.io", - ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, - }, - }, false), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, expectedError: ``, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - errs := ValidateValidatingWebhookConfigurationUpdate(test.config, test.oldconfig, test.gv) + errs := ValidateValidatingWebhookConfigurationUpdate(test.config, test.oldconfig) err := errs.ToAggregate() if err != nil { if e, a := test.expectedError, err.Error(); !strings.Contains(a, e) || e == "" { @@ -1015,6 +945,7 @@ func newMutatingWebhookConfiguration(hooks []admissionregistration.MutatingWebho } func TestValidateMutatingWebhookConfiguration(t *testing.T) { + noSideEffect := admissionregistration.SideEffectClassNone unknownSideEffect := admissionregistration.SideEffectClassUnknown validClientConfig := admissionregistration.WebhookClientConfig{ URL: strPtr("https://example.com"), @@ -1022,7 +953,6 @@ func TestValidateMutatingWebhookConfiguration(t *testing.T) { tests := []struct { name string config *admissionregistration.MutatingWebhookConfiguration - gv schema.GroupVersion expectedError string }{ { @@ -1052,11 +982,10 @@ func TestValidateMutatingWebhookConfiguration(t *testing.T) { { Name: "webhook.k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, AdmissionReviewVersions: []string{"v1beta1"}, }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, expectedError: ``, }, { @@ -1065,11 +994,10 @@ func TestValidateMutatingWebhookConfiguration(t *testing.T) { { Name: "webhook.k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, AdmissionReviewVersions: []string{"v1beta1", "invalid-version"}, }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, expectedError: ``, }, { @@ -1100,24 +1028,23 @@ func TestValidateMutatingWebhookConfiguration(t *testing.T) { { Name: "webhook.k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, }, { Name: "k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, }, { Name: "", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, expectedError: `webhooks[1].name: Invalid value: "k8s.io": should be a domain with at least three segments separated by dots, webhooks[2].name: Required value`, }, { - name: "Webhooks must have unique names when not created via v1beta1", + name: "Webhooks must have unique names when created", config: newMutatingWebhookConfiguration([]admissionregistration.MutatingWebhook{ { Name: "webhook.k8s.io", @@ -1130,26 +1057,8 @@ func TestValidateMutatingWebhookConfiguration(t *testing.T) { SideEffects: &unknownSideEffect, }, }, true), - gv: schema.GroupVersion{Group: "foo", Version: "bar"}, expectedError: `webhooks[1].name: Duplicate value: "webhook.k8s.io"`, }, - { - name: "Webhooks can have duplicate names when created via v1beta1", - config: newMutatingWebhookConfiguration([]admissionregistration.MutatingWebhook{ - { - Name: "webhook.k8s.io", - ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, - }, - { - Name: "webhook.k8s.io", - ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, - }, - }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, - expectedError: ``, - }, { name: "Operations must not be empty or nil", config: newMutatingWebhookConfiguration([]admissionregistration.MutatingWebhook{ @@ -1240,7 +1149,7 @@ func TestValidateMutatingWebhookConfiguration(t *testing.T) { { Name: "webhook.k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, Rules: []admissionregistration.RuleWithOperations{ { Operations: []admissionregistration.OperationType{"CREATE"}, @@ -1253,7 +1162,6 @@ func TestValidateMutatingWebhookConfiguration(t *testing.T) { }, }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, }, { name: `resource "*" cannot mix with resources that don't have subresources`, @@ -1303,7 +1211,7 @@ func TestValidateMutatingWebhookConfiguration(t *testing.T) { { Name: "webhook.k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, Rules: []admissionregistration.RuleWithOperations{ { Operations: []admissionregistration.OperationType{"CREATE"}, @@ -1316,7 +1224,6 @@ func TestValidateMutatingWebhookConfiguration(t *testing.T) { }, }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, }, { name: "resource */a cannot mix with x/a", @@ -1398,7 +1305,7 @@ func TestValidateMutatingWebhookConfiguration(t *testing.T) { expectedError: `webhooks[0].sideEffects: Required value: must specify one of None, NoneOnDryRun`, }, { - name: "SideEffects can only be \"Unknown\", \"None\", \"Some\", or \"NoneOnDryRun\" via v1beta1", + name: "SideEffects can only be \"None\" or \"NoneOnDryRun\" when created", config: newMutatingWebhookConfiguration([]admissionregistration.MutatingWebhook{ { Name: "webhook.k8s.io", @@ -1409,22 +1316,6 @@ func TestValidateMutatingWebhookConfiguration(t *testing.T) { }(), }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, - expectedError: `webhooks[0].sideEffects: Unsupported value: "other": supported values: "None", "NoneOnDryRun", "Some", "Unknown"`, - }, - { - name: "SideEffects can only be \"None\" or \"NoneOnDryRun\" via v1", - config: newMutatingWebhookConfiguration([]admissionregistration.MutatingWebhook{ - { - Name: "webhook.k8s.io", - ClientConfig: validClientConfig, - SideEffects: func() *admissionregistration.SideEffectClass { - r := admissionregistration.SideEffectClass("other") - return &r - }(), - }, - }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1"}, expectedError: `webhooks[0].sideEffects: Unsupported value: "other": supported values: "None", "NoneOnDryRun"`, }, { @@ -1568,10 +1459,9 @@ func TestValidateMutatingWebhookConfiguration(t *testing.T) { Port: 443, }, }, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, expectedError: ``, }, { @@ -1587,10 +1477,9 @@ func TestValidateMutatingWebhookConfiguration(t *testing.T) { Port: 443, }, }, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, expectedError: ``, }, { @@ -1606,7 +1495,7 @@ func TestValidateMutatingWebhookConfiguration(t *testing.T) { Port: 443, }, }, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, }, }, true), expectedError: `clientConfig.service.path: Invalid value: "//": segment[0] may not be empty`, @@ -1744,28 +1633,27 @@ func TestValidateMutatingWebhookConfiguration(t *testing.T) { { Name: "webhook.k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, TimeoutSeconds: int32Ptr(1), }, { Name: "webhook2.k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, TimeoutSeconds: int32Ptr(15), }, { Name: "webhook3.k8s.io", ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, + SideEffects: &noSideEffect, TimeoutSeconds: int32Ptr(30), }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - errs := ValidateMutatingWebhookConfiguration(test.config, test.gv) + errs := ValidateMutatingWebhookConfiguration(test.config) err := errs.ToAggregate() if err != nil { if e, a := test.expectedError, err.Error(); !strings.Contains(a, e) || e == "" { @@ -1791,7 +1679,6 @@ func TestValidateMutatingWebhookConfigurationUpdate(t *testing.T) { name string oldconfig *admissionregistration.MutatingWebhookConfiguration config *admissionregistration.MutatingWebhookConfiguration - gv schema.GroupVersion expectedError string }{ { @@ -1917,35 +1804,10 @@ func TestValidateMutatingWebhookConfigurationUpdate(t *testing.T) { SideEffects: &unknownSideEffect, }, }, true), - gv: schema.GroupVersion{Group: "foo", Version: "bar"}, expectedError: ``, }, { - name: "Webhooks can have duplicate names when updated via v1beta1", - config: newMutatingWebhookConfiguration([]admissionregistration.MutatingWebhook{ - { - Name: "webhook.k8s.io", - ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, - }, - { - Name: "webhook.k8s.io", - ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, - }, - }, true), - oldconfig: newMutatingWebhookConfiguration([]admissionregistration.MutatingWebhook{ - { - Name: "webhook.k8s.io", - ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, - }, - }, false), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, - expectedError: ``, - }, - { - name: "Webhooks can't have side effects when old config has no side effects via v1", + name: "Webhooks can't have side effects when old config has no side effects", config: newMutatingWebhookConfiguration([]admissionregistration.MutatingWebhook{ { Name: "webhook.k8s.io", @@ -1960,7 +1822,6 @@ func TestValidateMutatingWebhookConfigurationUpdate(t *testing.T) { SideEffects: &noSideEffect, }, }, true), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1"}, expectedError: `Unsupported value: "Unknown": supported values: "None", "NoneOnDryRun"`, }, { @@ -1979,32 +1840,12 @@ func TestValidateMutatingWebhookConfigurationUpdate(t *testing.T) { SideEffects: &unknownSideEffect, }, }, true), - gv: schema.GroupVersion{Group: "foo", Version: "bar"}, - expectedError: ``, - }, - { - name: "Webhooks can have side effects when updated via v1beta1", - config: newMutatingWebhookConfiguration([]admissionregistration.MutatingWebhook{ - { - Name: "webhook.k8s.io", - ClientConfig: validClientConfig, - SideEffects: &unknownSideEffect, - }, - }, true), - oldconfig: newMutatingWebhookConfiguration([]admissionregistration.MutatingWebhook{ - { - Name: "webhook.k8s.io", - ClientConfig: validClientConfig, - SideEffects: &noSideEffect, - }, - }, false), - gv: schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"}, expectedError: ``, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - errs := ValidateMutatingWebhookConfigurationUpdate(test.config, test.oldconfig, test.gv) + errs := ValidateMutatingWebhookConfigurationUpdate(test.config, test.oldconfig) err := errs.ToAggregate() if err != nil { if e, a := test.expectedError, err.Error(); !strings.Contains(a, e) || e == "" { diff --git a/pkg/apis/certificates/validation/validation.go b/pkg/apis/certificates/validation/validation.go index b019ac57cfd..a4e21860361 100644 --- a/pkg/apis/certificates/validation/validation.go +++ b/pkg/apis/certificates/validation/validation.go @@ -25,14 +25,12 @@ import ( v1 "k8s.io/api/core/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/sets" utilvalidation "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" utilcert "k8s.io/client-go/util/cert" "k8s.io/kubernetes/pkg/apis/certificates" - certificatesv1beta1 "k8s.io/kubernetes/pkg/apis/certificates/v1beta1" apivalidation "k8s.io/kubernetes/pkg/apis/core/validation" ) @@ -139,8 +137,8 @@ func ValidateCertificateRequestName(name string, prefix bool) []string { return nil } -func ValidateCertificateSigningRequestCreate(csr *certificates.CertificateSigningRequest, version schema.GroupVersion) field.ErrorList { - opts := getValidationOptions(version, csr, nil) +func ValidateCertificateSigningRequestCreate(csr *certificates.CertificateSigningRequest) field.ErrorList { + opts := getValidationOptions(csr, nil) return validateCertificateSigningRequest(csr, opts) } @@ -347,19 +345,19 @@ func ValidateCertificateSigningRequestSignerName(fldPath *field.Path, signerName return el } -func ValidateCertificateSigningRequestUpdate(newCSR, oldCSR *certificates.CertificateSigningRequest, version schema.GroupVersion) field.ErrorList { - opts := getValidationOptions(version, newCSR, oldCSR) +func ValidateCertificateSigningRequestUpdate(newCSR, oldCSR *certificates.CertificateSigningRequest) field.ErrorList { + opts := getValidationOptions(newCSR, oldCSR) return validateCertificateSigningRequestUpdate(newCSR, oldCSR, opts) } -func ValidateCertificateSigningRequestStatusUpdate(newCSR, oldCSR *certificates.CertificateSigningRequest, version schema.GroupVersion) field.ErrorList { - opts := getValidationOptions(version, newCSR, oldCSR) +func ValidateCertificateSigningRequestStatusUpdate(newCSR, oldCSR *certificates.CertificateSigningRequest) field.ErrorList { + opts := getValidationOptions(newCSR, oldCSR) opts.allowSettingCertificate = true return validateCertificateSigningRequestUpdate(newCSR, oldCSR, opts) } -func ValidateCertificateSigningRequestApprovalUpdate(newCSR, oldCSR *certificates.CertificateSigningRequest, version schema.GroupVersion) field.ErrorList { - opts := getValidationOptions(version, newCSR, oldCSR) +func ValidateCertificateSigningRequestApprovalUpdate(newCSR, oldCSR *certificates.CertificateSigningRequest) field.ErrorList { + opts := getValidationOptions(newCSR, oldCSR) opts.allowSettingApprovalConditions = true return validateCertificateSigningRequestUpdate(newCSR, oldCSR, opts) } @@ -420,24 +418,19 @@ func findConditions(csr *certificates.CertificateSigningRequest, conditionType c // compatible with the specified version and existing CSR. // oldCSR may be nil if this is a create request. // validation options related to subresource-specific capabilities are set to false. -func getValidationOptions(version schema.GroupVersion, newCSR, oldCSR *certificates.CertificateSigningRequest) certificateValidationOptions { +func getValidationOptions(newCSR, oldCSR *certificates.CertificateSigningRequest) certificateValidationOptions { return certificateValidationOptions{ - allowResettingCertificate: allowResettingCertificate(version), + allowResettingCertificate: false, allowBothApprovedAndDenied: allowBothApprovedAndDenied(oldCSR), - allowLegacySignerName: allowLegacySignerName(version, oldCSR), - allowDuplicateConditionTypes: allowDuplicateConditionTypes(version, oldCSR), - allowEmptyConditionType: allowEmptyConditionType(version, oldCSR), - allowArbitraryCertificate: allowArbitraryCertificate(version, newCSR, oldCSR), - allowDuplicateUsages: allowDuplicateUsages(version, oldCSR), - allowUnknownUsages: allowUnknownUsages(version, oldCSR), + allowLegacySignerName: allowLegacySignerName(oldCSR), + allowDuplicateConditionTypes: allowDuplicateConditionTypes(oldCSR), + allowEmptyConditionType: allowEmptyConditionType(oldCSR), + allowArbitraryCertificate: allowArbitraryCertificate(newCSR, oldCSR), + allowDuplicateUsages: allowDuplicateUsages(oldCSR), + allowUnknownUsages: allowUnknownUsages(oldCSR), } } -func allowResettingCertificate(version schema.GroupVersion) bool { - // compatibility with v1beta1 - return version == certificatesv1beta1.SchemeGroupVersion -} - func allowBothApprovedAndDenied(oldCSR *certificates.CertificateSigningRequest) bool { if oldCSR == nil { return false @@ -455,10 +448,8 @@ func allowBothApprovedAndDenied(oldCSR *certificates.CertificateSigningRequest) return approved && denied } -func allowLegacySignerName(version schema.GroupVersion, oldCSR *certificates.CertificateSigningRequest) bool { +func allowLegacySignerName(oldCSR *certificates.CertificateSigningRequest) bool { switch { - case version == certificatesv1beta1.SchemeGroupVersion: - return true // compatibility with v1beta1 case oldCSR != nil && oldCSR.Spec.SignerName == certificates.LegacyUnknownSignerName: return true // compatibility with existing data default: @@ -466,10 +457,8 @@ func allowLegacySignerName(version schema.GroupVersion, oldCSR *certificates.Cer } } -func allowDuplicateConditionTypes(version schema.GroupVersion, oldCSR *certificates.CertificateSigningRequest) bool { +func allowDuplicateConditionTypes(oldCSR *certificates.CertificateSigningRequest) bool { switch { - case version == certificatesv1beta1.SchemeGroupVersion: - return true // compatibility with v1beta1 case oldCSR != nil && hasDuplicateConditionTypes(oldCSR): return true // compatibility with existing data default: @@ -487,10 +476,8 @@ func hasDuplicateConditionTypes(csr *certificates.CertificateSigningRequest) boo return false } -func allowEmptyConditionType(version schema.GroupVersion, oldCSR *certificates.CertificateSigningRequest) bool { +func allowEmptyConditionType(oldCSR *certificates.CertificateSigningRequest) bool { switch { - case version == certificatesv1beta1.SchemeGroupVersion: - return true // compatibility with v1beta1 case oldCSR != nil && hasEmptyConditionType(oldCSR): return true // compatibility with existing data default: @@ -506,10 +493,8 @@ func hasEmptyConditionType(csr *certificates.CertificateSigningRequest) bool { return false } -func allowArbitraryCertificate(version schema.GroupVersion, newCSR, oldCSR *certificates.CertificateSigningRequest) bool { +func allowArbitraryCertificate(newCSR, oldCSR *certificates.CertificateSigningRequest) bool { switch { - case version == certificatesv1beta1.SchemeGroupVersion: - return true // compatibility with v1beta1 case newCSR != nil && oldCSR != nil && bytes.Equal(newCSR.Status.Certificate, oldCSR.Status.Certificate): return true // tolerate updates that don't touch status.certificate case oldCSR != nil && validateCertificate(oldCSR.Status.Certificate) != nil: @@ -519,10 +504,8 @@ func allowArbitraryCertificate(version schema.GroupVersion, newCSR, oldCSR *cert } } -func allowUnknownUsages(version schema.GroupVersion, oldCSR *certificates.CertificateSigningRequest) bool { +func allowUnknownUsages(oldCSR *certificates.CertificateSigningRequest) bool { switch { - case version == certificatesv1beta1.SchemeGroupVersion: - return true // compatibility with v1beta1 case oldCSR != nil && hasUnknownUsage(oldCSR.Spec.Usages): return true // compatibility with existing data default: @@ -539,10 +522,8 @@ func hasUnknownUsage(usages []certificates.KeyUsage) bool { return false } -func allowDuplicateUsages(version schema.GroupVersion, oldCSR *certificates.CertificateSigningRequest) bool { +func allowDuplicateUsages(oldCSR *certificates.CertificateSigningRequest) bool { switch { - case version == certificatesv1beta1.SchemeGroupVersion: - return true // compatibility with v1beta1 case oldCSR != nil && hasDuplicateUsage(oldCSR.Spec.Usages): return true // compatibility with existing data default: diff --git a/pkg/apis/certificates/validation/validation_test.go b/pkg/apis/certificates/validation/validation_test.go index 32cade47070..8ef876d895c 100644 --- a/pkg/apis/certificates/validation/validation_test.go +++ b/pkg/apis/certificates/validation/validation_test.go @@ -29,12 +29,10 @@ import ( "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/client-go/util/certificate/csr" capi "k8s.io/kubernetes/pkg/apis/certificates" - capiv1beta1 "k8s.io/kubernetes/pkg/apis/certificates/v1beta1" "k8s.io/kubernetes/pkg/apis/core" "k8s.io/utils/pointer" ) @@ -54,7 +52,6 @@ func TestValidateCertificateSigningRequestCreate(t *testing.T) { maxLengthSignerName := fmt.Sprintf("%s/%s.%s", maxLengthFQDN, repeatString("a", 63), repeatString("a", 253)) tests := map[string]struct { csr capi.CertificateSigningRequest - gv schema.GroupVersion errs field.ErrorList }{ "CSR with empty request data should fail": { @@ -342,19 +339,7 @@ func TestValidateCertificateSigningRequestCreate(t *testing.T) { field.Required(specPath.Child("usages"), "usages must be provided"), }, }, - "unknown and duplicate usages - v1beta1": { - gv: schema.GroupVersion{Group: capi.SchemeGroupVersion.Group, Version: "v1beta1"}, - csr: capi.CertificateSigningRequest{ - ObjectMeta: validObjectMeta, - Spec: capi.CertificateSigningRequestSpec{ - Usages: []capi.KeyUsage{"unknown", "unknown"}, - Request: newCSRPEM(t), - SignerName: validSignerName, - }, - }, - }, - "unknown and duplicate usages - v1": { - gv: schema.GroupVersion{Group: capi.SchemeGroupVersion.Group, Version: "v1"}, + "unknown and duplicate usages": { csr: capi.CertificateSigningRequest{ ObjectMeta: validObjectMeta, Spec: capi.CertificateSigningRequestSpec{ @@ -372,7 +357,7 @@ func TestValidateCertificateSigningRequestCreate(t *testing.T) { } for name, test := range tests { t.Run(name, func(t *testing.T) { - el := ValidateCertificateSigningRequestCreate(&test.csr, test.gv) + el := ValidateCertificateSigningRequestCreate(&test.csr) if !reflect.DeepEqual(el, test.errs) { t.Errorf("returned and expected errors did not match - expected\n%v\nbut got\n%v", test.errs.ToAggregate(), el.ToAggregate()) } @@ -420,59 +405,23 @@ func newCSRPEM(t *testing.T) []byte { func Test_getValidationOptions(t *testing.T) { tests := []struct { - name string - version schema.GroupVersion - newCSR *capi.CertificateSigningRequest - oldCSR *capi.CertificateSigningRequest - want certificateValidationOptions + name string + newCSR *capi.CertificateSigningRequest + oldCSR *capi.CertificateSigningRequest + want certificateValidationOptions }{ { - name: "v1beta1 compatible create", - version: capiv1beta1.SchemeGroupVersion, - oldCSR: nil, - want: certificateValidationOptions{ - allowResettingCertificate: true, - allowBothApprovedAndDenied: false, - allowLegacySignerName: true, - allowDuplicateConditionTypes: true, - allowEmptyConditionType: true, - allowArbitraryCertificate: true, - allowUnknownUsages: true, - allowDuplicateUsages: true, - }, + name: "strict create", + oldCSR: nil, + want: certificateValidationOptions{}, }, { - name: "v1 strict create", - version: schema.GroupVersion{Group: "certificates.k8s.io", Version: "v1"}, - oldCSR: nil, - want: certificateValidationOptions{}, + name: "strict update", + oldCSR: &capi.CertificateSigningRequest{}, + want: certificateValidationOptions{}, }, { - name: "v1beta1 compatible update", - version: capiv1beta1.SchemeGroupVersion, - oldCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{ - Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved}, {Type: capi.CertificateDenied}}, - }}, - want: certificateValidationOptions{ - allowResettingCertificate: true, - allowBothApprovedAndDenied: true, // existing object has both approved and denied - allowLegacySignerName: true, - allowDuplicateConditionTypes: true, - allowEmptyConditionType: true, - allowArbitraryCertificate: true, - allowUnknownUsages: true, - allowDuplicateUsages: true, - }, - }, - { - name: "v1 strict update", - version: schema.GroupVersion{Group: "certificates.k8s.io", Version: "v1"}, - oldCSR: &capi.CertificateSigningRequest{}, - want: certificateValidationOptions{}, - }, - { - name: "v1 compatible update, approved+denied", - version: schema.GroupVersion{Group: "certificates.k8s.io", Version: "v1"}, + name: "compatible update, approved+denied", oldCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{ Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved}, {Type: capi.CertificateDenied}}, }}, @@ -481,16 +430,14 @@ func Test_getValidationOptions(t *testing.T) { }, }, { - name: "v1 compatible update, legacy signerName", - version: schema.GroupVersion{Group: "certificates.k8s.io", Version: "v1"}, - oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{SignerName: capi.LegacyUnknownSignerName}}, + name: "compatible update, legacy signerName", + oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{SignerName: capi.LegacyUnknownSignerName}}, want: certificateValidationOptions{ allowLegacySignerName: true, }, }, { - name: "v1 compatible update, duplicate condition types", - version: schema.GroupVersion{Group: "certificates.k8s.io", Version: "v1"}, + name: "compatible update, duplicate condition types", oldCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{ Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved}, {Type: capi.CertificateApproved}}, }}, @@ -499,8 +446,7 @@ func Test_getValidationOptions(t *testing.T) { }, }, { - name: "v1 compatible update, empty condition types", - version: schema.GroupVersion{Group: "certificates.k8s.io", Version: "v1"}, + name: "compatible update, empty condition types", oldCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{ Conditions: []capi.CertificateSigningRequestCondition{{}}, }}, @@ -509,8 +455,7 @@ func Test_getValidationOptions(t *testing.T) { }, }, { - name: "v1 compatible update, no diff to certificate", - version: schema.GroupVersion{Group: "certificates.k8s.io", Version: "v1"}, + name: "compatible update, no diff to certificate", newCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{ Certificate: validCertificate, }}, @@ -522,8 +467,7 @@ func Test_getValidationOptions(t *testing.T) { }, }, { - name: "v1 compatible update, existing invalid certificate", - version: schema.GroupVersion{Group: "certificates.k8s.io", Version: "v1"}, + name: "compatible update, existing invalid certificate", newCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{ Certificate: []byte(`new - no PEM blocks`), }}, @@ -535,17 +479,15 @@ func Test_getValidationOptions(t *testing.T) { }, }, { - name: "v1 compatible update, existing unknown usages", - version: schema.GroupVersion{Group: "certificates.k8s.io", Version: "v1"}, - oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{Usages: []capi.KeyUsage{"unknown"}}}, + name: "compatible update, existing unknown usages", + oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{Usages: []capi.KeyUsage{"unknown"}}}, want: certificateValidationOptions{ allowUnknownUsages: true, }, }, { - name: "v1 compatible update, existing duplicate usages", - version: schema.GroupVersion{Group: "certificates.k8s.io", Version: "v1"}, - oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{Usages: []capi.KeyUsage{"any", "any"}}}, + name: "compatible update, existing duplicate usages", + oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{Usages: []capi.KeyUsage{"any", "any"}}}, want: certificateValidationOptions{ allowDuplicateUsages: true, }, @@ -553,7 +495,7 @@ func Test_getValidationOptions(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := getValidationOptions(tt.version, tt.newCSR, tt.oldCSR); !reflect.DeepEqual(got, tt.want) { + if got := getValidationOptions(tt.newCSR, tt.oldCSR); !reflect.DeepEqual(got, tt.want) { t.Errorf("got %#v\nwant %#v", got, tt.want) } }) @@ -574,10 +516,10 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) { } tests := []struct { - name string - newCSR *capi.CertificateSigningRequest - oldCSR *capi.CertificateSigningRequest - versionErrs map[string][]string + name string + newCSR *capi.CertificateSigningRequest + oldCSR *capi.CertificateSigningRequest + errs []string }{ { name: "no-op", @@ -595,9 +537,8 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) { Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}}, }}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, - versionErrs: map[string][]string{ - "v1": {`status.conditions: Forbidden: updates may not add a condition of type "Approved"`}, - "v1beta1": {`status.conditions: Forbidden: updates may not add a condition of type "Approved"`}, + errs: []string{ + `status.conditions: Forbidden: updates may not add a condition of type "Approved"`, }, }, { @@ -606,9 +547,8 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) { oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}}, }}, - versionErrs: map[string][]string{ - "v1": {`status.conditions: Forbidden: updates may not remove a condition of type "Approved"`}, - "v1beta1": {`status.conditions: Forbidden: updates may not remove a condition of type "Approved"`}, + errs: []string{ + `status.conditions: Forbidden: updates may not remove a condition of type "Approved"`, }, }, { @@ -617,9 +557,8 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) { Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}}, }}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, - versionErrs: map[string][]string{ - "v1": {`status.conditions: Forbidden: updates may not add a condition of type "Denied"`}, - "v1beta1": {`status.conditions: Forbidden: updates may not add a condition of type "Denied"`}, + errs: []string{ + `status.conditions: Forbidden: updates may not add a condition of type "Denied"`, }, }, { @@ -628,9 +567,8 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) { oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}}, }}, - versionErrs: map[string][]string{ - "v1": {`status.conditions: Forbidden: updates may not remove a condition of type "Denied"`}, - "v1beta1": {`status.conditions: Forbidden: updates may not remove a condition of type "Denied"`}, + errs: []string{ + `status.conditions: Forbidden: updates may not remove a condition of type "Denied"`, }, }, { @@ -638,8 +576,8 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) { newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}}, }}, - oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, - versionErrs: map[string][]string{}, + oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, + errs: []string{}, }, { name: "remove Failed condition", @@ -647,9 +585,8 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) { oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}}, }}, - versionErrs: map[string][]string{ - "v1": {`status.conditions: Forbidden: updates may not remove a condition of type "Failed"`}, - "v1beta1": {`status.conditions: Forbidden: updates may not remove a condition of type "Failed"`}, + errs: []string{ + `status.conditions: Forbidden: updates may not remove a condition of type "Failed"`, }, }, { @@ -658,29 +595,26 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) { Certificate: validCertificate, }}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, - versionErrs: map[string][]string{ - "v1": {`status.certificate: Forbidden: updates may not set certificate content`}, - "v1beta1": {`status.certificate: Forbidden: updates may not set certificate content`}, + errs: []string{ + `status.certificate: Forbidden: updates may not set certificate content`, }, }, } for _, tt := range tests { - for _, version := range []string{"v1", "v1beta1"} { - t.Run(tt.name+"_"+version, func(t *testing.T) { - gotErrs := sets.NewString() - for _, err := range ValidateCertificateSigningRequestUpdate(tt.newCSR, tt.oldCSR, schema.GroupVersion{Group: capi.GroupName, Version: version}) { - gotErrs.Insert(err.Error()) - } - wantErrs := sets.NewString(tt.versionErrs[version]...) - for _, missing := range wantErrs.Difference(gotErrs).List() { - t.Errorf("missing expected error: %s", missing) - } - for _, unexpected := range gotErrs.Difference(wantErrs).List() { - t.Errorf("unexpected error: %s", unexpected) - } - }) - } + t.Run(tt.name, func(t *testing.T) { + gotErrs := sets.NewString() + for _, err := range ValidateCertificateSigningRequestUpdate(tt.newCSR, tt.oldCSR) { + gotErrs.Insert(err.Error()) + } + wantErrs := sets.NewString(tt.errs...) + for _, missing := range wantErrs.Difference(gotErrs).List() { + t.Errorf("missing expected error: %s", missing) + } + for _, unexpected := range gotErrs.Difference(wantErrs).List() { + t.Errorf("unexpected error: %s", unexpected) + } + }) } } @@ -698,10 +632,10 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) { } tests := []struct { - name string - newCSR *capi.CertificateSigningRequest - oldCSR *capi.CertificateSigningRequest - versionErrs map[string][]string + name string + newCSR *capi.CertificateSigningRequest + oldCSR *capi.CertificateSigningRequest + errs []string }{ { name: "no-op", @@ -732,9 +666,8 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) { Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}}, }}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, - versionErrs: map[string][]string{ - "v1": {`status.conditions: Forbidden: updates may not add a condition of type "Approved"`}, - "v1beta1": {`status.conditions: Forbidden: updates may not add a condition of type "Approved"`}, + errs: []string{ + `status.conditions: Forbidden: updates may not add a condition of type "Approved"`, }, }, { @@ -743,9 +676,8 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) { oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}}, }}, - versionErrs: map[string][]string{ - "v1": {`status.conditions: Forbidden: updates may not remove a condition of type "Approved"`}, - "v1beta1": {`status.conditions: Forbidden: updates may not remove a condition of type "Approved"`}, + errs: []string{ + `status.conditions: Forbidden: updates may not remove a condition of type "Approved"`, }, }, { @@ -754,9 +686,8 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) { Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}}, }}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, - versionErrs: map[string][]string{ - "v1": {`status.conditions: Forbidden: updates may not add a condition of type "Denied"`}, - "v1beta1": {`status.conditions: Forbidden: updates may not add a condition of type "Denied"`}, + errs: []string{ + `status.conditions: Forbidden: updates may not add a condition of type "Denied"`, }, }, { @@ -765,9 +696,8 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) { oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}}, }}, - versionErrs: map[string][]string{ - "v1": {`status.conditions: Forbidden: updates may not remove a condition of type "Denied"`}, - "v1beta1": {`status.conditions: Forbidden: updates may not remove a condition of type "Denied"`}, + errs: []string{ + `status.conditions: Forbidden: updates may not remove a condition of type "Denied"`, }, }, { @@ -775,8 +705,8 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) { newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}}, }}, - oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, - versionErrs: map[string][]string{}, + oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, + errs: []string{}, }, { name: "remove Failed condition", @@ -784,9 +714,8 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) { oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}}, }}, - versionErrs: map[string][]string{ - "v1": {`status.conditions: Forbidden: updates may not remove a condition of type "Failed"`}, - "v1beta1": {`status.conditions: Forbidden: updates may not remove a condition of type "Failed"`}, + errs: []string{ + `status.conditions: Forbidden: updates may not remove a condition of type "Failed"`, }, }, { @@ -794,8 +723,8 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) { newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ Certificate: validCertificate, }}, - oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, - versionErrs: map[string][]string{}, + oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, + errs: []string{}, }, { name: "set invalid certificate", @@ -803,8 +732,8 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) { Certificate: invalidCertificateNoPEM, }}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, - versionErrs: map[string][]string{ - "v1": {`status.certificate: Invalid value: "": must contain at least one CERTIFICATE PEM block`}, + errs: []string{ + `status.certificate: Invalid value: "": must contain at least one CERTIFICATE PEM block`, }, }, { @@ -815,28 +744,26 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) { oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ Certificate: invalidCertificateNoPEM, }}, - versionErrs: map[string][]string{ - "v1": {`status.certificate: Forbidden: updates may not modify existing certificate content`}, + errs: []string{ + `status.certificate: Forbidden: updates may not modify existing certificate content`, }, }, } for _, tt := range tests { - for _, version := range []string{"v1", "v1beta1"} { - t.Run(tt.name+"_"+version, func(t *testing.T) { - gotErrs := sets.NewString() - for _, err := range ValidateCertificateSigningRequestStatusUpdate(tt.newCSR, tt.oldCSR, schema.GroupVersion{Group: capi.GroupName, Version: version}) { - gotErrs.Insert(err.Error()) - } - wantErrs := sets.NewString(tt.versionErrs[version]...) - for _, missing := range wantErrs.Difference(gotErrs).List() { - t.Errorf("missing expected error: %s", missing) - } - for _, unexpected := range gotErrs.Difference(wantErrs).List() { - t.Errorf("unexpected error: %s", unexpected) - } - }) - } + t.Run(tt.name, func(t *testing.T) { + gotErrs := sets.NewString() + for _, err := range ValidateCertificateSigningRequestStatusUpdate(tt.newCSR, tt.oldCSR) { + gotErrs.Insert(err.Error()) + } + wantErrs := sets.NewString(tt.errs...) + for _, missing := range wantErrs.Difference(gotErrs).List() { + t.Errorf("missing expected error: %s", missing) + } + for _, unexpected := range gotErrs.Difference(wantErrs).List() { + t.Errorf("unexpected error: %s", unexpected) + } + }) } } @@ -854,10 +781,10 @@ func TestValidateCertificateSigningRequestApprovalUpdate(t *testing.T) { } tests := []struct { - name string - newCSR *capi.CertificateSigningRequest - oldCSR *capi.CertificateSigningRequest - versionErrs map[string][]string + name string + newCSR *capi.CertificateSigningRequest + oldCSR *capi.CertificateSigningRequest + errs []string }{ { name: "no-op", @@ -882,9 +809,8 @@ func TestValidateCertificateSigningRequestApprovalUpdate(t *testing.T) { oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}}, }}, - versionErrs: map[string][]string{ - "v1": {`status.conditions: Forbidden: updates may not remove a condition of type "Approved"`}, - "v1beta1": {`status.conditions: Forbidden: updates may not remove a condition of type "Approved"`}, + errs: []string{ + `status.conditions: Forbidden: updates may not remove a condition of type "Approved"`, }, }, { @@ -900,9 +826,8 @@ func TestValidateCertificateSigningRequestApprovalUpdate(t *testing.T) { oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}}, }}, - versionErrs: map[string][]string{ - "v1": {`status.conditions: Forbidden: updates may not remove a condition of type "Denied"`}, - "v1beta1": {`status.conditions: Forbidden: updates may not remove a condition of type "Denied"`}, + errs: []string{ + `status.conditions: Forbidden: updates may not remove a condition of type "Denied"`, }, }, { @@ -910,8 +835,8 @@ func TestValidateCertificateSigningRequestApprovalUpdate(t *testing.T) { newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}}, }}, - oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, - versionErrs: map[string][]string{}, + oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, + errs: []string{}, }, { name: "remove Failed condition", @@ -919,9 +844,8 @@ func TestValidateCertificateSigningRequestApprovalUpdate(t *testing.T) { oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}}, }}, - versionErrs: map[string][]string{ - "v1": {`status.conditions: Forbidden: updates may not remove a condition of type "Failed"`}, - "v1beta1": {`status.conditions: Forbidden: updates may not remove a condition of type "Failed"`}, + errs: []string{ + `status.conditions: Forbidden: updates may not remove a condition of type "Failed"`, }, }, { @@ -930,29 +854,26 @@ func TestValidateCertificateSigningRequestApprovalUpdate(t *testing.T) { Certificate: validCertificate, }}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, - versionErrs: map[string][]string{ - "v1": {`status.certificate: Forbidden: updates may not set certificate content`}, - "v1beta1": {`status.certificate: Forbidden: updates may not set certificate content`}, + errs: []string{ + `status.certificate: Forbidden: updates may not set certificate content`, }, }, } for _, tt := range tests { - for _, version := range []string{"v1", "v1beta1"} { - t.Run(tt.name+"_"+version, func(t *testing.T) { - gotErrs := sets.NewString() - for _, err := range ValidateCertificateSigningRequestApprovalUpdate(tt.newCSR, tt.oldCSR, schema.GroupVersion{Group: capi.GroupName, Version: version}) { - gotErrs.Insert(err.Error()) - } - wantErrs := sets.NewString(tt.versionErrs[version]...) - for _, missing := range wantErrs.Difference(gotErrs).List() { - t.Errorf("missing expected error: %s", missing) - } - for _, unexpected := range gotErrs.Difference(wantErrs).List() { - t.Errorf("unexpected error: %s", unexpected) - } - }) - } + t.Run(tt.name, func(t *testing.T) { + gotErrs := sets.NewString() + for _, err := range ValidateCertificateSigningRequestApprovalUpdate(tt.newCSR, tt.oldCSR) { + gotErrs.Insert(err.Error()) + } + wantErrs := sets.NewString(tt.errs...) + for _, missing := range wantErrs.Difference(gotErrs).List() { + t.Errorf("missing expected error: %s", missing) + } + for _, unexpected := range gotErrs.Difference(wantErrs).List() { + t.Errorf("unexpected error: %s", unexpected) + } + }) } } diff --git a/pkg/apis/networking/validation/validation.go b/pkg/apis/networking/validation/validation.go index 2091a2cff2e..ccccea6ec43 100644 --- a/pkg/apis/networking/validation/validation.go +++ b/pkg/apis/networking/validation/validation.go @@ -21,12 +21,9 @@ import ( "net" "strings" - extensionsv1beta1 "k8s.io/api/extensions/v1beta1" - networkingv1beta1 "k8s.io/api/networking/v1beta1" apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" pathvalidation "k8s.io/apimachinery/pkg/api/validation/path" unversionedvalidation "k8s.io/apimachinery/pkg/apis/meta/v1/validation" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation" @@ -230,20 +227,20 @@ type IngressValidationOptions struct { } // ValidateIngress validates Ingresses on create and update. -func validateIngress(ingress *networking.Ingress, opts IngressValidationOptions, requestGV schema.GroupVersion) field.ErrorList { +func validateIngress(ingress *networking.Ingress, opts IngressValidationOptions) field.ErrorList { allErrs := apivalidation.ValidateObjectMeta(&ingress.ObjectMeta, true, ValidateIngressName, field.NewPath("metadata")) - allErrs = append(allErrs, ValidateIngressSpec(&ingress.Spec, field.NewPath("spec"), opts, requestGV)...) + allErrs = append(allErrs, ValidateIngressSpec(&ingress.Spec, field.NewPath("spec"), opts)...) return allErrs } // ValidateIngressCreate validates Ingresses on create. -func ValidateIngressCreate(ingress *networking.Ingress, requestGV schema.GroupVersion) field.ErrorList { +func ValidateIngressCreate(ingress *networking.Ingress) field.ErrorList { allErrs := field.ErrorList{} opts := IngressValidationOptions{ - AllowInvalidSecretName: allowInvalidSecretName(requestGV, nil), - AllowInvalidWildcardHostRule: allowInvalidWildcardHostRule(requestGV, nil), + AllowInvalidSecretName: false, + AllowInvalidWildcardHostRule: false, } - allErrs = append(allErrs, validateIngress(ingress, opts, requestGV)...) + allErrs = append(allErrs, validateIngress(ingress, opts)...) annotationVal, annotationIsSet := ingress.Annotations[annotationIngressClass] if annotationIsSet && ingress.Spec.IngressClassName != nil { annotationPath := field.NewPath("annotations").Child(annotationIngressClass) @@ -253,14 +250,14 @@ func ValidateIngressCreate(ingress *networking.Ingress, requestGV schema.GroupVe } // ValidateIngressUpdate validates ingresses on update. -func ValidateIngressUpdate(ingress, oldIngress *networking.Ingress, requestGV schema.GroupVersion) field.ErrorList { +func ValidateIngressUpdate(ingress, oldIngress *networking.Ingress) field.ErrorList { allErrs := apivalidation.ValidateObjectMetaUpdate(&ingress.ObjectMeta, &oldIngress.ObjectMeta, field.NewPath("metadata")) opts := IngressValidationOptions{ - AllowInvalidSecretName: allowInvalidSecretName(requestGV, oldIngress), - AllowInvalidWildcardHostRule: allowInvalidWildcardHostRule(requestGV, oldIngress), + AllowInvalidSecretName: allowInvalidSecretName(oldIngress), + AllowInvalidWildcardHostRule: allowInvalidWildcardHostRule(oldIngress), } - allErrs = append(allErrs, validateIngress(ingress, opts, requestGV)...) + allErrs = append(allErrs, validateIngress(ingress, opts)...) return allErrs } @@ -291,29 +288,18 @@ func validateIngressTLS(spec *networking.IngressSpec, fldPath *field.Path, opts return allErrs } -// defaultBackendFieldName returns the name of the field used for defaultBackend -// in the provided GroupVersion. -func defaultBackendFieldName(gv schema.GroupVersion) string { - switch gv { - case networkingv1beta1.SchemeGroupVersion, extensionsv1beta1.SchemeGroupVersion: - return "backend" - default: - return "defaultBackend" - } -} - // ValidateIngressSpec tests if required fields in the IngressSpec are set. -func ValidateIngressSpec(spec *networking.IngressSpec, fldPath *field.Path, opts IngressValidationOptions, requestGV schema.GroupVersion) field.ErrorList { +func ValidateIngressSpec(spec *networking.IngressSpec, fldPath *field.Path, opts IngressValidationOptions) field.ErrorList { allErrs := field.ErrorList{} if len(spec.Rules) == 0 && spec.DefaultBackend == nil { - errMsg := fmt.Sprintf("either `%s` or `rules` must be specified", defaultBackendFieldName(requestGV)) + errMsg := fmt.Sprintf("either `%s` or `rules` must be specified", "defaultBackend") allErrs = append(allErrs, field.Invalid(fldPath, spec.Rules, errMsg)) } if spec.DefaultBackend != nil { - allErrs = append(allErrs, validateIngressBackend(spec.DefaultBackend, fldPath.Child(defaultBackendFieldName(requestGV)), opts, requestGV)...) + allErrs = append(allErrs, validateIngressBackend(spec.DefaultBackend, fldPath.Child("defaultBackend"), opts)...) } if len(spec.Rules) > 0 { - allErrs = append(allErrs, validateIngressRules(spec.Rules, fldPath.Child("rules"), opts, requestGV)...) + allErrs = append(allErrs, validateIngressRules(spec.Rules, fldPath.Child("rules"), opts)...) } if len(spec.TLS) > 0 { allErrs = append(allErrs, validateIngressTLS(spec, fldPath.Child("tls"), opts)...) @@ -333,7 +319,7 @@ func ValidateIngressStatusUpdate(ingress, oldIngress *networking.Ingress) field. return allErrs } -func validateIngressRules(ingressRules []networking.IngressRule, fldPath *field.Path, opts IngressValidationOptions, requestGV schema.GroupVersion) field.ErrorList { +func validateIngressRules(ingressRules []networking.IngressRule, fldPath *field.Path, opts IngressValidationOptions) field.ErrorList { allErrs := field.ErrorList{} if len(ingressRules) == 0 { return append(allErrs, field.Required(fldPath, "")) @@ -359,32 +345,32 @@ func validateIngressRules(ingressRules []networking.IngressRule, fldPath *field. } if !wildcardHost || !opts.AllowInvalidWildcardHostRule { - allErrs = append(allErrs, validateIngressRuleValue(&ih.IngressRuleValue, fldPath.Index(i), opts, requestGV)...) + allErrs = append(allErrs, validateIngressRuleValue(&ih.IngressRuleValue, fldPath.Index(i), opts)...) } } return allErrs } -func validateIngressRuleValue(ingressRule *networking.IngressRuleValue, fldPath *field.Path, opts IngressValidationOptions, requestGV schema.GroupVersion) field.ErrorList { +func validateIngressRuleValue(ingressRule *networking.IngressRuleValue, fldPath *field.Path, opts IngressValidationOptions) field.ErrorList { allErrs := field.ErrorList{} if ingressRule.HTTP != nil { - allErrs = append(allErrs, validateHTTPIngressRuleValue(ingressRule.HTTP, fldPath.Child("http"), opts, requestGV)...) + allErrs = append(allErrs, validateHTTPIngressRuleValue(ingressRule.HTTP, fldPath.Child("http"), opts)...) } return allErrs } -func validateHTTPIngressRuleValue(httpIngressRuleValue *networking.HTTPIngressRuleValue, fldPath *field.Path, opts IngressValidationOptions, requestGV schema.GroupVersion) field.ErrorList { +func validateHTTPIngressRuleValue(httpIngressRuleValue *networking.HTTPIngressRuleValue, fldPath *field.Path, opts IngressValidationOptions) field.ErrorList { allErrs := field.ErrorList{} if len(httpIngressRuleValue.Paths) == 0 { allErrs = append(allErrs, field.Required(fldPath.Child("paths"), "")) } for i, path := range httpIngressRuleValue.Paths { - allErrs = append(allErrs, validateHTTPIngressPath(&path, fldPath.Child("paths").Index(i), opts, requestGV)...) + allErrs = append(allErrs, validateHTTPIngressPath(&path, fldPath.Child("paths").Index(i), opts)...) } return allErrs } -func validateHTTPIngressPath(path *networking.HTTPIngressPath, fldPath *field.Path, opts IngressValidationOptions, requestGV schema.GroupVersion) field.ErrorList { +func validateHTTPIngressPath(path *networking.HTTPIngressPath, fldPath *field.Path, opts IngressValidationOptions) field.ErrorList { allErrs := field.ErrorList{} if path.PathType == nil { @@ -418,45 +404,12 @@ func validateHTTPIngressPath(path *networking.HTTPIngressPath, fldPath *field.Pa default: allErrs = append(allErrs, field.NotSupported(fldPath.Child("pathType"), *path.PathType, supportedPathTypes.List())) } - allErrs = append(allErrs, validateIngressBackend(&path.Backend, fldPath.Child("backend"), opts, requestGV)...) + allErrs = append(allErrs, validateIngressBackend(&path.Backend, fldPath.Child("backend"), opts)...) return allErrs } -// numberPortField returns the field path to a service port number field -// relative to a backend struct in the provided GroupVersion -func numberPortField(numberPortFieldPath *field.Path, gv schema.GroupVersion) *field.Path { - switch gv { - case networkingv1beta1.SchemeGroupVersion, extensionsv1beta1.SchemeGroupVersion: - return numberPortFieldPath.Child("servicePort") - default: - return numberPortFieldPath.Child("service", "port", "number") - } -} - -// namedPortField returns the field path to a service port name field -// relative to a backend struct in the provided GroupVersion -func namedPortField(namedPortFieldPath *field.Path, gv schema.GroupVersion) *field.Path { - switch gv { - case networkingv1beta1.SchemeGroupVersion, extensionsv1beta1.SchemeGroupVersion: - return namedPortFieldPath.Child("servicePort") - default: - return namedPortFieldPath.Child("service", "port", "name") - } -} - -// serviceNameFieldPath returns the name of the field used for a -// service name in the provided GroupVersion. -func serviceNameFieldPath(backendFieldPath *field.Path, gv schema.GroupVersion) *field.Path { - switch gv { - case networkingv1beta1.SchemeGroupVersion, extensionsv1beta1.SchemeGroupVersion: - return backendFieldPath.Child("serviceName") - default: - return backendFieldPath.Child("service", "name") - } -} - // validateIngressBackend tests if a given backend is valid. -func validateIngressBackend(backend *networking.IngressBackend, fldPath *field.Path, opts IngressValidationOptions, requestGV schema.GroupVersion) field.ErrorList { +func validateIngressBackend(backend *networking.IngressBackend, fldPath *field.Path, opts IngressValidationOptions) field.ErrorList { allErrs := field.ErrorList{} hasResourceBackend := backend.Resource != nil @@ -470,10 +423,10 @@ func validateIngressBackend(backend *networking.IngressBackend, fldPath *field.P case hasServiceBackend: if len(backend.Service.Name) == 0 { - allErrs = append(allErrs, field.Required(serviceNameFieldPath(fldPath, requestGV), "")) + allErrs = append(allErrs, field.Required(fldPath.Child("service", "name"), "")) } else { for _, msg := range apivalidation.ValidateServiceName(backend.Service.Name, false) { - allErrs = append(allErrs, field.Invalid(serviceNameFieldPath(fldPath, requestGV), backend.Service.Name, msg)) + allErrs = append(allErrs, field.Invalid(fldPath.Child("service", "name"), backend.Service.Name, msg)) } } @@ -483,11 +436,11 @@ func validateIngressBackend(backend *networking.IngressBackend, fldPath *field.P allErrs = append(allErrs, field.Invalid(fldPath, "", "cannot set both port name & port number")) } else if hasPortName { for _, msg := range validation.IsValidPortName(backend.Service.Port.Name) { - allErrs = append(allErrs, field.Invalid(namedPortField(fldPath, requestGV), backend.Service.Port.Name, msg)) + allErrs = append(allErrs, field.Invalid(fldPath.Child("service", "port", "name"), backend.Service.Port.Name, msg)) } } else if hasPortNumber { for _, msg := range validation.IsValidPortNum(int(backend.Service.Port.Number)) { - allErrs = append(allErrs, field.Invalid(numberPortField(fldPath, requestGV), backend.Service.Port.Number, msg)) + allErrs = append(allErrs, field.Invalid(fldPath.Child("service", "port", "number"), backend.Service.Port.Number, msg)) } } else { allErrs = append(allErrs, field.Required(fldPath, "port name or number is required")) @@ -616,11 +569,7 @@ func validateIngressClassParametersReference(params *networking.IngressClassPara return allErrs } -func allowInvalidSecretName(gv schema.GroupVersion, oldIngress *networking.Ingress) bool { - if gv == networkingv1beta1.SchemeGroupVersion || gv == extensionsv1beta1.SchemeGroupVersion { - // backwards compatibility with released API versions that allowed invalid names - return true - } +func allowInvalidSecretName(oldIngress *networking.Ingress) bool { if oldIngress != nil { for _, tls := range oldIngress.Spec.TLS { if len(validateTLSSecretName(tls.SecretName)) > 0 { @@ -639,14 +588,10 @@ func validateTLSSecretName(name string) []string { return apivalidation.ValidateSecretName(name, false) } -func allowInvalidWildcardHostRule(gv schema.GroupVersion, oldIngress *networking.Ingress) bool { - if gv == networkingv1beta1.SchemeGroupVersion || gv == extensionsv1beta1.SchemeGroupVersion { - // backwards compatibility with released API versions that allowed invalid rules - return true - } +func allowInvalidWildcardHostRule(oldIngress *networking.Ingress) bool { if oldIngress != nil { for _, rule := range oldIngress.Spec.Rules { - if strings.Contains(rule.Host, "*") && len(validateIngressRuleValue(&rule.IngressRuleValue, nil, IngressValidationOptions{}, gv)) > 0 { + if strings.Contains(rule.Host, "*") && len(validateIngressRuleValue(&rule.IngressRuleValue, nil, IngressValidationOptions{})) > 0 { // backwards compatibility with existing invalid data return true } diff --git a/pkg/apis/networking/validation/validation_test.go b/pkg/apis/networking/validation/validation_test.go index badac5de7d1..2201d81c093 100644 --- a/pkg/apis/networking/validation/validation_test.go +++ b/pkg/apis/networking/validation/validation_test.go @@ -21,11 +21,8 @@ import ( "strings" "testing" - networkingv1 "k8s.io/api/networking/v1" - networkingv1beta1 "k8s.io/api/networking/v1beta1" apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/validation/field" utilfeature "k8s.io/apiserver/pkg/util/feature" @@ -514,7 +511,6 @@ func TestValidateIngress(t *testing.T) { } testCases := map[string]struct { - groupVersion *schema.GroupVersion tweakIngress func(ing *networking.Ingress) expectErrsOnFields []string }{ @@ -531,13 +527,12 @@ func TestValidateIngress(t *testing.T) { expectErrsOnFields: []string{}, }, // invalid use cases - "backend (v1beta1) with no service": { - groupVersion: &networkingv1beta1.SchemeGroupVersion, + "backend with no service": { tweakIngress: func(ing *networking.Ingress) { ing.Spec.DefaultBackend.Service.Name = "" }, expectErrsOnFields: []string{ - "spec.backend.serviceName", + "spec.defaultBackend.service.name", }, }, "invalid path type": { @@ -654,7 +649,6 @@ func TestValidateIngress(t *testing.T) { }, }, "spec.backend resource and service name are not allowed together": { - groupVersion: &networkingv1beta1.SchemeGroupVersion, tweakIngress: func(ing *networking.Ingress) { ing.Spec.DefaultBackend = &networking.IngressBackend{ Service: serviceBackend, @@ -666,11 +660,10 @@ func TestValidateIngress(t *testing.T) { } }, expectErrsOnFields: []string{ - "spec.backend", + "spec.defaultBackend", }, }, "spec.backend resource and service port are not allowed together": { - groupVersion: &networkingv1beta1.SchemeGroupVersion, tweakIngress: func(ing *networking.Ingress) { ing.Spec.DefaultBackend = &networking.IngressBackend{ Service: serviceBackend, @@ -682,7 +675,7 @@ func TestValidateIngress(t *testing.T) { } }, expectErrsOnFields: []string{ - "spec.backend", + "spec.defaultBackend", }, }, } @@ -691,11 +684,7 @@ func TestValidateIngress(t *testing.T) { t.Run(name, func(t *testing.T) { ingress := baseIngress.DeepCopy() testCase.tweakIngress(ingress) - gv := testCase.groupVersion - if gv == nil { - gv = &networkingv1.SchemeGroupVersion - } - errs := validateIngress(ingress, IngressValidationOptions{}, *gv) + errs := validateIngress(ingress, IngressValidationOptions{}) if len(testCase.expectErrsOnFields) != len(errs) { t.Fatalf("Expected %d errors, got %d errors: %v", len(testCase.expectErrsOnFields), len(errs), errs) } @@ -718,7 +707,6 @@ func TestValidateIngressRuleValue(t *testing.T) { } fldPath := field.NewPath("testing.http.paths[0].path") testCases := map[string]struct { - groupVersion *schema.GroupVersion pathType networking.PathType path string expectedErrs field.ErrorList @@ -820,11 +808,7 @@ func TestValidateIngressRuleValue(t *testing.T) { }, }, } - gv := testCase.groupVersion - if gv == nil { - gv = &networkingv1.SchemeGroupVersion - } - errs := validateIngressRuleValue(irv, field.NewPath("testing"), IngressValidationOptions{}, *gv) + errs := validateIngressRuleValue(irv, field.NewPath("testing"), IngressValidationOptions{}) if len(errs) != len(testCase.expectedErrs) { t.Fatalf("Expected %d errors, got %d (%+v)", len(testCase.expectedErrs), len(errs), errs) } @@ -868,7 +852,6 @@ func TestValidateIngressCreate(t *testing.T) { } testCases := map[string]struct { - groupVersion *schema.GroupVersion tweakIngress func(ingress *networking.Ingress) expectedErrs field.ErrorList }{ @@ -950,33 +933,18 @@ func TestValidateIngressCreate(t *testing.T) { }, expectedErrs: field.ErrorList{}, }, - "v1: valid secret": { - groupVersion: &networkingv1.SchemeGroupVersion, + "valid secret": { tweakIngress: func(ingress *networking.Ingress) { ingress.Spec.TLS = []networking.IngressTLS{{SecretName: "valid"}} }, }, - "v1: invalid secret": { - groupVersion: &networkingv1.SchemeGroupVersion, + "invalid secret": { tweakIngress: func(ingress *networking.Ingress) { ingress.Spec.TLS = []networking.IngressTLS{{SecretName: "invalid name"}} }, expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec").Child("tls").Index(0).Child("secretName"), "invalid name", `a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')`)}, }, - "v1beta1: valid secret": { - groupVersion: &networkingv1beta1.SchemeGroupVersion, - tweakIngress: func(ingress *networking.Ingress) { - ingress.Spec.TLS = []networking.IngressTLS{{SecretName: "valid"}} - }, - }, - "v1beta1: invalid secret": { - groupVersion: &networkingv1beta1.SchemeGroupVersion, - tweakIngress: func(ingress *networking.Ingress) { - ingress.Spec.TLS = []networking.IngressTLS{{SecretName: "invalid name 1"}} - }, - }, - "v1: valid rules with wildcard host": { - groupVersion: &networkingv1.SchemeGroupVersion, + "valid rules with wildcard host": { tweakIngress: func(ingress *networking.Ingress) { ingress.Spec.TLS = []networking.IngressTLS{{Hosts: []string{"*.bar.com"}}} ingress.Spec.Rules = []networking.IngressRule{{ @@ -993,8 +961,7 @@ func TestValidateIngressCreate(t *testing.T) { }} }, }, - "v1: invalid rules with wildcard host": { - groupVersion: &networkingv1.SchemeGroupVersion, + "invalid rules with wildcard host": { tweakIngress: func(ingress *networking.Ingress) { ingress.Spec.TLS = []networking.IngressTLS{{Hosts: []string{"*.bar.com"}}} ingress.Spec.Rules = []networking.IngressRule{{ @@ -1012,53 +979,13 @@ func TestValidateIngressCreate(t *testing.T) { }, expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec").Child("rules").Index(0).Child("http").Child("paths").Index(0).Child("path"), "foo", `must be an absolute path`)}, }, - "v1beta1: valid rules with wildcard host": { - groupVersion: &networkingv1beta1.SchemeGroupVersion, - tweakIngress: func(ingress *networking.Ingress) { - ingress.Spec.TLS = []networking.IngressTLS{{Hosts: []string{"*.bar.com"}}} - ingress.Spec.Rules = []networking.IngressRule{{ - Host: "*.foo.com", - IngressRuleValue: networking.IngressRuleValue{ - HTTP: &networking.HTTPIngressRuleValue{ - Paths: []networking.HTTPIngressPath{{ - Path: "/foo", - PathType: &exactPathType, - Backend: defaultBackend, - }}, - }, - }, - }} - }, - }, - "v1beta1: invalid rules with wildcard host": { - groupVersion: &networkingv1beta1.SchemeGroupVersion, - tweakIngress: func(ingress *networking.Ingress) { - ingress.Spec.TLS = []networking.IngressTLS{{Hosts: []string{"*.bar.com"}}} - ingress.Spec.Rules = []networking.IngressRule{{ - Host: "*.foo.com", - IngressRuleValue: networking.IngressRuleValue{ - HTTP: &networking.HTTPIngressRuleValue{ - Paths: []networking.HTTPIngressPath{{ - Path: "foo", - PathType: &exactPathType, - Backend: defaultBackend, - }}, - }, - }, - }} - }, - }, } for name, testCase := range testCases { t.Run(name, func(t *testing.T) { newIngress := baseIngress.DeepCopy() testCase.tweakIngress(newIngress) - gv := testCase.groupVersion - if gv == nil { - gv = &networkingv1.SchemeGroupVersion - } - errs := ValidateIngressCreate(newIngress, *gv) + errs := ValidateIngressCreate(newIngress) if len(errs) != len(testCase.expectedErrs) { t.Fatalf("Expected %d errors, got %d (%+v)", len(testCase.expectedErrs), len(errs), errs) } @@ -1101,7 +1028,6 @@ func TestValidateIngressUpdate(t *testing.T) { } testCases := map[string]struct { - gv schema.GroupVersion tweakIngresses func(newIngress, oldIngress *networking.Ingress) expectedErrs field.ErrorList }{ @@ -1385,37 +1311,20 @@ func TestValidateIngressUpdate(t *testing.T) { }, expectedErrs: field.ErrorList{}, }, - "v1: change valid secret -> invalid secret": { - gv: networkingv1.SchemeGroupVersion, + "change valid secret -> invalid secret": { tweakIngresses: func(newIngress, oldIngress *networking.Ingress) { oldIngress.Spec.TLS = []networking.IngressTLS{{SecretName: "valid"}} newIngress.Spec.TLS = []networking.IngressTLS{{SecretName: "invalid name"}} }, expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec").Child("tls").Index(0).Child("secretName"), "invalid name", `a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')`)}, }, - "v1: change invalid secret -> invalid secret": { - gv: networkingv1.SchemeGroupVersion, + "change invalid secret -> invalid secret": { tweakIngresses: func(newIngress, oldIngress *networking.Ingress) { oldIngress.Spec.TLS = []networking.IngressTLS{{SecretName: "invalid name 1"}} newIngress.Spec.TLS = []networking.IngressTLS{{SecretName: "invalid name 2"}} }, }, - "v1beta1: change valid secret -> invalid secret": { - gv: networkingv1beta1.SchemeGroupVersion, - tweakIngresses: func(newIngress, oldIngress *networking.Ingress) { - oldIngress.Spec.TLS = []networking.IngressTLS{{SecretName: "valid"}} - newIngress.Spec.TLS = []networking.IngressTLS{{SecretName: "invalid name"}} - }, - }, - "v1beta1: change invalid secret -> invalid secret": { - gv: networkingv1beta1.SchemeGroupVersion, - tweakIngresses: func(newIngress, oldIngress *networking.Ingress) { - oldIngress.Spec.TLS = []networking.IngressTLS{{SecretName: "invalid name 1"}} - newIngress.Spec.TLS = []networking.IngressTLS{{SecretName: "invalid name 2"}} - }, - }, - "v1: change valid rules with wildcard host -> invalid rules": { - gv: networkingv1.SchemeGroupVersion, + "change valid rules with wildcard host -> invalid rules": { tweakIngresses: func(newIngress, oldIngress *networking.Ingress) { oldIngress.Spec.TLS = []networking.IngressTLS{{Hosts: []string{"*.bar.com"}}} oldIngress.Spec.Rules = []networking.IngressRule{{ @@ -1446,70 +1355,7 @@ func TestValidateIngressUpdate(t *testing.T) { }, expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec").Child("rules").Index(0).Child("http").Child("paths").Index(0).Child("path"), "foo", `must be an absolute path`)}, }, - "v1: change invalid rules with wildcard host -> invalid rules": { - gv: networkingv1.SchemeGroupVersion, - tweakIngresses: func(newIngress, oldIngress *networking.Ingress) { - oldIngress.Spec.TLS = []networking.IngressTLS{{Hosts: []string{"*.bar.com"}}} - oldIngress.Spec.Rules = []networking.IngressRule{{ - Host: "*.foo.com", - IngressRuleValue: networking.IngressRuleValue{ - HTTP: &networking.HTTPIngressRuleValue{ - Paths: []networking.HTTPIngressPath{{ - Path: "foo", - PathType: &exactPathType, - Backend: defaultBackend, - }}, - }, - }, - }} - newIngress.Spec.TLS = []networking.IngressTLS{{Hosts: []string{"*.bar.com"}}} - newIngress.Spec.Rules = []networking.IngressRule{{ - Host: "*.foo.com", - IngressRuleValue: networking.IngressRuleValue{ - HTTP: &networking.HTTPIngressRuleValue{ - Paths: []networking.HTTPIngressPath{{ - Path: "bar", - PathType: &exactPathType, - Backend: defaultBackend, - }}, - }, - }, - }} - }, - }, - "v1beta1: change valid rules with wildcard host -> invalid rules": { - gv: networkingv1beta1.SchemeGroupVersion, - tweakIngresses: func(newIngress, oldIngress *networking.Ingress) { - oldIngress.Spec.TLS = []networking.IngressTLS{{Hosts: []string{"*.bar.com"}}} - oldIngress.Spec.Rules = []networking.IngressRule{{ - Host: "*.foo.com", - IngressRuleValue: networking.IngressRuleValue{ - HTTP: &networking.HTTPIngressRuleValue{ - Paths: []networking.HTTPIngressPath{{ - Path: "/foo", - PathType: &exactPathType, - Backend: defaultBackend, - }}, - }, - }, - }} - newIngress.Spec.TLS = []networking.IngressTLS{{Hosts: []string{"*.bar.com"}}} - newIngress.Spec.Rules = []networking.IngressRule{{ - Host: "*.foo.com", - IngressRuleValue: networking.IngressRuleValue{ - HTTP: &networking.HTTPIngressRuleValue{ - Paths: []networking.HTTPIngressPath{{ - Path: "foo", - PathType: &exactPathType, - Backend: defaultBackend, - }}, - }, - }, - }} - }, - }, - "v1beta1: change invalid rules with wildcard host -> invalid rules": { - gv: networkingv1beta1.SchemeGroupVersion, + "change invalid rules with wildcard host -> invalid rules": { tweakIngresses: func(newIngress, oldIngress *networking.Ingress) { oldIngress.Spec.TLS = []networking.IngressTLS{{Hosts: []string{"*.bar.com"}}} oldIngress.Spec.Rules = []networking.IngressRule{{ @@ -1547,11 +1393,7 @@ func TestValidateIngressUpdate(t *testing.T) { oldIngress := baseIngress.DeepCopy() testCase.tweakIngresses(newIngress, oldIngress) - gv := testCase.gv - if gv.Empty() { - gv = networkingv1beta1.SchemeGroupVersion - } - errs := ValidateIngressUpdate(newIngress, oldIngress, gv) + errs := ValidateIngressUpdate(newIngress, oldIngress) if len(errs) != len(testCase.expectedErrs) { t.Fatalf("Expected %d errors, got %d (%+v)", len(testCase.expectedErrs), len(errs), errs) @@ -1861,7 +1703,7 @@ func TestValidateIngressTLS(t *testing.T) { errorCases[badWildcardTLSErr] = badWildcardTLS for k, v := range errorCases { - errs := validateIngress(&v, IngressValidationOptions{}, networkingv1beta1.SchemeGroupVersion) + errs := validateIngress(&v, IngressValidationOptions{}) if len(errs) == 0 { t.Errorf("expected failure for %q", k) } else { @@ -1885,7 +1727,7 @@ func TestValidateIngressTLS(t *testing.T) { } validCases[fmt.Sprintf("spec.tls[0].hosts: Valid value: '%v'", wildHost)] = goodWildcardTLS for k, v := range validCases { - errs := validateIngress(&v, IngressValidationOptions{}, networkingv1beta1.SchemeGroupVersion) + errs := validateIngress(&v, IngressValidationOptions{}) if len(errs) != 0 { t.Errorf("expected success for %q", k) } @@ -1946,7 +1788,7 @@ func TestValidateEmptyIngressTLS(t *testing.T) { } validCases[fmt.Sprintf("spec.tls[0]: Valid value: %v", goodEmptyHosts.Spec.TLS[0])] = goodEmptyHosts for k, v := range validCases { - errs := validateIngress(&v, IngressValidationOptions{}, networkingv1beta1.SchemeGroupVersion) + errs := validateIngress(&v, IngressValidationOptions{}) if len(errs) != 0 { t.Errorf("expected success for %q", k) } diff --git a/pkg/controlplane/instance.go b/pkg/controlplane/instance.go index 606ccb921d6..944e7db79fd 100644 --- a/pkg/controlplane/instance.go +++ b/pkg/controlplane/instance.go @@ -26,42 +26,31 @@ import ( "time" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" - admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" apiserverinternalv1alpha1 "k8s.io/api/apiserverinternal/v1alpha1" appsv1 "k8s.io/api/apps/v1" authenticationv1 "k8s.io/api/authentication/v1" - authenticationv1beta1 "k8s.io/api/authentication/v1beta1" authorizationapiv1 "k8s.io/api/authorization/v1" - authorizationapiv1beta1 "k8s.io/api/authorization/v1beta1" autoscalingapiv1 "k8s.io/api/autoscaling/v1" autoscalingapiv2beta1 "k8s.io/api/autoscaling/v2beta1" autoscalingapiv2beta2 "k8s.io/api/autoscaling/v2beta2" batchapiv1 "k8s.io/api/batch/v1" batchapiv1beta1 "k8s.io/api/batch/v1beta1" certificatesapiv1 "k8s.io/api/certificates/v1" - certificatesapiv1beta1 "k8s.io/api/certificates/v1beta1" coordinationapiv1 "k8s.io/api/coordination/v1" - coordinationapiv1beta1 "k8s.io/api/coordination/v1beta1" apiv1 "k8s.io/api/core/v1" discoveryv1 "k8s.io/api/discovery/v1" discoveryv1beta1 "k8s.io/api/discovery/v1beta1" eventsv1 "k8s.io/api/events/v1" eventsv1beta1 "k8s.io/api/events/v1beta1" - extensionsapiv1beta1 "k8s.io/api/extensions/v1beta1" flowcontrolv1alpha1 "k8s.io/api/flowcontrol/v1alpha1" networkingapiv1 "k8s.io/api/networking/v1" - networkingapiv1beta1 "k8s.io/api/networking/v1beta1" nodev1 "k8s.io/api/node/v1" nodev1alpha1 "k8s.io/api/node/v1alpha1" nodev1beta1 "k8s.io/api/node/v1beta1" policyapiv1 "k8s.io/api/policy/v1" policyapiv1beta1 "k8s.io/api/policy/v1beta1" rbacv1 "k8s.io/api/rbac/v1" - rbacv1alpha1 "k8s.io/api/rbac/v1alpha1" - rbacv1beta1 "k8s.io/api/rbac/v1beta1" schedulingapiv1 "k8s.io/api/scheduling/v1" - schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" - schedulingapiv1beta1 "k8s.io/api/scheduling/v1beta1" storageapiv1 "k8s.io/api/storage/v1" storageapiv1alpha1 "k8s.io/api/storage/v1alpha1" storageapiv1beta1 "k8s.io/api/storage/v1beta1" @@ -108,7 +97,6 @@ import ( corerest "k8s.io/kubernetes/pkg/registry/core/rest" discoveryrest "k8s.io/kubernetes/pkg/registry/discovery/rest" eventsrest "k8s.io/kubernetes/pkg/registry/events/rest" - extensionsrest "k8s.io/kubernetes/pkg/registry/extensions/rest" flowcontrolrest "k8s.io/kubernetes/pkg/registry/flowcontrol/rest" networkingrest "k8s.io/kubernetes/pkg/registry/networking/rest" noderest "k8s.io/kubernetes/pkg/registry/node/rest" @@ -428,7 +416,6 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget) certificatesrest.RESTStorageProvider{}, coordinationrest.RESTStorageProvider{}, discoveryrest.StorageProvider{}, - extensionsrest.RESTStorageProvider{}, networkingrest.RESTStorageProvider{}, noderest.RESTStorageProvider{}, policyrest.RESTStorageProvider{}, @@ -643,51 +630,36 @@ func DefaultAPIResourceConfigSource() *serverstorage.ResourceConfig { // NOTE: GroupVersions listed here will be enabled by default. Don't put alpha versions in the list. ret.EnableVersions( admissionregistrationv1.SchemeGroupVersion, - admissionregistrationv1beta1.SchemeGroupVersion, apiv1.SchemeGroupVersion, appsv1.SchemeGroupVersion, authenticationv1.SchemeGroupVersion, - authenticationv1beta1.SchemeGroupVersion, authorizationapiv1.SchemeGroupVersion, - authorizationapiv1beta1.SchemeGroupVersion, autoscalingapiv1.SchemeGroupVersion, autoscalingapiv2beta1.SchemeGroupVersion, autoscalingapiv2beta2.SchemeGroupVersion, batchapiv1.SchemeGroupVersion, batchapiv1beta1.SchemeGroupVersion, certificatesapiv1.SchemeGroupVersion, - certificatesapiv1beta1.SchemeGroupVersion, coordinationapiv1.SchemeGroupVersion, - coordinationapiv1beta1.SchemeGroupVersion, discoveryv1.SchemeGroupVersion, discoveryv1beta1.SchemeGroupVersion, eventsv1.SchemeGroupVersion, eventsv1beta1.SchemeGroupVersion, - extensionsapiv1beta1.SchemeGroupVersion, networkingapiv1.SchemeGroupVersion, - networkingapiv1beta1.SchemeGroupVersion, nodev1.SchemeGroupVersion, nodev1beta1.SchemeGroupVersion, policyapiv1.SchemeGroupVersion, policyapiv1beta1.SchemeGroupVersion, rbacv1.SchemeGroupVersion, - rbacv1beta1.SchemeGroupVersion, storageapiv1.SchemeGroupVersion, storageapiv1beta1.SchemeGroupVersion, - schedulingapiv1beta1.SchemeGroupVersion, schedulingapiv1.SchemeGroupVersion, flowcontrolv1beta1.SchemeGroupVersion, ) - // enable non-deprecated beta resources in extensions/v1beta1 explicitly so we have a full list of what's possible to serve - ret.EnableResources( - extensionsapiv1beta1.SchemeGroupVersion.WithResource("ingresses"), - ) // disable alpha versions explicitly so we have a full list of what's possible to serve ret.DisableVersions( apiserverinternalv1alpha1.SchemeGroupVersion, nodev1alpha1.SchemeGroupVersion, - rbacv1alpha1.SchemeGroupVersion, - schedulingv1alpha1.SchemeGroupVersion, storageapiv1alpha1.SchemeGroupVersion, flowcontrolv1alpha1.SchemeGroupVersion, ) diff --git a/pkg/controlplane/storageversionhashdata/data.go b/pkg/controlplane/storageversionhashdata/data.go index cf817a1ab01..ec37f0728e2 100644 --- a/pkg/controlplane/storageversionhashdata/data.go +++ b/pkg/controlplane/storageversionhashdata/data.go @@ -31,12 +31,6 @@ var NoStorageVersionHash = sets.NewString( "authorization.k8s.io/v1/selfsubjectaccessreviews", "authorization.k8s.io/v1/selfsubjectrulesreviews", "authorization.k8s.io/v1/subjectaccessreviews", - "authentication.k8s.io/v1beta1/tokenreviews", - "authorization.k8s.io/v1beta1/localsubjectaccessreviews", - "authorization.k8s.io/v1beta1/selfsubjectaccessreviews", - "authorization.k8s.io/v1beta1/selfsubjectrulesreviews", - "authorization.k8s.io/v1beta1/subjectaccessreviews", - "extensions/v1beta1/replicationcontrollers", ) // GVRToStorageVersionHash shouldn't change unless we intentionally change the @@ -63,53 +57,37 @@ var GVRToStorageVersionHash = map[string]string{ "batch/v1/jobs": "mudhfqk/qZY=", "batch/v1/cronjobs": "h/JlFAZkyyY=", "batch/v1beta1/cronjobs": "h/JlFAZkyyY=", - "certificates.k8s.io/v1/certificatesigningrequests": "95fRKMXA+00=", - "certificates.k8s.io/v1beta1/certificatesigningrequests": "95fRKMXA+00=", - "coordination.k8s.io/v1beta1/leases": "gqkMMb/YqFM=", - "coordination.k8s.io/v1/leases": "gqkMMb/YqFM=", - "discovery.k8s.io/v1/endpointslices": "Nx3SIv6I0mE=", - "discovery.k8s.io/v1beta1/endpointslices": "Nx3SIv6I0mE=", - "extensions/v1beta1/ingresses": "ZOAfGflaKd0=", - "networking.k8s.io/v1/networkpolicies": "YpfwF18m1G8=", - "networking.k8s.io/v1beta1/ingresses": "ZOAfGflaKd0=", - "networking.k8s.io/v1beta1/ingressclasses": "l/iqIbDgFyQ=", - "networking.k8s.io/v1/ingresses": "ZOAfGflaKd0=", - "networking.k8s.io/v1/ingressclasses": "l/iqIbDgFyQ=", - "node.k8s.io/v1/runtimeclasses": "WQTu1GL3T2Q=", - "node.k8s.io/v1beta1/runtimeclasses": "WQTu1GL3T2Q=", - "policy/v1/poddisruptionbudgets": "6BGBu0kpHtk=", - "policy/v1beta1/poddisruptionbudgets": "6BGBu0kpHtk=", - "policy/v1beta1/podsecuritypolicies": "khBLobUXkqA=", - "rbac.authorization.k8s.io/v1/clusterrolebindings": "48tpQ8gZHFc=", - "rbac.authorization.k8s.io/v1/clusterroles": "bYE5ZWDrJ44=", - "rbac.authorization.k8s.io/v1/rolebindings": "eGsCzGH6b1g=", - "rbac.authorization.k8s.io/v1/roles": "7FuwZcIIItM=", - "rbac.authorization.k8s.io/v1beta1/clusterrolebindings": "48tpQ8gZHFc=", - "rbac.authorization.k8s.io/v1beta1/clusterroles": "bYE5ZWDrJ44=", - "rbac.authorization.k8s.io/v1beta1/rolebindings": "eGsCzGH6b1g=", - "rbac.authorization.k8s.io/v1beta1/roles": "7FuwZcIIItM=", - "scheduling.k8s.io/v1beta1/priorityclasses": "1QwjyaZjj3Y=", - "scheduling.k8s.io/v1/priorityclasses": "1QwjyaZjj3Y=", - "storage.k8s.io/v1/csidrivers": "hL6j/rwBV5w=", - "storage.k8s.io/v1/csinodes": "Pe62DkZtjuo=", - "storage.k8s.io/v1/storageclasses": "K+m6uJwbjGY=", - "storage.k8s.io/v1/volumeattachments": "vQAqD28V4AY=", - "storage.k8s.io/v1beta1/csidrivers": "hL6j/rwBV5w=", - "storage.k8s.io/v1beta1/csinodes": "Pe62DkZtjuo=", - "storage.k8s.io/v1beta1/csistoragecapacities": "xeVl+2Ly1kE=", - "storage.k8s.io/v1beta1/storageclasses": "K+m6uJwbjGY=", - "storage.k8s.io/v1beta1/volumeattachments": "vQAqD28V4AY=", - "apps/v1/controllerrevisions": "85nkx63pcBU=", - "apps/v1/daemonsets": "dd7pWHUlMKQ=", - "apps/v1/deployments": "8aSe+NMegvE=", - "apps/v1/replicasets": "P1RzHs8/mWQ=", - "apps/v1/statefulsets": "H+vl74LkKdo=", - "admissionregistration.k8s.io/v1beta1/mutatingwebhookconfigurations": "Sqi0GUgDaX0=", - "admissionregistration.k8s.io/v1beta1/validatingwebhookconfigurations": "B0wHjQmsGNk=", - "admissionregistration.k8s.io/v1/mutatingwebhookconfigurations": "Sqi0GUgDaX0=", - "admissionregistration.k8s.io/v1/validatingwebhookconfigurations": "B0wHjQmsGNk=", - "events.k8s.io/v1/events": "r2yiGXH7wu8=", - "events.k8s.io/v1beta1/events": "r2yiGXH7wu8=", - "flowcontrol.apiserver.k8s.io/v1beta1/flowschemas": "9bSnTLYweJ0=", - "flowcontrol.apiserver.k8s.io/v1beta1/prioritylevelconfigurations": "BFVwf8eYnsw=", + "certificates.k8s.io/v1/certificatesigningrequests": "95fRKMXA+00=", + "coordination.k8s.io/v1/leases": "gqkMMb/YqFM=", + "discovery.k8s.io/v1/endpointslices": "Nx3SIv6I0mE=", + "discovery.k8s.io/v1beta1/endpointslices": "Nx3SIv6I0mE=", + "networking.k8s.io/v1/networkpolicies": "YpfwF18m1G8=", + "networking.k8s.io/v1/ingresses": "ZOAfGflaKd0=", + "networking.k8s.io/v1/ingressclasses": "l/iqIbDgFyQ=", + "node.k8s.io/v1/runtimeclasses": "WQTu1GL3T2Q=", + "node.k8s.io/v1beta1/runtimeclasses": "WQTu1GL3T2Q=", + "policy/v1/poddisruptionbudgets": "6BGBu0kpHtk=", + "policy/v1beta1/poddisruptionbudgets": "6BGBu0kpHtk=", + "policy/v1beta1/podsecuritypolicies": "khBLobUXkqA=", + "rbac.authorization.k8s.io/v1/clusterrolebindings": "48tpQ8gZHFc=", + "rbac.authorization.k8s.io/v1/clusterroles": "bYE5ZWDrJ44=", + "rbac.authorization.k8s.io/v1/rolebindings": "eGsCzGH6b1g=", + "rbac.authorization.k8s.io/v1/roles": "7FuwZcIIItM=", + "scheduling.k8s.io/v1/priorityclasses": "1QwjyaZjj3Y=", + "storage.k8s.io/v1/csidrivers": "hL6j/rwBV5w=", + "storage.k8s.io/v1/csinodes": "Pe62DkZtjuo=", + "storage.k8s.io/v1/storageclasses": "K+m6uJwbjGY=", + "storage.k8s.io/v1/volumeattachments": "vQAqD28V4AY=", + "storage.k8s.io/v1beta1/csistoragecapacities": "xeVl+2Ly1kE=", + "apps/v1/controllerrevisions": "85nkx63pcBU=", + "apps/v1/daemonsets": "dd7pWHUlMKQ=", + "apps/v1/deployments": "8aSe+NMegvE=", + "apps/v1/replicasets": "P1RzHs8/mWQ=", + "apps/v1/statefulsets": "H+vl74LkKdo=", + "admissionregistration.k8s.io/v1/mutatingwebhookconfigurations": "Sqi0GUgDaX0=", + "admissionregistration.k8s.io/v1/validatingwebhookconfigurations": "B0wHjQmsGNk=", + "events.k8s.io/v1/events": "r2yiGXH7wu8=", + "events.k8s.io/v1beta1/events": "r2yiGXH7wu8=", + "flowcontrol.apiserver.k8s.io/v1beta1/flowschemas": "9bSnTLYweJ0=", + "flowcontrol.apiserver.k8s.io/v1beta1/prioritylevelconfigurations": "BFVwf8eYnsw=", } diff --git a/pkg/registry/admissionregistration/mutatingwebhookconfiguration/strategy.go b/pkg/registry/admissionregistration/mutatingwebhookconfiguration/strategy.go index e5bea2cf791..0ae88c5dd6c 100644 --- a/pkg/registry/admissionregistration/mutatingwebhookconfiguration/strategy.go +++ b/pkg/registry/admissionregistration/mutatingwebhookconfiguration/strategy.go @@ -21,9 +21,7 @@ import ( "reflect" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" - genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/apis/admissionregistration" @@ -70,13 +68,8 @@ func (mutatingWebhookConfigurationStrategy) PrepareForUpdate(ctx context.Context // Validate validates a new mutatingWebhookConfiguration. func (mutatingWebhookConfigurationStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { - var groupVersion schema.GroupVersion - if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found { - groupVersion = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} - } - ic := obj.(*admissionregistration.MutatingWebhookConfiguration) - return validation.ValidateMutatingWebhookConfiguration(ic, groupVersion) + return validation.ValidateMutatingWebhookConfiguration(ic) } // Canonicalize normalizes the object after validation. @@ -90,12 +83,7 @@ func (mutatingWebhookConfigurationStrategy) AllowCreateOnUpdate() bool { // ValidateUpdate is the default update validation for an end user. func (mutatingWebhookConfigurationStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { - var groupVersion schema.GroupVersion - if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found { - groupVersion = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} - } - - return validation.ValidateMutatingWebhookConfigurationUpdate(obj.(*admissionregistration.MutatingWebhookConfiguration), old.(*admissionregistration.MutatingWebhookConfiguration), groupVersion) + return validation.ValidateMutatingWebhookConfigurationUpdate(obj.(*admissionregistration.MutatingWebhookConfiguration), old.(*admissionregistration.MutatingWebhookConfiguration)) } // WarningsOnUpdate returns warnings for the given update. diff --git a/pkg/registry/admissionregistration/rest/storage_apiserver.go b/pkg/registry/admissionregistration/rest/storage_apiserver.go index 565d72e4933..7b75ecb2817 100644 --- a/pkg/registry/admissionregistration/rest/storage_apiserver.go +++ b/pkg/registry/admissionregistration/rest/storage_apiserver.go @@ -18,7 +18,6 @@ package rest import ( admissionregistrationv1 "k8s.io/api/admissionregistration/v1" - admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" genericapiserver "k8s.io/apiserver/pkg/server" @@ -36,13 +35,6 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // TODO refactor the plumbing to provide the information in the APIGroupInfo - if apiResourceConfigSource.VersionEnabled(admissionregistrationv1beta1.SchemeGroupVersion) { - if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { - return genericapiserver.APIGroupInfo{}, false, err - } else { - apiGroupInfo.VersionedResourcesStorageMap[admissionregistrationv1beta1.SchemeGroupVersion.Version] = storageMap - } - } if apiResourceConfigSource.VersionEnabled(admissionregistrationv1.SchemeGroupVersion) { if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { return genericapiserver.APIGroupInfo{}, false, err @@ -53,25 +45,6 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag return apiGroupInfo, true, nil } -func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { - storage := map[string]rest.Storage{} - // validatingwebhookconfigurations - validatingStorage, err := validatingwebhookconfigurationstorage.NewREST(restOptionsGetter) - if err != nil { - return storage, err - } - storage["validatingwebhookconfigurations"] = validatingStorage - - // mutatingwebhookconfigurations - mutatingStorage, err := mutatingwebhookconfigurationstorage.NewREST(restOptionsGetter) - if err != nil { - return storage, err - } - storage["mutatingwebhookconfigurations"] = mutatingStorage - - return storage, err -} - func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { storage := map[string]rest.Storage{} // validatingwebhookconfigurations diff --git a/pkg/registry/admissionregistration/validatingwebhookconfiguration/strategy.go b/pkg/registry/admissionregistration/validatingwebhookconfiguration/strategy.go index 3b91fc6612b..20bc653eeae 100644 --- a/pkg/registry/admissionregistration/validatingwebhookconfiguration/strategy.go +++ b/pkg/registry/admissionregistration/validatingwebhookconfiguration/strategy.go @@ -21,9 +21,7 @@ import ( "reflect" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" - genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/apis/admissionregistration" @@ -65,12 +63,7 @@ func (validatingWebhookConfigurationStrategy) PrepareForUpdate(ctx context.Conte // Validate validates a new validatingWebhookConfiguration. func (validatingWebhookConfigurationStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { - var groupVersion schema.GroupVersion - if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found { - groupVersion = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} - } - - return validation.ValidateValidatingWebhookConfiguration(obj.(*admissionregistration.ValidatingWebhookConfiguration), groupVersion) + return validation.ValidateValidatingWebhookConfiguration(obj.(*admissionregistration.ValidatingWebhookConfiguration)) } // WarningsOnCreate returns warnings for the creation of the given object. @@ -89,12 +82,7 @@ func (validatingWebhookConfigurationStrategy) AllowCreateOnUpdate() bool { // ValidateUpdate is the default update validation for an end user. func (validatingWebhookConfigurationStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { - var groupVersion schema.GroupVersion - if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found { - groupVersion = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} - } - - return validation.ValidateValidatingWebhookConfigurationUpdate(obj.(*admissionregistration.ValidatingWebhookConfiguration), old.(*admissionregistration.ValidatingWebhookConfiguration), groupVersion) + return validation.ValidateValidatingWebhookConfigurationUpdate(obj.(*admissionregistration.ValidatingWebhookConfiguration), old.(*admissionregistration.ValidatingWebhookConfiguration)) } // WarningsOnUpdate returns warnings for the given update. diff --git a/pkg/registry/apps/daemonset/strategy.go b/pkg/registry/apps/daemonset/strategy.go index edcdd0423dc..6cfd65ed7d5 100644 --- a/pkg/registry/apps/daemonset/strategy.go +++ b/pkg/registry/apps/daemonset/strategy.go @@ -19,7 +19,6 @@ package daemonset import ( "context" - appsv1beta2 "k8s.io/api/apps/v1beta2" extensionsv1beta1 "k8s.io/api/extensions/v1beta1" apiequality "k8s.io/apimachinery/pkg/api/equality" apivalidation "k8s.io/apimachinery/pkg/api/validation" @@ -48,20 +47,12 @@ type daemonSetStrategy struct { // Strategy is the default logic that applies when creating and updating DaemonSet objects. var Strategy = daemonSetStrategy{legacyscheme.Scheme, names.SimpleNameGenerator} -// DefaultGarbageCollectionPolicy returns OrphanDependents for extensions/v1beta1 and apps/v1beta2 for backwards compatibility, -// and DeleteDependents for all other versions. +// Make sure we correctly implement the interface. +var _ = rest.GarbageCollectionDeleteStrategy(Strategy) + +// DefaultGarbageCollectionPolicy returns DeleteDependents for all currently served versions. func (daemonSetStrategy) DefaultGarbageCollectionPolicy(ctx context.Context) rest.GarbageCollectionPolicy { - var groupVersion schema.GroupVersion - if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found { - groupVersion = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} - } - switch groupVersion { - case extensionsv1beta1.SchemeGroupVersion, appsv1beta2.SchemeGroupVersion: - // for back compatibility - return rest.OrphanDependents - default: - return rest.DeleteDependents - } + return rest.DeleteDependents } // NamespaceScoped returns true because all DaemonSets need to be within a namespace. diff --git a/pkg/registry/apps/daemonset/strategy_test.go b/pkg/registry/apps/daemonset/strategy_test.go index dfc30e2866c..82839fbbfa9 100644 --- a/pkg/registry/apps/daemonset/strategy_test.go +++ b/pkg/registry/apps/daemonset/strategy_test.go @@ -25,7 +25,6 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/validation/field" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" - "k8s.io/apiserver/pkg/registry/rest" utilfeature "k8s.io/apiserver/pkg/util/feature" featuregatetesting "k8s.io/component-base/featuregate/testing" "k8s.io/kubernetes/pkg/apis/apps" @@ -40,60 +39,6 @@ const ( namespace = "test-namespace" ) -func TestDaemonsetDefaultGarbageCollectionPolicy(t *testing.T) { - // Make sure we correctly implement the interface. - // Otherwise a typo could silently change the default. - var gcds rest.GarbageCollectionDeleteStrategy = Strategy - tests := []struct { - requestInfo genericapirequest.RequestInfo - expectedGCPolicy rest.GarbageCollectionPolicy - isNilRequestInfo bool - }{ - { - genericapirequest.RequestInfo{ - APIGroup: "extensions", - APIVersion: "v1beta1", - Resource: "daemonsets", - }, - rest.OrphanDependents, - false, - }, - { - genericapirequest.RequestInfo{ - APIGroup: "apps", - APIVersion: "v1beta2", - Resource: "daemonsets", - }, - rest.OrphanDependents, - false, - }, - { - genericapirequest.RequestInfo{ - APIGroup: "apps", - APIVersion: "v1", - Resource: "daemonsets", - }, - rest.DeleteDependents, - false, - }, - { - expectedGCPolicy: rest.DeleteDependents, - isNilRequestInfo: true, - }, - } - - for _, test := range tests { - context := genericapirequest.NewContext() - if !test.isNilRequestInfo { - context = genericapirequest.WithRequestInfo(context, &test.requestInfo) - } - if got, want := gcds.DefaultGarbageCollectionPolicy(context), test.expectedGCPolicy; got != want { - t.Errorf("%s/%s: DefaultGarbageCollectionPolicy() = %#v, want %#v", test.requestInfo.APIGroup, - test.requestInfo.APIVersion, got, want) - } - } -} - func TestSelectorImmutability(t *testing.T) { tests := []struct { requestInfo genericapirequest.RequestInfo diff --git a/pkg/registry/apps/deployment/strategy.go b/pkg/registry/apps/deployment/strategy.go index 43ca93f7d8e..71938f3280f 100644 --- a/pkg/registry/apps/deployment/strategy.go +++ b/pkg/registry/apps/deployment/strategy.go @@ -20,7 +20,6 @@ import ( "context" appsv1beta1 "k8s.io/api/apps/v1beta1" - appsv1beta2 "k8s.io/api/apps/v1beta2" extensionsv1beta1 "k8s.io/api/extensions/v1beta1" apiequality "k8s.io/apimachinery/pkg/api/equality" apivalidation "k8s.io/apimachinery/pkg/api/validation" @@ -47,20 +46,12 @@ type deploymentStrategy struct { // objects via the REST API. var Strategy = deploymentStrategy{legacyscheme.Scheme, names.SimpleNameGenerator} -// DefaultGarbageCollectionPolicy returns OrphanDependents for extensions/v1beta1, apps/v1beta1, and apps/v1beta2 for backwards compatibility, -// and DeleteDependents for all other versions. +// Make sure we correctly implement the interface. +var _ = rest.GarbageCollectionDeleteStrategy(Strategy) + +// DefaultGarbageCollectionPolicy returns DeleteDependents for all currently served versions. func (deploymentStrategy) DefaultGarbageCollectionPolicy(ctx context.Context) rest.GarbageCollectionPolicy { - var groupVersion schema.GroupVersion - if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found { - groupVersion = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} - } - switch groupVersion { - case extensionsv1beta1.SchemeGroupVersion, appsv1beta1.SchemeGroupVersion, appsv1beta2.SchemeGroupVersion: - // for back compatibility - return rest.OrphanDependents - default: - return rest.DeleteDependents - } + return rest.DeleteDependents } // NamespaceScoped is true for deployment. diff --git a/pkg/registry/apps/deployment/strategy_test.go b/pkg/registry/apps/deployment/strategy_test.go index 8955cb5754b..44d702e72e1 100644 --- a/pkg/registry/apps/deployment/strategy_test.go +++ b/pkg/registry/apps/deployment/strategy_test.go @@ -26,7 +26,6 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/validation/field" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" - "k8s.io/apiserver/pkg/registry/rest" "k8s.io/kubernetes/pkg/apis/apps" api "k8s.io/kubernetes/pkg/apis/core" ) @@ -186,69 +185,6 @@ func newDeploymentWithSelectorLabels(selectorLabels map[string]string) *apps.Dep } } -func TestDeploymentDefaultGarbageCollectionPolicy(t *testing.T) { - // Make sure we correctly implement the interface. - // Otherwise a typo could silently change the default. - var gcds rest.GarbageCollectionDeleteStrategy = Strategy - tests := []struct { - requestInfo genericapirequest.RequestInfo - expectedGCPolicy rest.GarbageCollectionPolicy - isNilRequestInfo bool - }{ - { - genericapirequest.RequestInfo{ - APIGroup: "extensions", - APIVersion: "v1beta1", - Resource: "deployments", - }, - rest.OrphanDependents, - false, - }, - { - genericapirequest.RequestInfo{ - APIGroup: "apps", - APIVersion: "v1beta1", - Resource: "deployments", - }, - rest.OrphanDependents, - false, - }, - { - genericapirequest.RequestInfo{ - APIGroup: "apps", - APIVersion: "v1beta2", - Resource: "deployments", - }, - rest.OrphanDependents, - false, - }, - { - genericapirequest.RequestInfo{ - APIGroup: "apps", - APIVersion: "v1", - Resource: "deployments", - }, - rest.DeleteDependents, - false, - }, - { - expectedGCPolicy: rest.DeleteDependents, - isNilRequestInfo: true, - }, - } - - for _, test := range tests { - context := genericapirequest.NewContext() - if !test.isNilRequestInfo { - context = genericapirequest.WithRequestInfo(context, &test.requestInfo) - } - if got, want := gcds.DefaultGarbageCollectionPolicy(context), test.expectedGCPolicy; got != want { - t.Errorf("%s/%s: DefaultGarbageCollectionPolicy() = %#v, want %#v", test.requestInfo.APIGroup, - test.requestInfo.APIVersion, got, want) - } - } -} - func newDeploymentWithHugePageValue(reousreceName api.ResourceName, value resource.Quantity) *apps.Deployment { return &apps.Deployment{ ObjectMeta: metav1.ObjectMeta{ diff --git a/pkg/registry/apps/replicaset/strategy.go b/pkg/registry/apps/replicaset/strategy.go index c8729d63cac..add8c23927d 100644 --- a/pkg/registry/apps/replicaset/strategy.go +++ b/pkg/registry/apps/replicaset/strategy.go @@ -23,7 +23,6 @@ import ( "fmt" "strconv" - appsv1beta2 "k8s.io/api/apps/v1beta2" extensionsv1beta1 "k8s.io/api/extensions/v1beta1" apiequality "k8s.io/apimachinery/pkg/api/equality" apivalidation "k8s.io/apimachinery/pkg/api/validation" @@ -53,20 +52,12 @@ type rsStrategy struct { // Strategy is the default logic that applies when creating and updating ReplicaSet objects. var Strategy = rsStrategy{legacyscheme.Scheme, names.SimpleNameGenerator} -// DefaultGarbageCollectionPolicy returns OrphanDependents for extensions/v1beta1 and apps/v1beta2 for backwards compatibility, -// and DeleteDependents for all other versions. +// Make sure we correctly implement the interface. +var _ = rest.GarbageCollectionDeleteStrategy(Strategy) + +// DefaultGarbageCollectionPolicy returns DeleteDependents for all currently served versions. func (rsStrategy) DefaultGarbageCollectionPolicy(ctx context.Context) rest.GarbageCollectionPolicy { - var groupVersion schema.GroupVersion - if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found { - groupVersion = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} - } - switch groupVersion { - case extensionsv1beta1.SchemeGroupVersion, appsv1beta2.SchemeGroupVersion: - // for back compatibility - return rest.OrphanDependents - default: - return rest.DeleteDependents - } + return rest.DeleteDependents } // NamespaceScoped returns true because all ReplicaSets need to be within a namespace. diff --git a/pkg/registry/apps/replicaset/strategy_test.go b/pkg/registry/apps/replicaset/strategy_test.go index b136d7d98bc..d76ed810be8 100644 --- a/pkg/registry/apps/replicaset/strategy_test.go +++ b/pkg/registry/apps/replicaset/strategy_test.go @@ -23,7 +23,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/validation/field" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" - "k8s.io/apiserver/pkg/registry/rest" "k8s.io/kubernetes/pkg/apis/apps" api "k8s.io/kubernetes/pkg/apis/core" ) @@ -228,57 +227,3 @@ func newReplicaSetWithSelectorLabels(selectorLabels map[string]string) *apps.Rep }, } } - -func TestReplicasetDefaultGarbageCollectionPolicy(t *testing.T) { - // Make sure we correctly implement the interface. - // Otherwise a typo could silently change the default. - var gcds rest.GarbageCollectionDeleteStrategy = Strategy - tests := []struct { - requestInfo genericapirequest.RequestInfo - expectedGCPolicy rest.GarbageCollectionPolicy - isNilRequestInfo bool - }{ - { - genericapirequest.RequestInfo{ - APIGroup: "extensions", - APIVersion: "v1beta1", - Resource: "replicasets", - }, - rest.OrphanDependents, - false, - }, - { - genericapirequest.RequestInfo{ - APIGroup: "apps", - APIVersion: "v1beta2", - Resource: "replicasets", - }, - rest.OrphanDependents, - false, - }, - { - genericapirequest.RequestInfo{ - APIGroup: "apps", - APIVersion: "v1", - Resource: "replicasets", - }, - rest.DeleteDependents, - false, - }, - { - expectedGCPolicy: rest.DeleteDependents, - isNilRequestInfo: true, - }, - } - - for _, test := range tests { - context := genericapirequest.NewContext() - if !test.isNilRequestInfo { - context = genericapirequest.WithRequestInfo(context, &test.requestInfo) - } - if got, want := gcds.DefaultGarbageCollectionPolicy(context), test.expectedGCPolicy; got != want { - t.Errorf("%s/%s: DefaultGarbageCollectionPolicy() = %#v, want %#v", test.requestInfo.APIGroup, - test.requestInfo.APIVersion, got, want) - } - } -} diff --git a/pkg/registry/apps/statefulset/strategy.go b/pkg/registry/apps/statefulset/strategy.go index 5b5ff04af95..21ed15771d8 100644 --- a/pkg/registry/apps/statefulset/strategy.go +++ b/pkg/registry/apps/statefulset/strategy.go @@ -21,13 +21,9 @@ import ( utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/kubernetes/pkg/features" - appsv1beta1 "k8s.io/api/apps/v1beta1" - appsv1beta2 "k8s.io/api/apps/v1beta2" apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" - genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/registry/rest" "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api/legacyscheme" @@ -46,20 +42,12 @@ type statefulSetStrategy struct { // Strategy is the default logic that applies when creating and updating Replication StatefulSet objects. var Strategy = statefulSetStrategy{legacyscheme.Scheme, names.SimpleNameGenerator} -// DefaultGarbageCollectionPolicy returns OrphanDependents for apps/v1beta1 and apps/v1beta2 for backwards compatibility, -// and DeleteDependents for all other versions. +// Make sure we correctly implement the interface. +var _ = rest.GarbageCollectionDeleteStrategy(Strategy) + +// DefaultGarbageCollectionPolicy returns DeleteDependents for all currently served versions. func (statefulSetStrategy) DefaultGarbageCollectionPolicy(ctx context.Context) rest.GarbageCollectionPolicy { - var groupVersion schema.GroupVersion - if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found { - groupVersion = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} - } - switch groupVersion { - case appsv1beta1.SchemeGroupVersion, appsv1beta2.SchemeGroupVersion: - // for back compatibility - return rest.OrphanDependents - default: - return rest.DeleteDependents - } + return rest.DeleteDependents } // NamespaceScoped returns true because all StatefulSet' need to be within a namespace. diff --git a/pkg/registry/apps/statefulset/strategy_test.go b/pkg/registry/apps/statefulset/strategy_test.go index ae47f56fad0..1b360cea5d3 100644 --- a/pkg/registry/apps/statefulset/strategy_test.go +++ b/pkg/registry/apps/statefulset/strategy_test.go @@ -23,7 +23,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/diff" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" - "k8s.io/apiserver/pkg/registry/rest" utilfeature "k8s.io/apiserver/pkg/util/feature" featuregatetesting "k8s.io/component-base/featuregate/testing" "k8s.io/kubernetes/pkg/apis/apps" @@ -194,60 +193,6 @@ func TestStatefulSetStrategy(t *testing.T) { } } -func TestStatefulsetDefaultGarbageCollectionPolicy(t *testing.T) { - // Make sure we correctly implement the interface. - // Otherwise a typo could silently change the default. - var gcds rest.GarbageCollectionDeleteStrategy = Strategy - tests := []struct { - requestInfo genericapirequest.RequestInfo - expectedGCPolicy rest.GarbageCollectionPolicy - isNilRequestInfo bool - }{ - { - genericapirequest.RequestInfo{ - APIGroup: "apps", - APIVersion: "v1beta1", - Resource: "statefulsets", - }, - rest.OrphanDependents, - false, - }, - { - genericapirequest.RequestInfo{ - APIGroup: "apps", - APIVersion: "v1beta2", - Resource: "statefulsets", - }, - rest.OrphanDependents, - false, - }, - { - genericapirequest.RequestInfo{ - APIGroup: "apps", - APIVersion: "v1", - Resource: "statefulsets", - }, - rest.DeleteDependents, - false, - }, - { - expectedGCPolicy: rest.DeleteDependents, - isNilRequestInfo: true, - }, - } - - for _, test := range tests { - context := genericapirequest.NewContext() - if !test.isNilRequestInfo { - context = genericapirequest.WithRequestInfo(context, &test.requestInfo) - } - if got, want := gcds.DefaultGarbageCollectionPolicy(context), test.expectedGCPolicy; got != want { - t.Errorf("%s/%s: DefaultGarbageCollectionPolicy() = %#v, want %#v", test.requestInfo.APIGroup, - test.requestInfo.APIVersion, got, want) - } - } -} - func TestStatefulSetStatusStrategy(t *testing.T) { ctx := genericapirequest.NewDefaultContext() if !StatusStrategy.NamespaceScoped() { diff --git a/pkg/registry/authentication/rest/storage_authentication.go b/pkg/registry/authentication/rest/storage_authentication.go index c99f9b3e8de..f79a5f218e3 100644 --- a/pkg/registry/authentication/rest/storage_authentication.go +++ b/pkg/registry/authentication/rest/storage_authentication.go @@ -18,7 +18,6 @@ package rest import ( authenticationv1 "k8s.io/api/authentication/v1" - authenticationv1beta1 "k8s.io/api/authentication/v1beta1" "k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" @@ -44,9 +43,6 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // TODO refactor the plumbing to provide the information in the APIGroupInfo - if apiResourceConfigSource.VersionEnabled(authenticationv1beta1.SchemeGroupVersion) { - apiGroupInfo.VersionedResourcesStorageMap[authenticationv1beta1.SchemeGroupVersion.Version] = p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter) - } if apiResourceConfigSource.VersionEnabled(authenticationv1.SchemeGroupVersion) { apiGroupInfo.VersionedResourcesStorageMap[authenticationv1.SchemeGroupVersion.Version] = p.v1Storage(apiResourceConfigSource, restOptionsGetter) } @@ -54,15 +50,6 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag return apiGroupInfo, true, nil } -func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage { - storage := map[string]rest.Storage{} - // tokenreviews - tokenReviewStorage := tokenreview.NewREST(p.Authenticator, p.APIAudiences) - storage["tokenreviews"] = tokenReviewStorage - - return storage -} - func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage { storage := map[string]rest.Storage{} // tokenreviews diff --git a/pkg/registry/authorization/rest/storage_authorization.go b/pkg/registry/authorization/rest/storage_authorization.go index 00d8f5c96f6..c424deaf9ef 100644 --- a/pkg/registry/authorization/rest/storage_authorization.go +++ b/pkg/registry/authorization/rest/storage_authorization.go @@ -18,7 +18,6 @@ package rest import ( authorizationv1 "k8s.io/api/authorization/v1" - authorizationv1beta1 "k8s.io/api/authorization/v1beta1" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" @@ -46,10 +45,6 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // TODO refactor the plumbing to provide the information in the APIGroupInfo - if apiResourceConfigSource.VersionEnabled(authorizationv1beta1.SchemeGroupVersion) { - apiGroupInfo.VersionedResourcesStorageMap[authorizationv1beta1.SchemeGroupVersion.Version] = p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter) - } - if apiResourceConfigSource.VersionEnabled(authorizationv1.SchemeGroupVersion) { apiGroupInfo.VersionedResourcesStorageMap[authorizationv1.SchemeGroupVersion.Version] = p.v1Storage(apiResourceConfigSource, restOptionsGetter) } @@ -57,20 +52,6 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag return apiGroupInfo, true, nil } -func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage { - storage := map[string]rest.Storage{} - // subjectaccessreviews - storage["subjectaccessreviews"] = subjectaccessreview.NewREST(p.Authorizer) - // selfsubjectaccessreviews - storage["selfsubjectaccessreviews"] = selfsubjectaccessreview.NewREST(p.Authorizer) - // localsubjectaccessreviews - storage["localsubjectaccessreviews"] = localsubjectaccessreview.NewREST(p.Authorizer) - // selfsubjectrulesreviews - storage["selfsubjectrulesreviews"] = selfsubjectrulesreview.NewREST(p.RuleResolver) - - return storage -} - func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage { storage := map[string]rest.Storage{} // subjectaccessreviews diff --git a/pkg/registry/certificates/certificates/strategy.go b/pkg/registry/certificates/certificates/strategy.go index 41281ee177d..95450358e6a 100644 --- a/pkg/registry/certificates/certificates/strategy.go +++ b/pkg/registry/certificates/certificates/strategy.go @@ -20,12 +20,10 @@ import ( "context" "fmt" - certificatesv1beta1 "k8s.io/api/certificates/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/registry/generic" @@ -120,7 +118,7 @@ func (csrStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object // Validate validates a new CSR. Validation must check for a correct signature. func (csrStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { csr := obj.(*certificates.CertificateSigningRequest) - return validation.ValidateCertificateSigningRequestCreate(csr, requestGroupVersion(ctx)) + return validation.ValidateCertificateSigningRequestCreate(csr) } // WarningsOnCreate returns warnings for the creation of the given object. @@ -133,7 +131,7 @@ func (csrStrategy) Canonicalize(obj runtime.Object) {} func (csrStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { oldCSR := old.(*certificates.CertificateSigningRequest) newCSR := obj.(*certificates.CertificateSigningRequest) - return validation.ValidateCertificateSigningRequestUpdate(newCSR, oldCSR, requestGroupVersion(ctx)) + return validation.ValidateCertificateSigningRequestUpdate(newCSR, oldCSR) } // WarningsOnUpdate returns warnings for the given update. @@ -181,20 +179,11 @@ func (csrStatusStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime. // Updating /status should not modify spec newCSR.Spec = oldCSR.Spec - switch requestGroupVersion(ctx) { - case certificatesv1beta1.SchemeGroupVersion: - // Specifically preserve existing Approved/Denied conditions. - // If we cannot (if the status update attempted to add/remove Approved/Denied conditions), revert to old conditions for backwards compatibility. - if !preserveConditionInstances(newCSR, oldCSR, certificates.CertificateApproved) || !preserveConditionInstances(newCSR, oldCSR, certificates.CertificateDenied) { - newCSR.Status.Conditions = oldCSR.Status.Conditions - } - default: - // Specifically preserve existing Approved/Denied conditions. - // Adding/removing Approved/Denied conditions will cause these to fail, - // and the change in Approved/Denied conditions will produce a validation error - preserveConditionInstances(newCSR, oldCSR, certificates.CertificateApproved) - preserveConditionInstances(newCSR, oldCSR, certificates.CertificateDenied) - } + // Specifically preserve existing Approved/Denied conditions. + // Adding/removing Approved/Denied conditions will cause these to fail, + // and the change in Approved/Denied conditions will produce a validation error + preserveConditionInstances(newCSR, oldCSR, certificates.CertificateApproved) + preserveConditionInstances(newCSR, oldCSR, certificates.CertificateDenied) populateConditionTimestamps(newCSR, oldCSR) } @@ -255,7 +244,7 @@ func populateConditionTimestamps(newCSR, oldCSR *certificates.CertificateSigning } func (csrStatusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { - return validation.ValidateCertificateSigningRequestStatusUpdate(obj.(*certificates.CertificateSigningRequest), old.(*certificates.CertificateSigningRequest), requestGroupVersion(ctx)) + return validation.ValidateCertificateSigningRequestStatusUpdate(obj.(*certificates.CertificateSigningRequest), old.(*certificates.CertificateSigningRequest)) } // WarningsOnUpdate returns warnings for the given update. @@ -307,7 +296,7 @@ func (csrApprovalStrategy) PrepareForUpdate(ctx context.Context, obj, old runtim } func (csrApprovalStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { - return validation.ValidateCertificateSigningRequestApprovalUpdate(obj.(*certificates.CertificateSigningRequest), old.(*certificates.CertificateSigningRequest), requestGroupVersion(ctx)) + return validation.ValidateCertificateSigningRequestApprovalUpdate(obj.(*certificates.CertificateSigningRequest), old.(*certificates.CertificateSigningRequest)) } // WarningsOnUpdate returns warnings for the given update. @@ -332,11 +321,3 @@ func SelectableFields(obj *certificates.CertificateSigningRequest) fields.Set { } return generic.MergeFieldsSets(objectMetaFieldsSet, csrSpecificFieldsSet) } - -// requestGroupVersion returns the group/version associated with the given context, or a zero-value group/version -func requestGroupVersion(ctx context.Context) schema.GroupVersion { - if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found { - return schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} - } - return schema.GroupVersion{} -} diff --git a/pkg/registry/certificates/certificates/strategy_test.go b/pkg/registry/certificates/certificates/strategy_test.go index fb1318d3ea5..c34c0af9b31 100644 --- a/pkg/registry/certificates/certificates/strategy_test.go +++ b/pkg/registry/certificates/certificates/strategy_test.go @@ -174,19 +174,16 @@ func TestStatusUpdate(t *testing.T) { }() tests := []struct { - name string - newObj *certapi.CertificateSigningRequest - oldObj *certapi.CertificateSigningRequest - expectedObjs map[string]*certapi.CertificateSigningRequest + name string + newObj *certapi.CertificateSigningRequest + oldObj *certapi.CertificateSigningRequest + expectedObj *certapi.CertificateSigningRequest }{ { - name: "no-op", - newObj: &certapi.CertificateSigningRequest{}, - oldObj: &certapi.CertificateSigningRequest{}, - expectedObjs: map[string]*certapi.CertificateSigningRequest{ - "v1": {}, - "v1beta1": {}, - }, + name: "no-op", + newObj: &certapi.CertificateSigningRequest{}, + oldObj: &certapi.CertificateSigningRequest{}, + expectedObj: &certapi.CertificateSigningRequest{}, }, { name: "adding failed condition to existing approved/denied conditions", @@ -211,29 +208,15 @@ func TestStatusUpdate(t *testing.T) { }, }, }, - expectedObjs: map[string]*certapi.CertificateSigningRequest{ + expectedObj: &certapi.CertificateSigningRequest{ // preserve existing Approved/Denied conditions - "v1": { - Status: certapi.CertificateSigningRequestStatus{ - Conditions: []certapi.CertificateSigningRequestCondition{ - {Type: certapi.CertificateFailed, LastUpdateTime: now, LastTransitionTime: now}, - {Type: certapi.CertificateDenied, LastUpdateTime: now, LastTransitionTime: later, Reason: "because1"}, - {Type: certapi.CertificateApproved, LastUpdateTime: now, LastTransitionTime: later, Reason: "because2"}, - {Type: certapi.CertificateDenied, LastUpdateTime: later, LastTransitionTime: later, Reason: "because3"}, - {Type: certapi.CertificateApproved, LastUpdateTime: later, LastTransitionTime: later, Reason: "because4"}, - }, - }, - }, - // preserve existing Approved/Denied conditions - "v1beta1": { - Status: certapi.CertificateSigningRequestStatus{ - Conditions: []certapi.CertificateSigningRequestCondition{ - {Type: certapi.CertificateFailed, LastUpdateTime: now, LastTransitionTime: now}, - {Type: certapi.CertificateDenied, LastUpdateTime: now, LastTransitionTime: later, Reason: "because1"}, - {Type: certapi.CertificateApproved, LastUpdateTime: now, LastTransitionTime: later, Reason: "because2"}, - {Type: certapi.CertificateDenied, LastUpdateTime: later, LastTransitionTime: later, Reason: "because3"}, - {Type: certapi.CertificateApproved, LastUpdateTime: later, LastTransitionTime: later, Reason: "because4"}, - }, + Status: certapi.CertificateSigningRequestStatus{ + Conditions: []certapi.CertificateSigningRequestCondition{ + {Type: certapi.CertificateFailed, LastUpdateTime: now, LastTransitionTime: now}, + {Type: certapi.CertificateDenied, LastUpdateTime: now, LastTransitionTime: later, Reason: "because1"}, + {Type: certapi.CertificateApproved, LastUpdateTime: now, LastTransitionTime: later, Reason: "because2"}, + {Type: certapi.CertificateDenied, LastUpdateTime: later, LastTransitionTime: later, Reason: "because3"}, + {Type: certapi.CertificateApproved, LastUpdateTime: later, LastTransitionTime: later, Reason: "because4"}, }, }, }, @@ -248,33 +231,24 @@ func TestStatusUpdate(t *testing.T) { }, }, oldObj: &certapi.CertificateSigningRequest{}, - expectedObjs: map[string]*certapi.CertificateSigningRequest{ + expectedObj: &certapi.CertificateSigningRequest{ // preserved submitted conditions if existing Approved/Denied conditions could not be copied over (will fail validation) - "v1": { - Status: certapi.CertificateSigningRequestStatus{ - Conditions: []certapi.CertificateSigningRequestCondition{ - {Type: certapi.CertificateApproved, LastUpdateTime: now, LastTransitionTime: now}, - }, + Status: certapi.CertificateSigningRequestStatus{ + Conditions: []certapi.CertificateSigningRequestCondition{ + {Type: certapi.CertificateApproved, LastUpdateTime: now, LastTransitionTime: now}, }, }, - // reset conditions to existing conditions if Approved/Denied conditions could not be copied over - "v1beta1": { - Status: certapi.CertificateSigningRequestStatus{}, - }, }, }, } for _, tt := range tests { - for _, version := range []string{"v1", "v1beta1"} { - t.Run(tt.name+"_"+version, func(t *testing.T) { - ctx := genericapirequest.WithRequestInfo(context.TODO(), &genericapirequest.RequestInfo{APIGroup: "certificates.k8s.io", APIVersion: version}) - obj := tt.newObj.DeepCopy() - StatusStrategy.PrepareForUpdate(ctx, obj, tt.oldObj.DeepCopy()) - if !reflect.DeepEqual(obj, tt.expectedObjs[version]) { - t.Errorf("object diff: %s", diff.ObjectDiff(obj, tt.expectedObjs[version])) - } - }) - } + t.Run(tt.name, func(t *testing.T) { + obj := tt.newObj.DeepCopy() + StatusStrategy.PrepareForUpdate(context.TODO(), obj, tt.oldObj.DeepCopy()) + if !reflect.DeepEqual(obj, tt.expectedObj) { + t.Errorf("object diff: %s", diff.ObjectDiff(obj, tt.expectedObj)) + } + }) } } diff --git a/pkg/registry/certificates/rest/storage_certificates.go b/pkg/registry/certificates/rest/storage_certificates.go index 51d4df034f8..18be6d6ea26 100644 --- a/pkg/registry/certificates/rest/storage_certificates.go +++ b/pkg/registry/certificates/rest/storage_certificates.go @@ -18,7 +18,6 @@ package rest import ( certificatesapiv1 "k8s.io/api/certificates/v1" - certificatesapiv1beta1 "k8s.io/api/certificates/v1beta1" "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" genericapiserver "k8s.io/apiserver/pkg/server" @@ -35,14 +34,6 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // TODO refactor the plumbing to provide the information in the APIGroupInfo - if apiResourceConfigSource.VersionEnabled(certificatesapiv1beta1.SchemeGroupVersion) { - storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter) - if err != nil { - return genericapiserver.APIGroupInfo{}, false, err - } - apiGroupInfo.VersionedResourcesStorageMap[certificatesapiv1beta1.SchemeGroupVersion.Version] = storageMap - } - if apiResourceConfigSource.VersionEnabled(certificatesapiv1.SchemeGroupVersion) { storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter) if err != nil { @@ -54,20 +45,6 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag return apiGroupInfo, true, nil } -func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { - storage := map[string]rest.Storage{} - // certificatesigningrequests - csrStorage, csrStatusStorage, csrApprovalStorage, err := certificatestore.NewREST(restOptionsGetter) - if err != nil { - return storage, err - } - storage["certificatesigningrequests"] = csrStorage - storage["certificatesigningrequests/status"] = csrStatusStorage - storage["certificatesigningrequests/approval"] = csrApprovalStorage - - return storage, err -} - func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { storage := map[string]rest.Storage{} // certificatesigningrequests diff --git a/pkg/registry/coordination/rest/storage_coordination.go b/pkg/registry/coordination/rest/storage_coordination.go index d89e35c5d29..693168b5ba7 100644 --- a/pkg/registry/coordination/rest/storage_coordination.go +++ b/pkg/registry/coordination/rest/storage_coordination.go @@ -18,7 +18,6 @@ package rest import ( coordinationv1 "k8s.io/api/coordination/v1" - coordinationv1beta1 "k8s.io/api/coordination/v1beta1" "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" genericapiserver "k8s.io/apiserver/pkg/server" @@ -35,13 +34,6 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // TODO refactor the plumbing to provide the information in the APIGroupInfo - if apiResourceConfigSource.VersionEnabled(coordinationv1beta1.SchemeGroupVersion) { - if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { - return genericapiserver.APIGroupInfo{}, false, err - } else { - apiGroupInfo.VersionedResourcesStorageMap[coordinationv1beta1.SchemeGroupVersion.Version] = storageMap - } - } if apiResourceConfigSource.VersionEnabled(coordinationv1.SchemeGroupVersion) { if storageMap, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { return genericapiserver.APIGroupInfo{}, false, err @@ -52,18 +44,6 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag return apiGroupInfo, true, nil } -func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { - storage := map[string]rest.Storage{} - // leases - leaseStorage, err := leasestorage.NewREST(restOptionsGetter) - if err != nil { - return storage, err - } - storage["leases"] = leaseStorage - - return storage, err -} - func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { storage := map[string]rest.Storage{} // leases diff --git a/pkg/registry/extensions/OWNERS b/pkg/registry/extensions/OWNERS deleted file mode 100644 index 8af01ebfbdd..00000000000 --- a/pkg/registry/extensions/OWNERS +++ /dev/null @@ -1,5 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -reviewers: -- deads2k -- hongchaodeng diff --git a/pkg/registry/extensions/rest/storage_extensions.go b/pkg/registry/extensions/rest/storage_extensions.go deleted file mode 100644 index 9843fb6bb68..00000000000 --- a/pkg/registry/extensions/rest/storage_extensions.go +++ /dev/null @@ -1,66 +0,0 @@ -/* -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 rest - -import ( - extensionsapiv1beta1 "k8s.io/api/extensions/v1beta1" - "k8s.io/apiserver/pkg/registry/generic" - "k8s.io/apiserver/pkg/registry/rest" - genericapiserver "k8s.io/apiserver/pkg/server" - serverstorage "k8s.io/apiserver/pkg/server/storage" - "k8s.io/kubernetes/pkg/api/legacyscheme" - "k8s.io/kubernetes/pkg/apis/extensions" - ingressstore "k8s.io/kubernetes/pkg/registry/networking/ingress/storage" -) - -type RESTStorageProvider struct{} - -func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { - apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(extensions.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) - // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. - // TODO refactor the plumbing to provide the information in the APIGroupInfo - - if apiResourceConfigSource.VersionEnabled(extensionsapiv1beta1.SchemeGroupVersion) { - if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { - return genericapiserver.APIGroupInfo{}, false, err - } else { - apiGroupInfo.VersionedResourcesStorageMap[extensionsapiv1beta1.SchemeGroupVersion.Version] = storageMap - } - } - - return apiGroupInfo, true, nil -} - -func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { - storage := map[string]rest.Storage{} - - // ingresses - if apiResourceConfigSource.ResourceEnabled(extensionsapiv1beta1.SchemeGroupVersion.WithResource("ingresses")) { - ingressStorage, ingressStatusStorage, err := ingressstore.NewREST(restOptionsGetter) - if err != nil { - return storage, err - } - storage["ingresses"] = ingressStorage - storage["ingresses/status"] = ingressStatusStorage - } - - return storage, nil -} - -func (p RESTStorageProvider) GroupName() string { - return extensions.GroupName -} diff --git a/pkg/registry/networking/ingress/strategy.go b/pkg/registry/networking/ingress/strategy.go index 8d524188279..fc934d796d1 100644 --- a/pkg/registry/networking/ingress/strategy.go +++ b/pkg/registry/networking/ingress/strategy.go @@ -21,9 +21,7 @@ import ( apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" - "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/storage/names" "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/apis/networking" @@ -90,12 +88,8 @@ func (ingressStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Ob // Validate validates ingresses on create. func (ingressStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { - var requestGV schema.GroupVersion - if requestInfo, ok := request.RequestInfoFrom(ctx); ok { - requestGV = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} - } ingress := obj.(*networking.Ingress) - return validation.ValidateIngressCreate(ingress, requestGV) + return validation.ValidateIngressCreate(ingress) } // WarningsOnCreate returns warnings for the creation of the given object. @@ -112,11 +106,7 @@ func (ingressStrategy) AllowCreateOnUpdate() bool { // ValidateUpdate validates ingresses on update. func (ingressStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { - var requestGV schema.GroupVersion - if requestInfo, ok := request.RequestInfoFrom(ctx); ok { - requestGV = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} - } - return validation.ValidateIngressUpdate(obj.(*networking.Ingress), old.(*networking.Ingress), requestGV) + return validation.ValidateIngressUpdate(obj.(*networking.Ingress), old.(*networking.Ingress)) } // WarningsOnUpdate returns warnings for the given update. diff --git a/pkg/registry/networking/rest/storage_settings.go b/pkg/registry/networking/rest/storage_settings.go index 3d9687d5398..2ff3d0a0bf1 100644 --- a/pkg/registry/networking/rest/storage_settings.go +++ b/pkg/registry/networking/rest/storage_settings.go @@ -18,7 +18,6 @@ package rest import ( networkingapiv1 "k8s.io/api/networking/v1" - networkingapiv1beta1 "k8s.io/api/networking/v1beta1" "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" genericapiserver "k8s.io/apiserver/pkg/server" @@ -45,14 +44,6 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag } } - if apiResourceConfigSource.VersionEnabled(networkingapiv1beta1.SchemeGroupVersion) { - if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { - return genericapiserver.APIGroupInfo{}, false, err - } else { - apiGroupInfo.VersionedResourcesStorageMap[networkingapiv1beta1.SchemeGroupVersion.Version] = storageMap - } - } - return apiGroupInfo, true, nil } @@ -83,26 +74,6 @@ func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.API return storage, nil } -func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { - storage := map[string]rest.Storage{} - // ingresses - ingressStorage, ingressStatusStorage, err := ingressstore.NewREST(restOptionsGetter) - if err != nil { - return storage, err - } - storage["ingresses"] = ingressStorage - storage["ingresses/status"] = ingressStatusStorage - - // ingressclasses - ingressClassStorage, err := ingressclassstore.NewREST(restOptionsGetter) - if err != nil { - return storage, err - } - storage["ingressclasses"] = ingressClassStorage - - return storage, nil -} - func (p RESTStorageProvider) GroupName() string { return networking.GroupName } diff --git a/pkg/registry/rbac/rest/storage_rbac.go b/pkg/registry/rbac/rest/storage_rbac.go index 94995b9fee9..e73b332ba6a 100644 --- a/pkg/registry/rbac/rest/storage_rbac.go +++ b/pkg/registry/rbac/rest/storage_rbac.go @@ -24,8 +24,6 @@ import ( "k8s.io/klog/v2" rbacapiv1 "k8s.io/api/rbac/v1" - rbacapiv1alpha1 "k8s.io/api/rbac/v1alpha1" - rbacapiv1beta1 "k8s.io/api/rbac/v1beta1" "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -72,20 +70,6 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities. // TODO refactor the plumbing to provide the information in the APIGroupInfo - if apiResourceConfigSource.VersionEnabled(rbacapiv1alpha1.SchemeGroupVersion) { - if storageMap, err := p.storage(rbacapiv1alpha1.SchemeGroupVersion, apiResourceConfigSource, restOptionsGetter); err != nil { - return genericapiserver.APIGroupInfo{}, false, err - } else { - apiGroupInfo.VersionedResourcesStorageMap[rbacapiv1alpha1.SchemeGroupVersion.Version] = storageMap - } - } - if apiResourceConfigSource.VersionEnabled(rbacapiv1beta1.SchemeGroupVersion) { - if storageMap, err := p.storage(rbacapiv1beta1.SchemeGroupVersion, apiResourceConfigSource, restOptionsGetter); err != nil { - return genericapiserver.APIGroupInfo{}, false, err - } else { - apiGroupInfo.VersionedResourcesStorageMap[rbacapiv1beta1.SchemeGroupVersion.Version] = storageMap - } - } if apiResourceConfigSource.VersionEnabled(rbacapiv1.SchemeGroupVersion) { if storageMap, err := p.storage(rbacapiv1.SchemeGroupVersion, apiResourceConfigSource, restOptionsGetter); err != nil { return genericapiserver.APIGroupInfo{}, false, err diff --git a/pkg/registry/scheduling/rest/storage_scheduling.go b/pkg/registry/scheduling/rest/storage_scheduling.go index 6c1a4a58a01..be529711ab0 100644 --- a/pkg/registry/scheduling/rest/storage_scheduling.go +++ b/pkg/registry/scheduling/rest/storage_scheduling.go @@ -35,8 +35,6 @@ import ( "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/apis/scheduling" schedulingapiv1 "k8s.io/kubernetes/pkg/apis/scheduling/v1" - schedulingapiv1alpha1 "k8s.io/kubernetes/pkg/apis/scheduling/v1alpha1" - schedulingapiv1beta1 "k8s.io/kubernetes/pkg/apis/scheduling/v1beta1" priorityclassstore "k8s.io/kubernetes/pkg/registry/scheduling/priorityclass/storage" ) @@ -49,20 +47,6 @@ var _ genericapiserver.PostStartHookProvider = RESTStorageProvider{} func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error) { apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(scheduling.GroupName, legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs) - if apiResourceConfigSource.VersionEnabled(schedulingapiv1alpha1.SchemeGroupVersion) { - if storage, err := p.v1alpha1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { - return genericapiserver.APIGroupInfo{}, false, err - } else { - apiGroupInfo.VersionedResourcesStorageMap[schedulingapiv1alpha1.SchemeGroupVersion.Version] = storage - } - } - if apiResourceConfigSource.VersionEnabled(schedulingapiv1beta1.SchemeGroupVersion) { - if storage, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { - return genericapiserver.APIGroupInfo{}, false, err - } else { - apiGroupInfo.VersionedResourcesStorageMap[schedulingapiv1beta1.SchemeGroupVersion.Version] = storage - } - } if apiResourceConfigSource.VersionEnabled(schedulingapiv1.SchemeGroupVersion) { if storage, err := p.v1Storage(apiResourceConfigSource, restOptionsGetter); err != nil { return genericapiserver.APIGroupInfo{}, false, err @@ -73,29 +57,6 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag return apiGroupInfo, true, nil } -func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { - storage := map[string]rest.Storage{} - // priorityclasses - if priorityClassStorage, err := priorityclassstore.NewREST(restOptionsGetter); err != nil { - return nil, err - } else { - storage["priorityclasses"] = priorityClassStorage - } - return storage, nil -} - -func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { - storage := map[string]rest.Storage{} - // priorityclasses - if priorityClassStorage, err := priorityclassstore.NewREST(restOptionsGetter); err != nil { - return nil, err - } else { - storage["priorityclasses"] = priorityClassStorage - } - - return storage, nil -} - func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { storage := map[string]rest.Storage{} // priorityclasses diff --git a/pkg/registry/storage/rest/storage_storage.go b/pkg/registry/storage/rest/storage_storage.go index bafb1ce2c36..4e17538075c 100644 --- a/pkg/registry/storage/rest/storage_storage.go +++ b/pkg/registry/storage/rest/storage_storage.go @@ -68,12 +68,6 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { storage := map[string]rest.Storage{} - // volumeattachments - volumeAttachmentStorage, err := volumeattachmentstore.NewStorage(restOptionsGetter) - if err != nil { - return storage, err - } - storage["volumeattachments"] = volumeAttachmentStorage.VolumeAttachment // register csistoragecapacities csiStorageStorage, err := csistoragecapacitystore.NewStorage(restOptionsGetter) @@ -87,33 +81,6 @@ func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource serverstora func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) { storage := map[string]rest.Storage{} - // storageclasses - storageClassStorage, err := storageclassstore.NewREST(restOptionsGetter) - if err != nil { - return storage, err - } - storage["storageclasses"] = storageClassStorage - - // volumeattachments - volumeAttachmentStorage, err := volumeattachmentstore.NewStorage(restOptionsGetter) - if err != nil { - return storage, err - } - storage["volumeattachments"] = volumeAttachmentStorage.VolumeAttachment - - // register csinodes - csiNodeStorage, err := csinodestore.NewStorage(restOptionsGetter) - if err != nil { - return storage, err - } - storage["csinodes"] = csiNodeStorage.CSINode - - // register csidrivers - csiDriverStorage, err := csidriverstore.NewStorage(restOptionsGetter) - if err != nil { - return storage, err - } - storage["csidrivers"] = csiDriverStorage.CSIDriver // register csistoragecapacities csiStorageStorage, err := csistoragecapacitystore.NewStorage(restOptionsGetter) diff --git a/pkg/registry/storage/volumeattachment/strategy.go b/pkg/registry/storage/volumeattachment/strategy.go index 2e4182f2294..26bd749286a 100644 --- a/pkg/registry/storage/volumeattachment/strategy.go +++ b/pkg/registry/storage/volumeattachment/strategy.go @@ -19,12 +19,9 @@ package volumeattachment import ( "context" - storageapiv1beta1 "k8s.io/api/storage/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" - genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/storage/names" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/kubernetes/pkg/api/legacyscheme" @@ -62,20 +59,8 @@ func (volumeAttachmentStrategy) GetResetFields() map[fieldpath.APIVersion]*field // ResetBeforeCreate clears the Status field which is not allowed to be set by end users on creation. func (volumeAttachmentStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) { - var groupVersion schema.GroupVersion - - if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found { - groupVersion = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} - } - volumeAttachment := obj.(*storage.VolumeAttachment) - - switch groupVersion { - case storageapiv1beta1.SchemeGroupVersion: - // allow modification of status for v1beta1 - default: - volumeAttachment.Status = storage.VolumeAttachmentStatus{} - } + volumeAttachment.Status = storage.VolumeAttachmentStatus{} if !utilfeature.DefaultFeatureGate.Enabled(features.CSIMigration) { volumeAttachment.Spec.Source.InlineVolumeSpec = nil @@ -88,19 +73,8 @@ func (volumeAttachmentStrategy) Validate(ctx context.Context, obj runtime.Object errs := validation.ValidateVolumeAttachment(volumeAttachment) - var groupVersion schema.GroupVersion - - if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found { - groupVersion = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} - } - - switch groupVersion { - case storageapiv1beta1.SchemeGroupVersion: - // no extra validation - default: - // tighten up validation of newly created v1 attachments - errs = append(errs, validation.ValidateVolumeAttachmentV1(volumeAttachment)...) - } + // tighten up validation of newly created v1 attachments + errs = append(errs, validation.ValidateVolumeAttachmentV1(volumeAttachment)...) return errs } @@ -119,22 +93,11 @@ func (volumeAttachmentStrategy) AllowCreateOnUpdate() bool { // PrepareForUpdate sets the Status fields which is not allowed to be set by an end user updating a VolumeAttachment func (volumeAttachmentStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { - var groupVersion schema.GroupVersion - - if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found { - groupVersion = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} - } - newVolumeAttachment := obj.(*storage.VolumeAttachment) oldVolumeAttachment := old.(*storage.VolumeAttachment) - switch groupVersion { - case storageapiv1beta1.SchemeGroupVersion: - // allow modification of Status via main resource for v1beta1 - default: - newVolumeAttachment.Status = oldVolumeAttachment.Status - // No need to increment Generation because we don't allow updates to spec - } + newVolumeAttachment.Status = oldVolumeAttachment.Status + // No need to increment Generation because we don't allow updates to spec if !utilfeature.DefaultFeatureGate.Enabled(features.CSIMigration) && oldVolumeAttachment.Spec.Source.InlineVolumeSpec == nil { newVolumeAttachment.Spec.Source.InlineVolumeSpec = nil diff --git a/pkg/registry/storage/volumeattachment/strategy_test.go b/pkg/registry/storage/volumeattachment/strategy_test.go index 9ee8e73fb9e..a641761a764 100644 --- a/pkg/registry/storage/volumeattachment/strategy_test.go +++ b/pkg/registry/storage/volumeattachment/strategy_test.go @@ -17,13 +17,13 @@ limitations under the License. package volumeattachment import ( + "context" "testing" apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/diff" - "k8s.io/apimachinery/pkg/util/validation/field" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" utilfeature "k8s.io/apiserver/pkg/util/feature" featuregatetesting "k8s.io/component-base/featuregate/testing" @@ -196,77 +196,22 @@ func TestVolumeAttachmentStatusStrategy(t *testing.T) { } } -func TestBetaAndV1StatusUpdate(t *testing.T) { - tests := []struct { - requestInfo genericapirequest.RequestInfo - newStatus bool - expectedStatus bool - }{ - { - genericapirequest.RequestInfo{ - APIGroup: "storage.k8s.io", - APIVersion: "v1", - Resource: "volumeattachments", - }, - true, - false, - }, - { - genericapirequest.RequestInfo{ - APIGroup: "storage.k8s.io", - APIVersion: "v1beta1", - Resource: "volumeattachments", - }, - true, - true, - }, +func TestUpdatePreventsStatusWrite(t *testing.T) { + va := getValidVolumeAttachment("valid-attachment") + newAttachment := va.DeepCopy() + newAttachment.Status.Attached = true + Strategy.PrepareForUpdate(context.TODO(), newAttachment, va) + if newAttachment.Status.Attached { + t.Errorf("expected status to be %v got %v", false, newAttachment.Status.Attached) } - for _, test := range tests { - va := getValidVolumeAttachment("valid-attachment") - newAttachment := va.DeepCopy() - newAttachment.Status.Attached = test.newStatus - context := genericapirequest.WithRequestInfo(genericapirequest.NewContext(), &test.requestInfo) - Strategy.PrepareForUpdate(context, newAttachment, va) - if newAttachment.Status.Attached != test.expectedStatus { - t.Errorf("expected status to be %v got %v", test.expectedStatus, newAttachment.Status.Attached) - } - } - } -func TestBetaAndV1StatusCreate(t *testing.T) { - tests := []struct { - requestInfo genericapirequest.RequestInfo - newStatus bool - expectedStatus bool - }{ - { - genericapirequest.RequestInfo{ - APIGroup: "storage.k8s.io", - APIVersion: "v1", - Resource: "volumeattachments", - }, - true, - false, - }, - { - genericapirequest.RequestInfo{ - APIGroup: "storage.k8s.io", - APIVersion: "v1beta1", - Resource: "volumeattachments", - }, - true, - true, - }, - } - for _, test := range tests { - va := getValidVolumeAttachment("valid-attachment") - va.Status.Attached = test.newStatus - context := genericapirequest.WithRequestInfo(genericapirequest.NewContext(), &test.requestInfo) - Strategy.PrepareForCreate(context, va) - if va.Status.Attached != test.expectedStatus { - t.Errorf("expected status to be %v got %v", test.expectedStatus, va.Status.Attached) - } +func TestCreatePreventsStatusWrite(t *testing.T) { + va := getValidVolumeAttachment("valid-attachment") + va.Status.Attached = true + Strategy.PrepareForCreate(context.TODO(), va) + if va.Status.Attached { + t.Errorf("expected status to be false got %v", va.Status.Attached) } } @@ -276,14 +221,12 @@ func TestVolumeAttachmentValidation(t *testing.T) { tests := []struct { name string volumeAttachment *storage.VolumeAttachment - expectBetaError bool - expectV1Error bool + expectError bool }{ { "valid attachment", getValidVolumeAttachment("foo"), false, - false, }, { "invalid PV name", @@ -299,7 +242,6 @@ func TestVolumeAttachmentValidation(t *testing.T) { NodeName: "valid-node", }, }, - false, true, }, { @@ -316,7 +258,6 @@ func TestVolumeAttachmentValidation(t *testing.T) { NodeName: "valid-node", }, }, - false, true, }, { @@ -334,36 +275,17 @@ func TestVolumeAttachmentValidation(t *testing.T) { }, }, true, - true, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - - testValidation := func(va *storage.VolumeAttachment, apiVersion string) field.ErrorList { - ctx := genericapirequest.WithRequestInfo(genericapirequest.NewContext(), &genericapirequest.RequestInfo{ - APIGroup: "storage.k8s.io", - APIVersion: apiVersion, - Resource: "volumeattachments", - }) - return Strategy.Validate(ctx, va) + err := Strategy.Validate(context.TODO(), test.volumeAttachment) + if len(err) > 0 && !test.expectError { + t.Errorf("Validation of object failed: %+v", err) } - - v1Err := testValidation(test.volumeAttachment, "v1") - if len(v1Err) > 0 && !test.expectV1Error { - t.Errorf("Validation of v1 object failed: %+v", v1Err) - } - if len(v1Err) == 0 && test.expectV1Error { - t.Errorf("Validation of v1 object unexpectedly succeeded") - } - - betaErr := testValidation(test.volumeAttachment, "v1beta1") - if len(betaErr) > 0 && !test.expectBetaError { - t.Errorf("Validation of v1beta1 object failed: %+v", betaErr) - } - if len(betaErr) == 0 && test.expectBetaError { - t.Errorf("Validation of v1beta1 object unexpectedly succeeded") + if len(err) == 0 && test.expectError { + t.Errorf("Validation of object unexpectedly succeeded") } }) } diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go index 32ae5e99436..c2ce09e627a 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go @@ -27,7 +27,6 @@ import ( structuraldefaulting "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/defaulting" apiequality "k8s.io/apimachinery/pkg/api/equality" genericvalidation "k8s.io/apimachinery/pkg/api/validation" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/sets" utilvalidation "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" @@ -47,7 +46,7 @@ var ( ) // ValidateCustomResourceDefinition statically validates -func ValidateCustomResourceDefinition(obj *apiextensions.CustomResourceDefinition, requestGV schema.GroupVersion) field.ErrorList { +func ValidateCustomResourceDefinition(obj *apiextensions.CustomResourceDefinition) field.ErrorList { nameValidationFn := func(name string, prefix bool) []string { ret := genericvalidation.NameIsDNSSubdomain(name, prefix) requiredName := obj.Spec.Names.Plural + "." + obj.Spec.Group @@ -57,15 +56,13 @@ func ValidateCustomResourceDefinition(obj *apiextensions.CustomResourceDefinitio return ret } - allowDefaults, rejectDefaultsReason := allowDefaults(requestGV, nil) opts := validationOptions{ - allowDefaults: allowDefaults, - disallowDefaultsReason: rejectDefaultsReason, + allowDefaults: true, requireRecognizedConversionReviewVersion: true, requireImmutableNames: false, - requireOpenAPISchema: requireOpenAPISchema(requestGV, nil), - requireValidPropertyType: requireValidPropertyType(requestGV, nil), - requireStructuralSchema: requireStructuralSchema(requestGV, nil), + requireOpenAPISchema: true, + requireValidPropertyType: true, + requireStructuralSchema: true, requirePrunedDefaults: true, requireAtomicSetType: true, requireMapListKeysMapSetValidation: true, @@ -75,8 +72,8 @@ func ValidateCustomResourceDefinition(obj *apiextensions.CustomResourceDefinitio allErrs = append(allErrs, validateCustomResourceDefinitionSpec(&obj.Spec, opts, field.NewPath("spec"))...) allErrs = append(allErrs, ValidateCustomResourceDefinitionStatus(&obj.Status, field.NewPath("status"))...) allErrs = append(allErrs, ValidateCustomResourceDefinitionStoredVersions(obj.Status.StoredVersions, obj.Spec.Versions, field.NewPath("status").Child("storedVersions"))...) - allErrs = append(allErrs, validateAPIApproval(obj, nil, requestGV)...) - allErrs = append(allErrs, validatePreserveUnknownFields(obj, nil, requestGV)...) + allErrs = append(allErrs, validateAPIApproval(obj, nil)...) + allErrs = append(allErrs, validatePreserveUnknownFields(obj, nil)...) return allErrs } @@ -107,16 +104,14 @@ type validationOptions struct { } // ValidateCustomResourceDefinitionUpdate statically validates -func ValidateCustomResourceDefinitionUpdate(obj, oldObj *apiextensions.CustomResourceDefinition, requestGV schema.GroupVersion) field.ErrorList { - allowDefaults, rejectDefaultsReason := allowDefaults(requestGV, &oldObj.Spec) +func ValidateCustomResourceDefinitionUpdate(obj, oldObj *apiextensions.CustomResourceDefinition) field.ErrorList { opts := validationOptions{ - allowDefaults: allowDefaults, - disallowDefaultsReason: rejectDefaultsReason, + allowDefaults: true, requireRecognizedConversionReviewVersion: oldObj.Spec.Conversion == nil || hasValidConversionReviewVersionOrEmpty(oldObj.Spec.Conversion.ConversionReviewVersions), requireImmutableNames: apiextensions.IsCRDConditionTrue(oldObj, apiextensions.Established), - requireOpenAPISchema: requireOpenAPISchema(requestGV, &oldObj.Spec), - requireValidPropertyType: requireValidPropertyType(requestGV, &oldObj.Spec), - requireStructuralSchema: requireStructuralSchema(requestGV, &oldObj.Spec), + requireOpenAPISchema: requireOpenAPISchema(&oldObj.Spec), + requireValidPropertyType: requireValidPropertyType(&oldObj.Spec), + requireStructuralSchema: requireStructuralSchema(&oldObj.Spec), requirePrunedDefaults: requirePrunedDefaults(&oldObj.Spec), requireAtomicSetType: requireAtomicSetType(&oldObj.Spec), requireMapListKeysMapSetValidation: requireMapListKeysMapSetValidation(&oldObj.Spec), @@ -126,8 +121,8 @@ func ValidateCustomResourceDefinitionUpdate(obj, oldObj *apiextensions.CustomRes allErrs = append(allErrs, validateCustomResourceDefinitionSpecUpdate(&obj.Spec, &oldObj.Spec, opts, field.NewPath("spec"))...) allErrs = append(allErrs, ValidateCustomResourceDefinitionStatus(&obj.Status, field.NewPath("status"))...) allErrs = append(allErrs, ValidateCustomResourceDefinitionStoredVersions(obj.Status.StoredVersions, obj.Spec.Versions, field.NewPath("status").Child("storedVersions"))...) - allErrs = append(allErrs, validateAPIApproval(obj, oldObj, requestGV)...) - allErrs = append(allErrs, validatePreserveUnknownFields(obj, oldObj, requestGV)...) + allErrs = append(allErrs, validateAPIApproval(obj, oldObj)...) + allErrs = append(allErrs, validatePreserveUnknownFields(obj, oldObj)...) return allErrs } @@ -1129,11 +1124,7 @@ func allowedAtRootSchema(field string) bool { } // requireOpenAPISchema returns true if the request group version requires a schema -func requireOpenAPISchema(requestGV schema.GroupVersion, oldCRDSpec *apiextensions.CustomResourceDefinitionSpec) bool { - if requestGV == apiextensionsv1beta1.SchemeGroupVersion { - // for backwards compatibility - return false - } +func requireOpenAPISchema(oldCRDSpec *apiextensions.CustomResourceDefinitionSpec) bool { if oldCRDSpec != nil && !allVersionsSpecifyOpenAPISchema(oldCRDSpec) { // don't tighten validation on existing persisted data return false @@ -1152,19 +1143,6 @@ func allVersionsSpecifyOpenAPISchema(spec *apiextensions.CustomResourceDefinitio return true } -// allowDefaults returns true if the defaulting feature is enabled and the request group version allows adding defaults, -// or false and a reason for the user if defaults are not allowed. -func allowDefaults(requestGV schema.GroupVersion, oldCRDSpec *apiextensions.CustomResourceDefinitionSpec) (bool, string) { - if oldCRDSpec != nil && specHasDefaults(oldCRDSpec) { - // don't tighten validation on existing persisted data - return true, "" - } - if requestGV == apiextensionsv1beta1.SchemeGroupVersion { - return false, "(cannot set default values in apiextensions.k8s.io/v1beta1 CRDs, must use apiextensions.k8s.io/v1)" - } - return true, "" -} - func specHasDefaults(spec *apiextensions.CustomResourceDefinitionSpec) bool { return hasSchemaWith(spec, schemaHasDefaults) } @@ -1277,11 +1255,7 @@ func schemaHasKubernetesExtensions(s *apiextensions.JSONSchemaProps) bool { } // requireStructuralSchema returns true if schemas specified must be structural -func requireStructuralSchema(requestGV schema.GroupVersion, oldCRDSpec *apiextensions.CustomResourceDefinitionSpec) bool { - if requestGV == apiextensionsv1beta1.SchemeGroupVersion { - // for compatibility - return false - } +func requireStructuralSchema(oldCRDSpec *apiextensions.CustomResourceDefinitionSpec) bool { if oldCRDSpec != nil && specHasNonStructuralSchema(oldCRDSpec) { // don't tighten validation on existing persisted data return false @@ -1380,11 +1354,7 @@ func hasInvalidMapListKeysMapSet(schema *apiextensions.JSONSchemaProps) bool { } // requireValidPropertyType returns true if valid openapi v3 types should be required for the given API version -func requireValidPropertyType(requestGV schema.GroupVersion, oldCRDSpec *apiextensions.CustomResourceDefinitionSpec) bool { - if requestGV == apiextensionsv1beta1.SchemeGroupVersion { - // for compatibility - return false - } +func requireValidPropertyType(oldCRDSpec *apiextensions.CustomResourceDefinitionSpec) bool { if oldCRDSpec != nil && specHasInvalidTypes(oldCRDSpec) { // don't tighten validation on existing persisted data return false @@ -1393,13 +1363,8 @@ func requireValidPropertyType(requestGV schema.GroupVersion, oldCRDSpec *apiexte } // validateAPIApproval returns a list of errors if the API approval annotation isn't valid -func validateAPIApproval(newCRD, oldCRD *apiextensions.CustomResourceDefinition, requestGV schema.GroupVersion) field.ErrorList { +func validateAPIApproval(newCRD, oldCRD *apiextensions.CustomResourceDefinition) field.ErrorList { // check to see if we need confirm API approval for kube group. - - if requestGV == apiextensionsv1beta1.SchemeGroupVersion { - // no-op for compatibility with v1beta1 - return nil - } if !apihelpers.IsProtectedCommunityGroup(newCRD.Spec.Group) { // no-op for non-protected groups return nil @@ -1433,12 +1398,7 @@ func validateAPIApproval(newCRD, oldCRD *apiextensions.CustomResourceDefinition, } } -func validatePreserveUnknownFields(crd, oldCRD *apiextensions.CustomResourceDefinition, requestGV schema.GroupVersion) field.ErrorList { - if requestGV == apiextensionsv1beta1.SchemeGroupVersion { - // no-op for compatibility with v1beta1 - return nil - } - +func validatePreserveUnknownFields(crd, oldCRD *apiextensions.CustomResourceDefinition) field.ErrorList { if oldCRD != nil && oldCRD.Spec.PreserveUnknownFields != nil && *oldCRD.Spec.PreserveUnknownFields { // no-op for compatibility with existing data return nil diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go index 0f7cad95454..538e24f9099 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation_test.go @@ -24,12 +24,10 @@ import ( "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" apiextensionsfuzzer "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" "k8s.io/apimachinery/pkg/api/apitesting/fuzzer" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/util/json" "k8s.io/apimachinery/pkg/util/validation/field" @@ -60,9 +58,6 @@ func immutable(path ...string) validationMatch { func forbidden(path ...string) validationMatch { return validationMatch{path: field.NewPath(path[0], path[1:]...), errorType: field.ErrorTypeForbidden} } -func forbiddenContains(contains string, path ...string) validationMatch { - return validationMatch{path: field.NewPath(path[0], path[1:]...), errorType: field.ErrorTypeForbidden, contains: contains} -} func (v validationMatch) matches(err *field.Error) bool { return err.Type == v.errorType && err.Field == v.path.String() && strings.Contains(err.Error(), v.contains) @@ -79,44 +74,12 @@ func TestValidateCustomResourceDefinition(t *testing.T) { }, } tests := []struct { - name string - resource *apiextensions.CustomResourceDefinition - requestGV schema.GroupVersion - errors []validationMatch + name string + resource *apiextensions.CustomResourceDefinition + errors []validationMatch }{ { - name: "invalid types allowed via v1beta1", - 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, - }}, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{"foo": {Type: "bogus"}}, - }, - }, - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, - }, - { - name: "invalid types disallowed via v1", + name: "invalid types disallowed", resource: &apiextensions.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"}, Spec: apiextensions.CustomResourceDefinitionSpec{ @@ -141,7 +104,6 @@ func TestValidateCustomResourceDefinition(t *testing.T) { StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1.SchemeGroupVersion, errors: []validationMatch{ unsupported("spec.validation.openAPIV3Schema.properties[foo].type"), }, @@ -374,13 +336,17 @@ func TestValidateCustomResourceDefinition(t *testing.T) { URL: strPtr("https://example.com/webhook"), }, }, - PreserveUnknownFields: pointer.BoolPtr(true), + PreserveUnknownFields: pointer.BoolPtr(false), + Validation: &apiextensions.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ + Type: "object", + }, + }, }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, errors: []validationMatch{ forbidden("spec", "conversion", "webhookClientConfig"), }, @@ -414,13 +380,17 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Strategy: apiextensions.ConversionStrategyType("None"), ConversionReviewVersions: []string{"v1beta1"}, }, - PreserveUnknownFields: pointer.BoolPtr(true), + PreserveUnknownFields: pointer.BoolPtr(false), + Validation: &apiextensions.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ + Type: "object", + }, + }, }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, errors: []validationMatch{ forbidden("spec", "conversion", "conversionReviewVersions"), }, @@ -726,14 +696,18 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Conversion: &apiextensions.CustomResourceConversion{ Strategy: apiextensions.ConversionStrategyType("None"), }, - PreserveUnknownFields: pointer.BoolPtr(true), + PreserveUnknownFields: nil, + Validation: &apiextensions.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ + Type: "object", + }, + }, }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{"version1"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, - errors: []validationMatch{}, + errors: []validationMatch{}, }, { name: "webhook conversion without preserveUnknownFields=false", @@ -767,13 +741,17 @@ func TestValidateCustomResourceDefinition(t *testing.T) { }, ConversionReviewVersions: []string{"v1beta1"}, }, - PreserveUnknownFields: pointer.BoolPtr(true), + PreserveUnknownFields: nil, + Validation: &apiextensions.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ + Type: "object", + }, + }, }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{"version1"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, errors: []validationMatch{ invalid("spec", "conversion", "strategy"), }, @@ -896,13 +874,17 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Conversion: &apiextensions.CustomResourceConversion{ Strategy: apiextensions.ConversionStrategyType("None"), }, - PreserveUnknownFields: pointer.BoolPtr(true), + PreserveUnknownFields: pointer.BoolPtr(false), + Validation: &apiextensions.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ + Type: "object", + }, + }, }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, errors: []validationMatch{ invalid("spec", "versions"), }, @@ -935,13 +917,17 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Conversion: &apiextensions.CustomResourceConversion{ Strategy: apiextensions.ConversionStrategyType("None"), }, - PreserveUnknownFields: pointer.BoolPtr(true), + PreserveUnknownFields: pointer.BoolPtr(false), + Validation: &apiextensions.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ + Type: "object", + }, + }, }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, errors: []validationMatch{ invalid("spec", "versions"), invalid("status", "storedVersions"), @@ -975,13 +961,17 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Conversion: &apiextensions.CustomResourceConversion{ Strategy: apiextensions.ConversionStrategyType("None"), }, - PreserveUnknownFields: pointer.BoolPtr(true), + PreserveUnknownFields: pointer.BoolPtr(false), + Validation: &apiextensions.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ + Type: "object", + }, + }, }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, errors: []validationMatch{ invalid("status", "storedVersions"), }, @@ -1009,13 +999,17 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Conversion: &apiextensions.CustomResourceConversion{ Strategy: apiextensions.ConversionStrategyType("None"), }, - PreserveUnknownFields: pointer.BoolPtr(true), + PreserveUnknownFields: pointer.BoolPtr(false), + Validation: &apiextensions.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ + Type: "object", + }, + }, }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, errors: []validationMatch{ invalid("status", "storedVersions"), }, @@ -1029,10 +1023,14 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Names: apiextensions.CustomResourceDefinitionNames{ Plural: "plural", }, - PreserveUnknownFields: pointer.BoolPtr(true), + PreserveUnknownFields: pointer.BoolPtr(false), + Validation: &apiextensions.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ + Type: "object", + }, + }, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, errors: []validationMatch{ invalid("status", "storedVersions"), invalid("metadata", "name"), @@ -1074,7 +1072,12 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Kind: "value()*a", ListKind: "value()*a", }, - PreserveUnknownFields: pointer.BoolPtr(true), + PreserveUnknownFields: pointer.BoolPtr(false), + Validation: &apiextensions.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ + Type: "object", + }, + }, }, Status: apiextensions.CustomResourceDefinitionStatus{ AcceptedNames: apiextensions.CustomResourceDefinitionNames{ @@ -1085,7 +1088,6 @@ func TestValidateCustomResourceDefinition(t *testing.T) { }, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, errors: []validationMatch{ invalid("status", "storedVersions"), invalid("metadata", "name"), @@ -1122,7 +1124,12 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Kind: "matching", ListKind: "matching", }, - PreserveUnknownFields: pointer.BoolPtr(true), + PreserveUnknownFields: pointer.BoolPtr(false), + Validation: &apiextensions.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ + Type: "object", + }, + }, }, Status: apiextensions.CustomResourceDefinitionStatus{ AcceptedNames: apiextensions.CustomResourceDefinitionNames{ @@ -1134,7 +1141,6 @@ func TestValidateCustomResourceDefinition(t *testing.T) { StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, errors: []validationMatch{ invalid("metadata", "name"), invalid("spec", "group"), @@ -1163,21 +1169,26 @@ func TestValidateCustomResourceDefinition(t *testing.T) { }, Validation: &apiextensions.CustomResourceValidation{ OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ + Type: "object", Properties: map[string]apiextensions.JSONSchemaProps{ - "foo": {}, + "foo": { + Type: "object", + Properties: map[string]apiextensions.JSONSchemaProps{ + "bar": {Type: "object"}, + }, + AdditionalProperties: &apiextensions.JSONSchemaPropsOrBool{Allows: false}, + }, }, - AdditionalProperties: &apiextensions.JSONSchemaPropsOrBool{Allows: false}, }, }, - PreserveUnknownFields: pointer.BoolPtr(true), + PreserveUnknownFields: pointer.BoolPtr(false), }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, errors: []validationMatch{ - forbidden("spec", "validation", "openAPIV3Schema", "additionalProperties"), + forbidden("spec", "validation", "openAPIV3Schema", "properties[foo]", "additionalProperties"), }, }, { @@ -1200,22 +1211,27 @@ func TestValidateCustomResourceDefinition(t *testing.T) { }, Validation: &apiextensions.CustomResourceValidation{ OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - AdditionalProperties: &apiextensions.JSONSchemaPropsOrBool{ - Allows: true, - Schema: &apiextensions.JSONSchemaProps{ - Type: "string", + Type: "object", + Properties: map[string]apiextensions.JSONSchemaProps{ + "foo": { + Type: "object", + AdditionalProperties: &apiextensions.JSONSchemaPropsOrBool{ + Allows: true, + Schema: &apiextensions.JSONSchemaProps{ + Type: "string", + }, + }, }, }, }, }, - PreserveUnknownFields: pointer.BoolPtr(true), + PreserveUnknownFields: pointer.BoolPtr(false), }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, - errors: []validationMatch{}, + errors: []validationMatch{}, }, { name: "per-version fields may not all be set to identical values (top-level field should be used instead)", @@ -1253,13 +1269,12 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Kind: "Plural", ListKind: "PluralList", }, - PreserveUnknownFields: pointer.BoolPtr(true), + PreserveUnknownFields: pointer.BoolPtr(false), }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, errors: []validationMatch{ // Per-version schema/subresources/columns may not all be set to identical values. // Note that the test will fail if we de-duplicate the expected errors below. @@ -1427,7 +1442,6 @@ func TestValidateCustomResourceDefinition(t *testing.T) { StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, errors: []validationMatch{ required("spec", "versions[1]", "schema", "openAPIV3Schema"), }, @@ -1468,14 +1482,13 @@ func TestValidateCustomResourceDefinition(t *testing.T) { StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, errors: []validationMatch{ required("spec", "versions[0]", "schema", "openAPIV3Schema"), required("spec", "versions[1]", "schema", "openAPIV3Schema"), }, }, { - name: "no schema via v1", + name: "schema is required", resource: &apiextensions.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"}, Spec: apiextensions.CustomResourceDefinitionSpec{ @@ -1510,14 +1523,13 @@ func TestValidateCustomResourceDefinition(t *testing.T) { StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1.SchemeGroupVersion, errors: []validationMatch{ required("spec", "versions[0]", "schema", "openAPIV3Schema"), required("spec", "versions[1]", "schema", "openAPIV3Schema"), }, }, { - name: "preserveUnknownFields: true via v1", + name: "preserveUnknownFields: true", resource: &apiextensions.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"}, Spec: apiextensions.CustomResourceDefinitionSpec{ @@ -1531,8 +1543,7 @@ func TestValidateCustomResourceDefinition(t *testing.T) { }, Status: apiextensions.CustomResourceDefinitionStatus{StoredVersions: []string{"version"}}, }, - requestGV: apiextensionsv1.SchemeGroupVersion, - errors: []validationMatch{invalid("spec.preserveUnknownFields")}, + errors: []validationMatch{invalid("spec.preserveUnknownFields")}, }, { name: "labelSelectorPath outside of .spec and .status", @@ -1601,56 +1612,23 @@ func TestValidateCustomResourceDefinition(t *testing.T) { Kind: "Plural", ListKind: "PluralList", }, - PreserveUnknownFields: pointer.BoolPtr(true), + PreserveUnknownFields: pointer.BoolPtr(false), + Validation: &apiextensions.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ + Type: "object", + }, + }, }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{"version0"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, errors: []validationMatch{ invalid("spec", "versions[3]", "subresources", "scale", "labelSelectorPath"), }, }, { - name: "defaults with enabled feature gate via v1beta1", - resource: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: singleVersionList, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "a": { - Type: "number", - Default: jsonPtr(42.0), - }, - }, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(true), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, - errors: []validationMatch{ - forbiddenContains("cannot set default values in apiextensions.k8s.io/v1beta1", "spec", "validation", "openAPIV3Schema", "properties[a]", "default"), // disallowed via v1beta1 - }, - }, - { - name: "defaults with enabled feature gate via v1", + name: "defaults with enabled feature gate", resource: &apiextensions.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"}, Spec: apiextensions.CustomResourceDefinitionSpec{ @@ -1681,116 +1659,6 @@ func TestValidateCustomResourceDefinition(t *testing.T) { StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1.SchemeGroupVersion, - }, - { - name: "x-kubernetes-int-or-string without structural", - resource: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: singleVersionList, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Properties: map[string]apiextensions.JSONSchemaProps{ - "intorstring": { - XIntOrString: true, - }, - }, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(true), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, - errors: []validationMatch{ - required("spec", "validation", "openAPIV3Schema", "type"), - }, - }, - { - name: "x-kubernetes-preserve-unknown-fields without structural", - resource: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: singleVersionList, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Properties: map[string]apiextensions.JSONSchemaProps{ - "raw": { - XPreserveUnknownFields: pointer.BoolPtr(true), - }, - }, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(true), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, - errors: []validationMatch{ - required("spec", "validation", "openAPIV3Schema", "type"), - }, - }, - { - name: "x-kubernetes-embedded-resource without structural", - resource: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: singleVersionList, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Properties: map[string]apiextensions.JSONSchemaProps{ - "embedded": { - Type: "object", - XEmbeddedResource: true, - Properties: map[string]apiextensions.JSONSchemaProps{ - "foo": {Type: "string"}, - }, - }, - }, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(true), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, - errors: []validationMatch{ - required("spec", "validation", "openAPIV3Schema", "type"), - }, }, { name: "x-kubernetes-embedded-resource with pruning and empty properties", @@ -1809,7 +1677,8 @@ func TestValidateCustomResourceDefinition(t *testing.T) { }, Validation: &apiextensions.CustomResourceValidation{ OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", + Type: "object", + XPreserveUnknownFields: pointer.BoolPtr(true), Properties: map[string]apiextensions.JSONSchemaProps{ "nil": { Type: "object", @@ -1824,13 +1693,11 @@ func TestValidateCustomResourceDefinition(t *testing.T) { }, }, }, - PreserveUnknownFields: pointer.BoolPtr(true), }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, errors: []validationMatch{ required("spec", "validation", "openAPIV3Schema", "properties[nil]", "properties"), required("spec", "validation", "openAPIV3Schema", "properties[empty]", "properties"), @@ -1889,13 +1756,11 @@ func TestValidateCustomResourceDefinition(t *testing.T) { }, }, }, - PreserveUnknownFields: pointer.BoolPtr(true), }, Status: apiextensions.CustomResourceDefinitionStatus{ StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, errors: []validationMatch{ forbidden("spec", "validation", "openAPIV3Schema", "properties[embedded]", "properties[metadata]", "x-kubernetes-embedded-resource"), forbidden("spec", "validation", "openAPIV3Schema", "properties[embedded]", "properties[apiVersion]", "properties[foo]", "x-kubernetes-embedded-resource"), @@ -4083,7 +3948,7 @@ func TestValidateCustomResourceDefinition(t *testing.T) { if tc.resource.Spec.Conversion != nil && tc.resource.Spec.Conversion.Strategy == apiextensions.WebhookConverter && len(tc.resource.Spec.Conversion.ConversionReviewVersions) == 0 { tc.resource.Spec.Conversion.ConversionReviewVersions = []string{"v1beta1"} } - errs := ValidateCustomResourceDefinition(tc.resource, tc.requestGV) + errs := ValidateCustomResourceDefinition(tc.resource) seenErrs := make([]bool, len(errs)) for _, expectedError := range tc.errors { @@ -4112,14 +3977,13 @@ func TestValidateCustomResourceDefinition(t *testing.T) { func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { tests := []struct { - name string - old *apiextensions.CustomResourceDefinition - resource *apiextensions.CustomResourceDefinition - requestGV schema.GroupVersion - errors []validationMatch + name string + old *apiextensions.CustomResourceDefinition + resource *apiextensions.CustomResourceDefinition + errors []validationMatch }{ { - name: "invalid type updates allowed via v1beta1", + name: "invalid types updates disallowed", old: &apiextensions.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, Spec: apiextensions.CustomResourceDefinitionSpec{ @@ -4167,64 +4031,12 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, - }, - { - name: "invalid types updates disallowed via v1", - old: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, - 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}}, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - }, - }, - PreserveUnknownFields: pointer.BoolPtr(false), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - resource: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, - 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}}, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{"foo": {Type: "bogus"}}, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(false), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - requestGV: apiextensionsv1.SchemeGroupVersion, errors: []validationMatch{ unsupported("spec.validation.openAPIV3Schema.properties[foo].type"), }, }, { - name: "invalid types updates allowed via v1 if old object has invalid types", + name: "invalid types updates allowed if old object has invalid types", old: &apiextensions.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, Spec: apiextensions.CustomResourceDefinitionSpec{ @@ -4273,7 +4085,6 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1.SchemeGroupVersion, }, { name: "non-atomic items in lists of type set allowed if pre-existing", @@ -4343,7 +4154,6 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1.SchemeGroupVersion, }, { name: "reject non-atomic items in lists of type set if not pre-existing", @@ -4404,13 +4214,12 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1.SchemeGroupVersion, errors: []validationMatch{ invalid("spec", "validation", "openAPIV3Schema", "properties[bar]", "items", "x-kubernetes-map-type"), }, }, { - name: "structural to non-structural updates allowed via v1beta1", + name: "structural to non-structural updates not allowed", old: &apiextensions.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, Spec: apiextensions.CustomResourceDefinitionSpec{ @@ -4449,55 +4258,12 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, - }, - { - name: "structural to non-structural updates not allowed via v1", - old: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, - 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}}, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{"foo": {Type: "integer"}}, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(true), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - resource: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, - 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}}, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{"foo": {}}, // untyped object - }, - }, - PreserveUnknownFields: pointer.BoolPtr(true), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - requestGV: apiextensionsv1.SchemeGroupVersion, errors: []validationMatch{ required("spec.validation.openAPIV3Schema.properties[foo].type"), }, }, { - name: "absent schema to non-structural updates not allowed via v1", + name: "absent schema to non-structural updates not allowed", old: &apiextensions.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, Spec: apiextensions.CustomResourceDefinitionSpec{ @@ -4531,13 +4297,12 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1.SchemeGroupVersion, errors: []validationMatch{ required("spec.validation.openAPIV3Schema.properties[foo].type"), }, }, { - name: "non-structural updates allowed via v1 if old object has non-structural schema", + name: "non-structural updates allowed if old object has non-structural schema", old: &apiextensions.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, Spec: apiextensions.CustomResourceDefinitionSpec{ @@ -4590,8 +4355,7 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1.SchemeGroupVersion, - errors: []validationMatch{}, + errors: []validationMatch{}, }, { name: "webhookconfig: should pass on invalid ConversionReviewVersion with old invalid versions", @@ -5457,74 +5221,7 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { errors: []validationMatch{}, }, { - name: "switch on preserveUnknownFields without structural schema", - old: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: "plural.group.com", - ResourceVersion: "42", - }, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: validValidationSchema, - }, - Versions: []apiextensions.CustomResourceDefinitionVersion{ - { - Name: "version", - Served: true, - Storage: true, - }, - }, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - PreserveUnknownFields: pointer.BoolPtr(false), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - resource: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: "plural.group.com", - ResourceVersion: "42", - }, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: validUnstructuralValidationSchema, - }, - Versions: []apiextensions.CustomResourceDefinitionVersion{ - { - Name: "version", - Served: true, - Storage: true, - }, - }, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - PreserveUnknownFields: pointer.BoolPtr(true), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, - errors: []validationMatch{}, - }, - { - name: "switch to preserveUnknownFields: true is allowed via v1beta1", + name: "switch to preserveUnknownFields: true is forbidden", old: &apiextensions.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, Spec: apiextensions.CustomResourceDefinitionSpec{ @@ -5551,42 +5248,10 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { }, Status: apiextensions.CustomResourceDefinitionStatus{StoredVersions: []string{"version"}}, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, - errors: []validationMatch{}, + errors: []validationMatch{invalid("spec.preserveUnknownFields")}, }, { - name: "switch to preserveUnknownFields: true is forbidden via v1", - old: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: []apiextensions.CustomResourceDefinitionVersion{{Name: "version", Served: true, Storage: true}}, - Validation: &apiextensions.CustomResourceValidation{OpenAPIV3Schema: &apiextensions.JSONSchemaProps{Type: "object"}}, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{Plural: "plural", Singular: "singular", Kind: "Plural", ListKind: "PluralList"}, - PreserveUnknownFields: pointer.BoolPtr(false), - }, - Status: apiextensions.CustomResourceDefinitionStatus{StoredVersions: []string{"version"}}, - }, - resource: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: []apiextensions.CustomResourceDefinitionVersion{{Name: "version", Served: true, Storage: true}}, - Validation: &apiextensions.CustomResourceValidation{OpenAPIV3Schema: &apiextensions.JSONSchemaProps{Type: "object"}}, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{Plural: "plural", Singular: "singular", Kind: "Plural", ListKind: "PluralList"}, - PreserveUnknownFields: pointer.BoolPtr(true), - }, - Status: apiextensions.CustomResourceDefinitionStatus{StoredVersions: []string{"version"}}, - }, - requestGV: apiextensionsv1.SchemeGroupVersion, - errors: []validationMatch{invalid("spec.preserveUnknownFields")}, - }, - { - name: "keep preserveUnknownFields: true is allowed via v1", + name: "keep preserveUnknownFields: true is allowed", old: &apiextensions.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, Spec: apiextensions.CustomResourceDefinitionSpec{ @@ -5613,11 +5278,10 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { }, Status: apiextensions.CustomResourceDefinitionStatus{StoredVersions: []string{"version"}}, }, - requestGV: apiextensionsv1.SchemeGroupVersion, - errors: []validationMatch{}, + errors: []validationMatch{}, }, { - name: "schema not required via v1beta1", + name: "schema not required if old object is missing schema", old: &apiextensions.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, Spec: apiextensions.CustomResourceDefinitionSpec{ @@ -5642,40 +5306,10 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { }, Status: apiextensions.CustomResourceDefinitionStatus{StoredVersions: []string{"version"}}, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, - errors: []validationMatch{}, + errors: []validationMatch{}, }, { - name: "schema not required via v1 if old object is missing schema", - old: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: []apiextensions.CustomResourceDefinitionVersion{{Name: "version", Served: true, Storage: true}}, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{Plural: "plural", Singular: "singular", Kind: "Plural", ListKind: "PluralList"}, - PreserveUnknownFields: pointer.BoolPtr(true), - }, - Status: apiextensions.CustomResourceDefinitionStatus{StoredVersions: []string{"version"}}, - }, - resource: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: []apiextensions.CustomResourceDefinitionVersion{{Name: "version", Served: true, Storage: true}}, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{Plural: "plural", Singular: "singular", Kind: "Plural", ListKind: "PluralList"}, - PreserveUnknownFields: pointer.BoolPtr(true), - }, - Status: apiextensions.CustomResourceDefinitionStatus{StoredVersions: []string{"version"}}, - }, - requestGV: apiextensionsv1.SchemeGroupVersion, - errors: []validationMatch{}, - }, - { - name: "schema not required via v1 if old object is missing schema for some versions", + name: "schema not required if old object is missing schema for some versions", old: &apiextensions.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, Spec: apiextensions.CustomResourceDefinitionSpec{ @@ -5706,11 +5340,10 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { }, Status: apiextensions.CustomResourceDefinitionStatus{StoredVersions: []string{"version"}}, }, - requestGV: apiextensionsv1.SchemeGroupVersion, - errors: []validationMatch{}, + errors: []validationMatch{}, }, { - name: "schema required via v1 if old object has top-level schema", + name: "schema required if old object has top-level schema", old: &apiextensions.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, Spec: apiextensions.CustomResourceDefinitionSpec{ @@ -5736,13 +5369,12 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { }, Status: apiextensions.CustomResourceDefinitionStatus{StoredVersions: []string{"version"}}, }, - requestGV: apiextensionsv1.SchemeGroupVersion, errors: []validationMatch{ required("spec.versions[0].schema.openAPIV3Schema"), }, }, { - name: "schema required via v1 if all versions of old object have schema", + name: "schema required if all versions of old object have schema", old: &apiextensions.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{Name: "plural.group.com", ResourceVersion: "1"}, Spec: apiextensions.CustomResourceDefinitionSpec{ @@ -5773,14 +5405,13 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { }, Status: apiextensions.CustomResourceDefinitionStatus{StoredVersions: []string{"version"}}, }, - requestGV: apiextensionsv1.SchemeGroupVersion, errors: []validationMatch{ required("spec.versions[0].schema.openAPIV3Schema"), required("spec.versions[1].schema.openAPIV3Schema"), }, }, { - name: "setting defaults with enabled feature gate via v1beta1", + name: "setting defaults with enabled feature gate", old: &apiextensions.CustomResourceDefinition{ ObjectMeta: metav1.ObjectMeta{ Name: "plural.group.com", @@ -5858,90 +5489,7 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { StoredVersions: []string{"version"}, }, }, - requestGV: apiextensionsv1beta1.SchemeGroupVersion, - errors: []validationMatch{forbidden("spec.validation.openAPIV3Schema.properties[a].default")}, - }, - { - name: "setting defaults with enabled feature gate via v1", - old: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: "plural.group.com", - ResourceVersion: "42", - }, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: []apiextensions.CustomResourceDefinitionVersion{ - { - Name: "version", - Served: true, - Storage: true, - }, - }, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "a": { - Type: "number", - }, - }, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(false), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - resource: &apiextensions.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: "plural.group.com", - ResourceVersion: "42", - }, - Spec: apiextensions.CustomResourceDefinitionSpec{ - Group: "group.com", - Version: "version", - Versions: []apiextensions.CustomResourceDefinitionVersion{ - { - Name: "version", - Served: true, - Storage: true, - }, - }, - Scope: apiextensions.NamespaceScoped, - Names: apiextensions.CustomResourceDefinitionNames{ - Plural: "plural", - Singular: "singular", - Kind: "Plural", - ListKind: "PluralList", - }, - Validation: &apiextensions.CustomResourceValidation{ - OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ - Type: "object", - Properties: map[string]apiextensions.JSONSchemaProps{ - "a": { - Type: "number", - Default: jsonPtr(42.0), - }, - }, - }, - }, - PreserveUnknownFields: pointer.BoolPtr(false), - }, - Status: apiextensions.CustomResourceDefinitionStatus{ - StoredVersions: []string{"version"}, - }, - }, - requestGV: apiextensionsv1.SchemeGroupVersion, - errors: []validationMatch{}, + errors: []validationMatch{}, }, { name: "add default with enabled feature gate, structural schema, without pruning", @@ -6527,7 +6075,7 @@ func TestValidateCustomResourceDefinitionUpdate(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - errs := ValidateCustomResourceDefinitionUpdate(tc.resource, tc.old, tc.requestGV) + errs := ValidateCustomResourceDefinitionUpdate(tc.resource, tc.old) seenErrs := make([]bool, len(errs)) for _, expectedError := range tc.errors { diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/apiserver.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/apiserver.go index 8ef78d82f44..d08693bbfdf 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/apiserver.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/apiserver.go @@ -137,26 +137,8 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget) GenericAPIServer: genericServer, } - // used later to filter the served resource by those that have expired. - resourceExpirationEvaluator, err := genericapiserver.NewResourceExpirationEvaluator(*c.GenericConfig.Version) - if err != nil { - return nil, err - } - apiResourceConfig := c.GenericConfig.MergedResourceConfig apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apiextensions.GroupName, Scheme, metav1.ParameterCodec, Codecs) - if resourceExpirationEvaluator.ShouldServeForVersion(1, 22) && apiResourceConfig.VersionEnabled(v1beta1.SchemeGroupVersion) { - storage := map[string]rest.Storage{} - // customresourcedefinitions - customResourceDefinitionStorage, err := customresourcedefinition.NewREST(Scheme, c.GenericConfig.RESTOptionsGetter) - if err != nil { - return nil, err - } - storage["customresourcedefinitions"] = customResourceDefinitionStorage - storage["customresourcedefinitions/status"] = customresourcedefinition.NewStatusREST(Scheme, customResourceDefinitionStorage) - - apiGroupInfo.VersionedResourcesStorageMap[v1beta1.SchemeGroupVersion.Version] = storage - } if apiResourceConfig.VersionEnabled(v1.SchemeGroupVersion) { storage := map[string]rest.Storage{} // customresourcedefinitions diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go index 389c87b9e3d..708ef2d9b11 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go @@ -27,9 +27,7 @@ import ( "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" - genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/storage" "k8s.io/apiserver/pkg/storage/names" @@ -111,12 +109,7 @@ func (strategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) { // Validate validates a new CustomResourceDefinition. func (strategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { - var groupVersion schema.GroupVersion - if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found { - groupVersion = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} - } - - return validation.ValidateCustomResourceDefinition(obj.(*apiextensions.CustomResourceDefinition), groupVersion) + return validation.ValidateCustomResourceDefinition(obj.(*apiextensions.CustomResourceDefinition)) } // WarningsOnCreate returns warnings for the creation of the given object. @@ -139,12 +132,7 @@ func (strategy) Canonicalize(obj runtime.Object) { // ValidateUpdate is the default update validation for an end user updating status. func (strategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { - var groupVersion schema.GroupVersion - if requestInfo, found := genericapirequest.RequestInfoFrom(ctx); found { - groupVersion = schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} - } - - return validation.ValidateCustomResourceDefinitionUpdate(obj.(*apiextensions.CustomResourceDefinition), old.(*apiextensions.CustomResourceDefinition), groupVersion) + return validation.ValidateCustomResourceDefinitionUpdate(obj.(*apiextensions.CustomResourceDefinition), old.(*apiextensions.CustomResourceDefinition)) } // WarningsOnUpdate returns warnings for the given update. diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy_test.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy_test.go index 14323d32575..ecef7af8dca 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy_test.go @@ -23,7 +23,6 @@ import ( "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/utils/pointer" ) @@ -43,29 +42,19 @@ func TestValidateAPIApproval(t *testing.T) { tests := []struct { name string - version string group string annotationValue string oldAnnotationValue *string validateError func(t *testing.T, errors field.ErrorList) }{ - { - name: "ignore v1beta1", - version: "v1beta1", - group: "sigs.k8s.io", - annotationValue: "invalid", - validateError: okFn, - }, { name: "ignore non-k8s group", - version: "v1", group: "other.io", annotationValue: "invalid", validateError: okFn, }, { name: "invalid annotation create", - version: "v1", group: "sigs.k8s.io", annotationValue: "invalid", validateError: func(t *testing.T, errors field.ErrorList) { @@ -80,7 +69,6 @@ func TestValidateAPIApproval(t *testing.T) { }, { name: "invalid annotation update", - version: "v1", group: "sigs.k8s.io", annotationValue: "invalid", oldAnnotationValue: strPtr("invalid"), @@ -88,7 +76,6 @@ func TestValidateAPIApproval(t *testing.T) { }, { name: "invalid annotation to missing", - version: "v1", group: "sigs.k8s.io", annotationValue: "", oldAnnotationValue: strPtr("invalid"), @@ -104,7 +91,6 @@ func TestValidateAPIApproval(t *testing.T) { }, { name: "missing to invalid annotation", - version: "v1", group: "sigs.k8s.io", annotationValue: "invalid", oldAnnotationValue: strPtr(""), @@ -120,7 +106,6 @@ func TestValidateAPIApproval(t *testing.T) { }, { name: "missing annotation", - version: "v1", group: "sigs.k8s.io", annotationValue: "", validateError: func(t *testing.T, errors field.ErrorList) { @@ -135,7 +120,6 @@ func TestValidateAPIApproval(t *testing.T) { }, { name: "missing annotation update", - version: "v1", group: "sigs.k8s.io", annotationValue: "", oldAnnotationValue: strPtr(""), @@ -143,33 +127,16 @@ func TestValidateAPIApproval(t *testing.T) { }, { name: "url", - version: "v1", group: "sigs.k8s.io", annotationValue: "https://github.com/kubernetes/kubernetes/pull/79724", validateError: okFn, }, { name: "unapproved", - version: "v1", group: "sigs.k8s.io", annotationValue: "unapproved, other reason", validateError: okFn, }, - { - name: "next version validates", - version: "v2", - group: "sigs.k8s.io", - annotationValue: "invalid", - validateError: func(t *testing.T, errors field.ErrorList) { - t.Helper() - if len(errors) == 0 { - t.Fatal("expected errors, got none") - } - if e, a := `metadata.annotations[api-approved.kubernetes.io]: Invalid value: "invalid": protected groups must have approval annotation "api-approved.kubernetes.io" with either a URL or a reason starting with "unapproved", see https://github.com/kubernetes/enhancements/pull/1111`, errors.ToAggregate().Error(); e != a { - t.Fatal(errors) - } - }, - }, } for _, test := range tests { @@ -212,9 +179,9 @@ func TestValidateAPIApproval(t *testing.T) { var actual field.ErrorList if oldCRD == nil { - actual = validation.ValidateCustomResourceDefinition(crd, schema.GroupVersion{Group: "apiextensions.k8s.io", Version: test.version}) + actual = validation.ValidateCustomResourceDefinition(crd) } else { - actual = validation.ValidateCustomResourceDefinitionUpdate(crd, oldCRD, schema.GroupVersion{Group: "apiextensions.k8s.io", Version: test.version}) + actual = validation.ValidateCustomResourceDefinitionUpdate(crd, oldCRD) } test.validateError(t, actual) }) diff --git a/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/rest/storage_apiservice.go b/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/rest/storage_apiservice.go index fc3fd6b2f1a..4ae5205ca05 100644 --- a/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/rest/storage_apiservice.go +++ b/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/rest/storage_apiservice.go @@ -25,7 +25,6 @@ import ( "k8s.io/kube-aggregator/pkg/apis/apiregistration" v1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" - "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" aggregatorscheme "k8s.io/kube-aggregator/pkg/apiserver/scheme" apiservicestorage "k8s.io/kube-aggregator/pkg/registry/apiservice/etcd" ) @@ -34,14 +33,6 @@ import ( func NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter, shouldServeBeta bool) genericapiserver.APIGroupInfo { apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apiregistration.GroupName, aggregatorscheme.Scheme, metav1.ParameterCodec, aggregatorscheme.Codecs) - if shouldServeBeta && apiResourceConfigSource.VersionEnabled(v1beta1.SchemeGroupVersion) { - storage := map[string]rest.Storage{} - apiServiceREST := apiservicestorage.NewREST(aggregatorscheme.Scheme, restOptionsGetter) - storage["apiservices"] = apiServiceREST - storage["apiservices/status"] = apiservicestorage.NewStatusREST(aggregatorscheme.Scheme, apiServiceREST) - apiGroupInfo.VersionedResourcesStorageMap["v1beta1"] = storage - } - if apiResourceConfigSource.VersionEnabled(v1.SchemeGroupVersion) { storage := map[string]rest.Storage{} apiServiceREST := apiservicestorage.NewREST(aggregatorscheme.Scheme, restOptionsGetter) diff --git a/test/integration/etcd/data.go b/test/integration/etcd/data.go index 90b1e4bb733..e3a5293a4e5 100644 --- a/test/integration/etcd/data.go +++ b/test/integration/etcd/data.go @@ -166,14 +166,6 @@ func GetEtcdStorageDataForNamespace(namespace string) map[schema.GroupVersionRes }, // -- - // k8s.io/kubernetes/pkg/apis/certificates/v1beta1 - gvr("certificates.k8s.io", "v1beta1", "certificatesigningrequests"): { - Stub: `{"metadata": {"name": "csr1"}, "spec": {"request": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQnlqQ0NBVE1DQVFBd2dZa3hDekFKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFJRXdwRFlXeHBabTl5Ym1saApNUll3RkFZRFZRUUhFdzFOYjNWdWRHRnBiaUJXYVdWM01STXdFUVlEVlFRS0V3cEhiMjluYkdVZ1NXNWpNUjh3CkhRWURWUVFMRXhaSmJtWnZjbTFoZEdsdmJpQlVaV05vYm05c2IyZDVNUmN3RlFZRFZRUURFdzUzZDNjdVoyOXYKWjJ4bExtTnZiVENCbnpBTkJna3Foa2lHOXcwQkFRRUZBQU9CalFBd2dZa0NnWUVBcFp0WUpDSEo0VnBWWEhmVgpJbHN0UVRsTzRxQzAzaGpYK1prUHl2ZFlkMVE0K3FiQWVUd1htQ1VLWUhUaFZSZDVhWFNxbFB6eUlCd2llTVpyCldGbFJRZGRaMUl6WEFsVlJEV3dBbzYwS2VjcWVBWG5uVUsrNWZYb1RJL1VnV3NocmU4dEoreC9UTUhhUUtSL0oKY0lXUGhxYVFoc0p1elpidkFkR0E4MEJMeGRNQ0F3RUFBYUFBTUEwR0NTcUdTSWIzRFFFQkJRVUFBNEdCQUlobAo0UHZGcStlN2lwQVJnSTVaTStHWng2bXBDejQ0RFRvMEprd2ZSRGYrQnRyc2FDMHE2OGVUZjJYaFlPc3E0ZmtIClEwdUEwYVZvZzNmNWlKeENhM0hwNWd4YkpRNnpWNmtKMFRFc3VhYU9oRWtvOXNkcENvUE9uUkJtMmkvWFJEMkQKNmlOaDhmOHowU2hHc0ZxakRnRkh5RjNvK2xVeWorVUM2SDFRVzdibgotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0="}}`, - ExpectedEtcdPath: "/registry/certificatesigningrequests/csr1", - ExpectedGVK: gvkP("certificates.k8s.io", "v1", "CertificateSigningRequest"), - }, - // -- - // k8s.io/kubernetes/pkg/apis/certificates/v1 gvr("certificates.k8s.io", "v1", "certificatesigningrequests"): { Stub: `{"metadata": {"name": "csr2"}, "spec": {"signerName":"example.com/signer", "usages":["any"], "request": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQnlqQ0NBVE1DQVFBd2dZa3hDekFKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFJRXdwRFlXeHBabTl5Ym1saApNUll3RkFZRFZRUUhFdzFOYjNWdWRHRnBiaUJXYVdWM01STXdFUVlEVlFRS0V3cEhiMjluYkdVZ1NXNWpNUjh3CkhRWURWUVFMRXhaSmJtWnZjbTFoZEdsdmJpQlVaV05vYm05c2IyZDVNUmN3RlFZRFZRUURFdzUzZDNjdVoyOXYKWjJ4bExtTnZiVENCbnpBTkJna3Foa2lHOXcwQkFRRUZBQU9CalFBd2dZa0NnWUVBcFp0WUpDSEo0VnBWWEhmVgpJbHN0UVRsTzRxQzAzaGpYK1prUHl2ZFlkMVE0K3FiQWVUd1htQ1VLWUhUaFZSZDVhWFNxbFB6eUlCd2llTVpyCldGbFJRZGRaMUl6WEFsVlJEV3dBbzYwS2VjcWVBWG5uVUsrNWZYb1RJL1VnV3NocmU4dEoreC9UTUhhUUtSL0oKY0lXUGhxYVFoc0p1elpidkFkR0E4MEJMeGRNQ0F3RUFBYUFBTUEwR0NTcUdTSWIzRFFFQkJRVUFBNEdCQUlobAo0UHZGcStlN2lwQVJnSTVaTStHWng2bXBDejQ0RFRvMEprd2ZSRGYrQnRyc2FDMHE2OGVUZjJYaFlPc3E0ZmtIClEwdUEwYVZvZzNmNWlKeENhM0hwNWd4YkpRNnpWNmtKMFRFc3VhYU9oRWtvOXNkcENvUE9uUkJtMmkvWFJEMkQKNmlOaDhmOHowU2hHc0ZxakRnRkh5RjNvK2xVeWorVUM2SDFRVzdibgotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0="}}`, @@ -188,14 +180,6 @@ func GetEtcdStorageDataForNamespace(namespace string) map[schema.GroupVersionRes }, // -- - // k8s.io/kubernetes/pkg/apis/coordination/v1beta1 - gvr("coordination.k8s.io", "v1beta1", "leases"): { - Stub: `{"metadata": {"name": "leasev1beta1"}, "spec": {"holderIdentity": "holder", "leaseDurationSeconds": 5}}`, - ExpectedEtcdPath: "/registry/leases/" + namespace + "/leasev1beta1", - ExpectedGVK: gvkP("coordination.k8s.io", "v1", "Lease"), - }, - // -- - // k8s.io/kubernetes/pkg/apis/discovery/v1 gvr("discovery.k8s.io", "v1", "endpointslices"): { Stub: `{"metadata": {"name": "slicev1"}, "addressType": "IPv4", "protocol": "TCP", "ports": [], "endpoints": []}`, @@ -227,27 +211,6 @@ func GetEtcdStorageDataForNamespace(namespace string) map[schema.GroupVersionRes }, // -- - // k8s.io/kubernetes/pkg/apis/extensions/v1beta1 - gvr("extensions", "v1beta1", "ingresses"): { - Stub: `{"metadata": {"name": "ingress1"}, "spec": {"backend": {"serviceName": "service", "servicePort": 5000}}}`, - ExpectedEtcdPath: "/registry/ingress/" + namespace + "/ingress1", - ExpectedGVK: gvkP("networking.k8s.io", "v1", "Ingress"), - }, - // -- - - // k8s.io/kubernetes/pkg/apis/networking/v1beta1 - gvr("networking.k8s.io", "v1beta1", "ingresses"): { - Stub: `{"metadata": {"name": "ingress2"}, "spec": {"backend": {"serviceName": "service", "servicePort": 5000}}}`, - ExpectedEtcdPath: "/registry/ingress/" + namespace + "/ingress2", - ExpectedGVK: gvkP("networking.k8s.io", "v1", "Ingress"), - }, - gvr("networking.k8s.io", "v1beta1", "ingressclasses"): { - Stub: `{"metadata": {"name": "ingressclass2"}, "spec": {"controller": "example.com/controller"}}`, - ExpectedEtcdPath: "/registry/ingressclasses/ingressclass2", - ExpectedGVK: gvkP("networking.k8s.io", "v1", "IngressClass"), - }, - // -- - // k8s.io/kubernetes/pkg/apis/networking/v1 gvr("networking.k8s.io", "v1", "ingresses"): { Stub: `{"metadata": {"name": "ingress3"}, "spec": {"defaultBackend": {"service":{"name":"service", "port":{"number": 5000}}}}}`, @@ -282,14 +245,6 @@ func GetEtcdStorageDataForNamespace(namespace string) map[schema.GroupVersionRes }, // -- - // k8s.io/kubernetes/pkg/apis/storage/v1alpha1 - gvr("storage.k8s.io", "v1alpha1", "volumeattachments"): { - Stub: `{"metadata": {"name": "va1"}, "spec": {"attacher": "gce", "nodeName": "localhost", "source": {"persistentVolumeName": "pv1"}}}`, - ExpectedEtcdPath: "/registry/volumeattachments/va1", - ExpectedGVK: gvkP("storage.k8s.io", "v1", "VolumeAttachment"), - }, - // -- - // k8s.io/kubernetes/pkg/apis/storage/v1alpha1 gvr("storage.k8s.io", "v1alpha1", "csistoragecapacities"): { Stub: `{"metadata": {"name": "csc-12345-1"}, "storageClassName": "sc1"}`, @@ -328,14 +283,6 @@ func GetEtcdStorageDataForNamespace(namespace string) map[schema.GroupVersionRes }, // -- - // k8s.io/kubernetes/pkg/apis/storage/v1beta1 - gvr("storage.k8s.io", "v1beta1", "volumeattachments"): { - Stub: `{"metadata": {"name": "va2"}, "spec": {"attacher": "gce", "nodeName": "localhost", "source": {"persistentVolumeName": "pv2"}}}`, - ExpectedEtcdPath: "/registry/volumeattachments/va2", - ExpectedGVK: gvkP("storage.k8s.io", "v1", "VolumeAttachment"), - }, - // -- - // k8s.io/kubernetes/pkg/apis/storage/v1 gvr("storage.k8s.io", "v1", "volumeattachments"): { Stub: `{"metadata": {"name": "va3"}, "spec": {"attacher": "gce", "nodeName": "localhost", "source": {"persistentVolumeName": "pv3"}}}`, @@ -344,13 +291,6 @@ func GetEtcdStorageDataForNamespace(namespace string) map[schema.GroupVersionRes // -- // k8s.io/kubernetes/pkg/apis/storage/v1beta1 - gvr("storage.k8s.io", "v1beta1", "storageclasses"): { - Stub: `{"metadata": {"name": "sc1"}, "provisioner": "aws"}`, - ExpectedEtcdPath: "/registry/storageclasses/sc1", - ExpectedGVK: gvkP("storage.k8s.io", "v1", "StorageClass"), - }, - // -- - // k8s.io/kubernetes/pkg/apis/storage/v1beta1 gvr("storage.k8s.io", "v1beta1", "csistoragecapacities"): { Stub: `{"metadata": {"name": "csc-12345-2"}, "storageClassName": "sc1"}`, @@ -365,52 +305,6 @@ func GetEtcdStorageDataForNamespace(namespace string) map[schema.GroupVersionRes }, // -- - // k8s.io/kubernetes/pkg/apis/rbac/v1alpha1 - gvr("rbac.authorization.k8s.io", "v1alpha1", "roles"): { - Stub: `{"metadata": {"name": "role1"}, "rules": [{"apiGroups": ["v1"], "resources": ["events"], "verbs": ["watch"]}]}`, - ExpectedEtcdPath: "/registry/roles/" + namespace + "/role1", - ExpectedGVK: gvkP("rbac.authorization.k8s.io", "v1", "Role"), - }, - gvr("rbac.authorization.k8s.io", "v1alpha1", "clusterroles"): { - Stub: `{"metadata": {"name": "crole1"}, "rules": [{"nonResourceURLs": ["/version"], "verbs": ["get"]}]}`, - ExpectedEtcdPath: "/registry/clusterroles/crole1", - ExpectedGVK: gvkP("rbac.authorization.k8s.io", "v1", "ClusterRole"), - }, - gvr("rbac.authorization.k8s.io", "v1alpha1", "rolebindings"): { - Stub: `{"metadata": {"name": "roleb1"}, "roleRef": {"apiGroup": "rbac.authorization.k8s.io", "kind": "ClusterRole", "name": "somecr"}, "subjects": [{"apiVersion": "rbac.authorization.k8s.io/v1alpha1", "kind": "Group", "name": "system:authenticated"}]}`, - ExpectedEtcdPath: "/registry/rolebindings/" + namespace + "/roleb1", - ExpectedGVK: gvkP("rbac.authorization.k8s.io", "v1", "RoleBinding"), - }, - gvr("rbac.authorization.k8s.io", "v1alpha1", "clusterrolebindings"): { - Stub: `{"metadata": {"name": "croleb1"}, "roleRef": {"apiGroup": "rbac.authorization.k8s.io", "kind": "ClusterRole", "name": "somecr"}, "subjects": [{"apiVersion": "rbac.authorization.k8s.io/v1alpha1", "kind": "Group", "name": "system:authenticated"}]}`, - ExpectedEtcdPath: "/registry/clusterrolebindings/croleb1", - ExpectedGVK: gvkP("rbac.authorization.k8s.io", "v1", "ClusterRoleBinding"), - }, - // -- - - // k8s.io/kubernetes/pkg/apis/rbac/v1beta1 - gvr("rbac.authorization.k8s.io", "v1beta1", "roles"): { - Stub: `{"metadata": {"name": "role2"}, "rules": [{"apiGroups": ["v1"], "resources": ["events"], "verbs": ["watch"]}]}`, - ExpectedEtcdPath: "/registry/roles/" + namespace + "/role2", - ExpectedGVK: gvkP("rbac.authorization.k8s.io", "v1", "Role"), - }, - gvr("rbac.authorization.k8s.io", "v1beta1", "clusterroles"): { - Stub: `{"metadata": {"name": "crole2"}, "rules": [{"nonResourceURLs": ["/version"], "verbs": ["get"]}]}`, - ExpectedEtcdPath: "/registry/clusterroles/crole2", - ExpectedGVK: gvkP("rbac.authorization.k8s.io", "v1", "ClusterRole"), - }, - gvr("rbac.authorization.k8s.io", "v1beta1", "rolebindings"): { - Stub: `{"metadata": {"name": "roleb2"}, "roleRef": {"apiGroup": "rbac.authorization.k8s.io", "kind": "ClusterRole", "name": "somecr"}, "subjects": [{"apiVersion": "rbac.authorization.k8s.io/v1alpha1", "kind": "Group", "name": "system:authenticated"}]}`, - ExpectedEtcdPath: "/registry/rolebindings/" + namespace + "/roleb2", - ExpectedGVK: gvkP("rbac.authorization.k8s.io", "v1", "RoleBinding"), - }, - gvr("rbac.authorization.k8s.io", "v1beta1", "clusterrolebindings"): { - Stub: `{"metadata": {"name": "croleb2"}, "roleRef": {"apiGroup": "rbac.authorization.k8s.io", "kind": "ClusterRole", "name": "somecr"}, "subjects": [{"apiVersion": "rbac.authorization.k8s.io/v1alpha1", "kind": "Group", "name": "system:authenticated"}]}`, - ExpectedEtcdPath: "/registry/clusterrolebindings/croleb2", - ExpectedGVK: gvkP("rbac.authorization.k8s.io", "v1", "ClusterRoleBinding"), - }, - // -- - // k8s.io/kubernetes/pkg/apis/rbac/v1 gvr("rbac.authorization.k8s.io", "v1", "roles"): { Stub: `{"metadata": {"name": "role3"}, "rules": [{"apiGroups": ["v1"], "resources": ["events"], "verbs": ["watch"]}]}`, @@ -441,35 +335,6 @@ func GetEtcdStorageDataForNamespace(namespace string) map[schema.GroupVersionRes }, // -- - // k8s.io/kubernetes/pkg/apis/admissionregistration/v1beta1 - gvr("admissionregistration.k8s.io", "v1beta1", "validatingwebhookconfigurations"): { - Stub: `{"metadata":{"name":"hook1","creationTimestamp":null},"webhooks":[{"name":"externaladmissionhook.k8s.io","clientConfig":{"service":{"namespace":"ns","name":"n"},"caBundle":null},"rules":[{"operations":["CREATE"],"apiGroups":["group"],"apiVersions":["version"],"resources":["resource"]}],"failurePolicy":"Ignore"}]}`, - ExpectedEtcdPath: "/registry/validatingwebhookconfigurations/hook1", - ExpectedGVK: gvkP("admissionregistration.k8s.io", "v1", "ValidatingWebhookConfiguration"), - }, - gvr("admissionregistration.k8s.io", "v1beta1", "mutatingwebhookconfigurations"): { - Stub: `{"metadata":{"name":"hook1","creationTimestamp":null},"webhooks":[{"name":"externaladmissionhook.k8s.io","clientConfig":{"service":{"namespace":"ns","name":"n"},"caBundle":null},"rules":[{"operations":["CREATE"],"apiGroups":["group"],"apiVersions":["version"],"resources":["resource"]}],"failurePolicy":"Ignore"}]}`, - ExpectedEtcdPath: "/registry/mutatingwebhookconfigurations/hook1", - ExpectedGVK: gvkP("admissionregistration.k8s.io", "v1", "MutatingWebhookConfiguration"), - }, - // -- - - // k8s.io/kubernetes/pkg/apis/scheduling/v1alpha1 - gvr("scheduling.k8s.io", "v1alpha1", "priorityclasses"): { - Stub: `{"metadata":{"name":"pc1"},"Value":1000}`, - ExpectedEtcdPath: "/registry/priorityclasses/pc1", - ExpectedGVK: gvkP("scheduling.k8s.io", "v1", "PriorityClass"), - }, - // -- - - // k8s.io/kubernetes/pkg/apis/scheduling/v1beta1 - gvr("scheduling.k8s.io", "v1beta1", "priorityclasses"): { - Stub: `{"metadata":{"name":"pc2"},"Value":1000}`, - ExpectedEtcdPath: "/registry/priorityclasses/pc2", - ExpectedGVK: gvkP("scheduling.k8s.io", "v1", "PriorityClass"), - }, - // -- - // k8s.io/kubernetes/pkg/apis/scheduling/v1 gvr("scheduling.k8s.io", "v1", "priorityclasses"): { Stub: `{"metadata":{"name":"pc3"},"Value":1000}`, @@ -477,15 +342,6 @@ func GetEtcdStorageDataForNamespace(namespace string) map[schema.GroupVersionRes }, // -- - // k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1 - // depends on aggregator using the same ungrouped RESTOptionsGetter as the kube apiserver, not SimpleRestOptionsFactory in aggregator.go - gvr("apiregistration.k8s.io", "v1beta1", "apiservices"): { - Stub: `{"metadata": {"name": "as1.foo.com"}, "spec": {"group": "foo.com", "version": "as1", "groupPriorityMinimum":100, "versionPriority":10}}`, - ExpectedEtcdPath: "/registry/apiregistration.k8s.io/apiservices/as1.foo.com", - ExpectedGVK: gvkP("apiregistration.k8s.io", "v1", "APIService"), - }, - // -- - // k8s.io/kube-aggregator/pkg/apis/apiregistration/v1 // depends on aggregator using the same ungrouped RESTOptionsGetter as the kube apiserver, not SimpleRestOptionsFactory in aggregator.go gvr("apiregistration.k8s.io", "v1", "apiservices"): { @@ -503,11 +359,6 @@ func GetEtcdStorageDataForNamespace(namespace string) map[schema.GroupVersionRes ExpectedEtcdPath: "/registry/apiextensions.k8s.io/customresourcedefinitions/openshiftwebconsoleconfigs.webconsole2.operator.openshift.io", ExpectedGVK: gvkP("apiextensions.k8s.io", "v1beta1", "CustomResourceDefinition"), }, - // k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1 - gvr("apiextensions.k8s.io", "v1beta1", "customresourcedefinitions"): { - Stub: `{"metadata": {"name": "openshiftwebconsoleconfigs.webconsole.operator.openshift.io"},"spec": {"scope": "Cluster","group": "webconsole.operator.openshift.io","version": "v1alpha1","names": {"kind": "OpenShiftWebConsoleConfig","plural": "openshiftwebconsoleconfigs","singular": "openshiftwebconsoleconfig"}}}`, - ExpectedEtcdPath: "/registry/apiextensions.k8s.io/customresourcedefinitions/openshiftwebconsoleconfigs.webconsole.operator.openshift.io", - }, gvr("cr.bar.com", "v1", "foos"): { Stub: `{"kind": "Foo", "apiVersion": "cr.bar.com/v1", "metadata": {"name": "cr1foo"}, "color": "blue"}`, // requires TypeMeta due to CRD scheme's UnstructuredObjectTyper ExpectedEtcdPath: "/registry/cr.bar.com/foos/" + namespace + "/cr1foo", @@ -563,13 +414,6 @@ func GetEtcdStorageDataForNamespace(namespace string) map[schema.GroupVersionRes } // add csinodes - // k8s.io/kubernetes/pkg/apis/storage/v1beta1 - etcdStorageData[gvr("storage.k8s.io", "v1beta1", "csinodes")] = StorageData{ - Stub: `{"metadata": {"name": "csini1"}, "spec": {"drivers": [{"name": "test-driver", "nodeID": "localhost", "topologyKeys": ["company.com/zone1", "company.com/zone2"]}]}}`, - ExpectedEtcdPath: "/registry/csinodes/csini1", - ExpectedGVK: gvkP("storage.k8s.io", "v1", "CSINode"), - } - // k8s.io/kubernetes/pkg/apis/storage/v1 etcdStorageData[gvr("storage.k8s.io", "v1", "csinodes")] = StorageData{ Stub: `{"metadata": {"name": "csini2"}, "spec": {"drivers": [{"name": "test-driver", "nodeID": "localhost", "topologyKeys": ["company.com/zone1", "company.com/zone2"]}]}}`, @@ -577,13 +421,6 @@ func GetEtcdStorageDataForNamespace(namespace string) map[schema.GroupVersionRes } // add csidrivers - // k8s.io/kubernetes/pkg/apis/storage/v1beta1 - etcdStorageData[gvr("storage.k8s.io", "v1beta1", "csidrivers")] = StorageData{ - Stub: `{"metadata": {"name": "csid1"}, "spec": {"attachRequired": true, "podInfoOnMount": true}}`, - ExpectedEtcdPath: "/registry/csidrivers/csid1", - ExpectedGVK: gvkP("storage.k8s.io", "v1", "CSIDriver"), - } - // k8s.io/kubernetes/pkg/apis/storage/v1 etcdStorageData[gvr("storage.k8s.io", "v1", "csidrivers")] = StorageData{ Stub: `{"metadata": {"name": "csid2"}, "spec": {"attachRequired": true, "podInfoOnMount": true}}`,