From 71a136fc047aa7e170de6a9ad9139e072cdc65b8 Mon Sep 17 00:00:00 2001 From: Abu Kashem Date: Mon, 23 Sep 2024 12:22:53 -0400 Subject: [PATCH 01/14] api: add a new field to meta/v1 DeleteOptions add a new boolean field IgnoreStoreReadErrorWithClusterBreakingPotential to meta/v1 DeleteOptions --- .../apimachinery/pkg/apis/meta/v1/types.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go index 4cea1c1481430..f108a0e0b7675 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go @@ -560,6 +560,23 @@ type DeleteOptions struct { // +optional // +listType=atomic DryRun []string `json:"dryRun,omitempty" protobuf:"bytes,5,rep,name=dryRun"` + + // IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, + // will trigger an unsafe deletion of the resource in case the + // normal deletion flow fails with a corrupt object error. + // A resource is considered corrupt if it can not be retrieved from + // the underlying storage because of a) its data can not be transformed + // successfully, or b) it fails to decode into an object. + // NOTE: unsafe deletion ignores finalzer constraints, skips + // precondition checks, or any post deletion hooks and + // removes the object from the storage. + // WARNING: This will break the cluster if the resource has any + // dependencies. Use only if you REALLY know what you are doing. + // WARNING: Vendor(s) will most likely consider enablement of this + // option to be in violation of the support of their product. + // The default value is nil, and the user must opt in to enable it + // +optional + IgnoreStoreReadErrorWithClusterBreakingPotential *bool `json:"ignoreStoreReadErrorWithClusterBreakingPotential,omitempty" protobuf:"varint,6,opt,name=ignoreStoreReadErrorWithClusterBreakingPotential"` } const ( From 7b138af208f40a065eecd7faa8c83cc5b3d2518c Mon Sep 17 00:00:00 2001 From: Abu Kashem Date: Mon, 23 Sep 2024 13:29:15 -0400 Subject: [PATCH 02/14] api: run codegen run 'make update' to code gen for changes in meta/v1 DeleteOptions --- api/openapi-spec/swagger.json | 422 ++++++++++++++++++ api/openapi-spec/v3/api__v1_openapi.json | 265 +++++++++++ ...issionregistration.k8s.io__v1_openapi.json | 76 ++++ ...registration.k8s.io__v1alpha1_openapi.json | 40 ++ ...nregistration.k8s.io__v1beta1_openapi.json | 40 ++ ...pis__apiextensions.k8s.io__v1_openapi.json | 22 + ...s__apiregistration.k8s.io__v1_openapi.json | 22 + .../v3/apis__apps__v1_openapi.json | 94 ++++ .../v3/apis__autoscaling__v1_openapi.json | 22 + .../v3/apis__autoscaling__v2_openapi.json | 22 + .../v3/apis__batch__v1_openapi.json | 40 ++ ...apis__certificates.k8s.io__v1_openapi.json | 22 + ...certificates.k8s.io__v1alpha1_openapi.json | 22 + ...apis__coordination.k8s.io__v1_openapi.json | 22 + ...coordination.k8s.io__v1alpha1_openapi.json | 22 + .../apis__discovery.k8s.io__v1_openapi.json | 22 + .../v3/apis__events.k8s.io__v1_openapi.json | 22 + ...wcontrol.apiserver.k8s.io__v1_openapi.json | 40 ++ ...rol.apiserver.k8s.io__v1beta3_openapi.json | 40 ++ ...al.apiserver.k8s.io__v1alpha1_openapi.json | 22 + .../apis__networking.k8s.io__v1_openapi.json | 58 +++ ...s__networking.k8s.io__v1beta1_openapi.json | 40 ++ .../v3/apis__node.k8s.io__v1_openapi.json | 22 + .../v3/apis__policy__v1_openapi.json | 22 + ...rbac.authorization.k8s.io__v1_openapi.json | 76 ++++ ...is__resource.k8s.io__v1alpha3_openapi.json | 76 ++++ .../apis__scheduling.k8s.io__v1_openapi.json | 22 + .../v3/apis__storage.k8s.io__v1_openapi.json | 94 ++++ ...pis__storage.k8s.io__v1alpha1_openapi.json | 22 + ...apis__storage.k8s.io__v1beta1_openapi.json | 22 + ...agemigration.k8s.io__v1alpha1_openapi.json | 22 + pkg/generated/openapi/zz_generated.openapi.go | 7 + .../testdata/HEAD/core.v1.DeleteOptions.json | 3 +- .../testdata/HEAD/core.v1.DeleteOptions.pb | Bin 106 -> 108 bytes .../testdata/HEAD/core.v1.DeleteOptions.yaml | 1 + .../api/testdata/HEAD/policy.v1.Eviction.json | 3 +- .../api/testdata/HEAD/policy.v1.Eviction.pb | Bin 466 -> 468 bytes .../api/testdata/HEAD/policy.v1.Eviction.yaml | 1 + .../HEAD/policy.v1beta1.Eviction.json | 3 +- .../testdata/HEAD/policy.v1beta1.Eviction.pb | Bin 471 -> 473 bytes .../HEAD/policy.v1beta1.Eviction.yaml | 1 + .../generated/openapi/zz_generated.openapi.go | 7 + .../pkg/apis/meta/v1/generated.pb.go | 400 +++++++++-------- .../pkg/apis/meta/v1/generated.proto | 17 + .../meta/v1/types_swagger_doc_generated.go | 1 + .../apis/meta/v1/zz_generated.conversion.go | 7 + .../pkg/apis/meta/v1/zz_generated.deepcopy.go | 5 + .../applyconfigurations/internal/internal.go | 3 + .../meta/v1/deleteoptions.go | 21 +- .../apiserver/openapi/zz_generated.openapi.go | 7 + .../generated/openapi/zz_generated.openapi.go | 7 + .../generated/openapi/zz_generated.openapi.go | 7 + 52 files changed, 2086 insertions(+), 190 deletions(-) diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index ae6e85634b08c..522d2a5f384c4 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -17935,6 +17935,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -19339,6 +19343,13 @@ "type": "integer", "uniqueItems": true }, + "ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "type": "boolean", + "uniqueItems": true + }, "insecureSkipTLSVerifyBackend-gM00jVbe": { "description": "insecureSkipTLSVerifyBackend indicates that the apiserver should not confirm the validity of the serving certificate of the backend it is connecting to. This will make the HTTPS connection between the apiserver and the backend insecure. This means the apiserver cannot verify the log data it is receiving came from the real kubelet. If the kubelet is configured to verify the apiserver's TLS credentials, it does not mean the connection to the real kubelet is vulnerable to a man in the middle attack (e.g. an attacker could not intercept the actual log data coming from the real kubelet).", "in": "query", @@ -20334,6 +20345,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -20561,6 +20575,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -20819,6 +20836,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -21046,6 +21066,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -21304,6 +21327,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -21531,6 +21557,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -21789,6 +21818,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -22016,6 +22048,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -22274,6 +22309,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -22501,6 +22539,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -22949,6 +22990,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -23176,6 +23220,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -24856,6 +24903,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -25083,6 +25133,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -25341,6 +25394,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -25568,6 +25624,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -26206,6 +26265,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -26433,6 +26495,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -26881,6 +26946,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -27108,6 +27176,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -27366,6 +27437,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -27593,6 +27667,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -27943,6 +28020,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -28170,6 +28250,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -29113,6 +29196,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -29638,6 +29724,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -29862,6 +29951,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -30873,6 +30965,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -31097,6 +31192,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -35456,6 +35554,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -35680,6 +35781,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -35935,6 +36039,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -36159,6 +36266,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -36601,6 +36711,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -36825,6 +36938,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -37080,6 +37196,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -37304,6 +37423,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -38216,6 +38338,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -38440,6 +38565,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -38882,6 +39010,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -39106,6 +39237,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -39706,6 +39840,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -39930,6 +40067,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -40372,6 +40512,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -40596,6 +40739,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -41229,6 +41375,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -41453,6 +41602,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -42117,6 +42269,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -42341,6 +42496,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -43227,6 +43385,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -43454,6 +43615,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -43712,6 +43876,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -43939,6 +44106,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -44387,6 +44557,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -44614,6 +44787,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -45252,6 +45428,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -45479,6 +45658,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -46117,6 +46299,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -46344,6 +46529,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -49299,6 +49487,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -49526,6 +49717,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -50317,6 +50511,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -50544,6 +50741,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -51442,6 +51642,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -51669,6 +51872,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -52117,6 +52323,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -52344,6 +52553,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -53330,6 +53542,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -53554,6 +53769,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -54372,6 +54590,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -54596,6 +54817,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -55147,6 +55371,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -55374,6 +55601,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -55975,6 +56205,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -56202,6 +56435,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -56836,6 +57072,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -57063,6 +57302,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -57697,6 +57939,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -57924,6 +58169,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -58484,6 +58732,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -58708,6 +58959,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -59150,6 +59404,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -59374,6 +59631,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -60161,6 +60421,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -60385,6 +60648,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -60827,6 +61093,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -61051,6 +61320,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -61871,6 +62143,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -62095,6 +62370,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -62759,6 +63037,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -62983,6 +63264,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -63312,6 +63596,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -63539,6 +63826,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -63987,6 +64277,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -64214,6 +64507,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -65207,6 +65503,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -65431,6 +65730,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -65686,6 +65988,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -65910,6 +66215,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -66730,6 +67038,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -66954,6 +67265,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -67431,6 +67745,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -67658,6 +67975,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -68482,6 +68802,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -68706,6 +69029,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -68961,6 +69287,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -69185,6 +69514,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -69440,6 +69772,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -69667,6 +70002,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -69925,6 +70263,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -70152,6 +70493,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -71408,6 +71752,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -71632,6 +71979,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -71887,6 +72237,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -72114,6 +72467,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -72562,6 +72918,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -72789,6 +73148,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -73195,6 +73557,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -73419,6 +73784,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -74524,6 +74892,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -74748,6 +75119,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -75225,6 +75599,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -75449,6 +75826,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -75704,6 +76084,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -75928,6 +76311,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -76257,6 +76643,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -76484,6 +76873,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -76742,6 +77134,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -76966,6 +77361,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -77221,6 +77619,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -77445,6 +77846,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -78780,6 +79184,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -79004,6 +79411,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -79448,6 +79858,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -79672,6 +80085,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, @@ -80149,6 +80565,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/labelSelector-5Zw57w4C" }, @@ -80373,6 +80792,9 @@ { "$ref": "#/parameters/gracePeriodSeconds--K5HaBOS" }, + { + "$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-XxCm4o8X" + }, { "$ref": "#/parameters/orphanDependents-uRB25kX5" }, diff --git a/api/openapi-spec/v3/api__v1_openapi.json b/api/openapi-spec/v3/api__v1_openapi.json index 70b0336976ad1..307de8719a194 100644 --- a/api/openapi-spec/v3/api__v1_openapi.json +++ b/api/openapi-spec/v3/api__v1_openapi.json @@ -8800,6 +8800,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -11202,6 +11206,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -11621,6 +11634,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -12033,6 +12055,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -12452,6 +12483,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -12864,6 +12904,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -13283,6 +13332,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -13695,6 +13753,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -14114,6 +14181,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -14526,6 +14602,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -14945,6 +15030,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -15646,6 +15740,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -16065,6 +16168,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -18315,6 +18427,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -18734,6 +18855,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -19146,6 +19276,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -19565,6 +19704,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -20555,6 +20703,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -20974,6 +21131,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -21675,6 +21841,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -22094,6 +22269,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -22506,6 +22690,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -22925,6 +23118,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -23485,6 +23687,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -23904,6 +24115,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -25055,6 +25275,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -25854,6 +26083,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -26263,6 +26501,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -27543,6 +27790,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -27952,6 +28208,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__admissionregistration.k8s.io__v1_openapi.json b/api/openapi-spec/v3/apis__admissionregistration.k8s.io__v1_openapi.json index cda973376a4f2..3bd67cd3e8fe1 100644 --- a/api/openapi-spec/v3/apis__admissionregistration.k8s.io__v1_openapi.json +++ b/api/openapi-spec/v3/apis__admissionregistration.k8s.io__v1_openapi.json @@ -1280,6 +1280,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -2441,6 +2445,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -2850,6 +2863,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -3252,6 +3274,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -3661,6 +3692,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -4342,6 +4382,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -4751,6 +4800,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -5153,6 +5211,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -5562,6 +5629,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__admissionregistration.k8s.io__v1alpha1_openapi.json b/api/openapi-spec/v3/apis__admissionregistration.k8s.io__v1alpha1_openapi.json index 9cbee0c85e7bf..6938ca9d3a190 100644 --- a/api/openapi-spec/v3/apis__admissionregistration.k8s.io__v1alpha1_openapi.json +++ b/api/openapi-spec/v3/apis__admissionregistration.k8s.io__v1alpha1_openapi.json @@ -792,6 +792,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1953,6 +1957,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -2362,6 +2375,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -3043,6 +3065,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -3452,6 +3483,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__admissionregistration.k8s.io__v1beta1_openapi.json b/api/openapi-spec/v3/apis__admissionregistration.k8s.io__v1beta1_openapi.json index 92abca2031de2..007dceae187fb 100644 --- a/api/openapi-spec/v3/apis__admissionregistration.k8s.io__v1beta1_openapi.json +++ b/api/openapi-spec/v3/apis__admissionregistration.k8s.io__v1beta1_openapi.json @@ -794,6 +794,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1955,6 +1959,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -2364,6 +2377,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -3045,6 +3067,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -3454,6 +3485,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__apiextensions.k8s.io__v1_openapi.json b/api/openapi-spec/v3/apis__apiextensions.k8s.io__v1_openapi.json index e32d3d51bca05..dde917a79f231 100644 --- a/api/openapi-spec/v3/apis__apiextensions.k8s.io__v1_openapi.json +++ b/api/openapi-spec/v3/apis__apiextensions.k8s.io__v1_openapi.json @@ -1003,6 +1003,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -2107,6 +2111,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -2516,6 +2529,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__apiregistration.k8s.io__v1_openapi.json b/api/openapi-spec/v3/apis__apiregistration.k8s.io__v1_openapi.json index 5e2b02f572e85..76456f5ea6cfd 100644 --- a/api/openapi-spec/v3/apis__apiregistration.k8s.io__v1_openapi.json +++ b/api/openapi-spec/v3/apis__apiregistration.k8s.io__v1_openapi.json @@ -136,6 +136,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1460,6 +1464,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -1869,6 +1882,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__apps__v1_openapi.json b/api/openapi-spec/v3/apis__apps__v1_openapi.json index 6bc3da14edbcc..bee2f4cb95aaa 100644 --- a/api/openapi-spec/v3/apis__apps__v1_openapi.json +++ b/api/openapi-spec/v3/apis__apps__v1_openapi.json @@ -5500,6 +5500,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -7126,6 +7130,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -7545,6 +7558,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -7957,6 +7979,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -8376,6 +8407,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -9077,6 +9117,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -9496,6 +9545,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -10486,6 +10544,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -10905,6 +10972,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -11895,6 +11971,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -12314,6 +12399,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__autoscaling__v1_openapi.json b/api/openapi-spec/v3/apis__autoscaling__v1_openapi.json index 69f16435ada32..36ec7b3484c18 100644 --- a/api/openapi-spec/v3/apis__autoscaling__v1_openapi.json +++ b/api/openapi-spec/v3/apis__autoscaling__v1_openapi.json @@ -329,6 +329,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1584,6 +1588,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -2003,6 +2016,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__autoscaling__v2_openapi.json b/api/openapi-spec/v3/apis__autoscaling__v2_openapi.json index d23709a09f1aa..3d1db33d12530 100644 --- a/api/openapi-spec/v3/apis__autoscaling__v2_openapi.json +++ b/api/openapi-spec/v3/apis__autoscaling__v2_openapi.json @@ -981,6 +981,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -2293,6 +2297,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -2712,6 +2725,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__batch__v1_openapi.json b/api/openapi-spec/v3/apis__batch__v1_openapi.json index a37d481afc7e5..1649f754fe644 100644 --- a/api/openapi-spec/v3/apis__batch__v1_openapi.json +++ b/api/openapi-spec/v3/apis__batch__v1_openapi.json @@ -4704,6 +4704,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -6179,6 +6183,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -6598,6 +6611,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -7299,6 +7321,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -7718,6 +7749,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__certificates.k8s.io__v1_openapi.json b/api/openapi-spec/v3/apis__certificates.k8s.io__v1_openapi.json index 04018d3bb768a..96bff064bb60e 100644 --- a/api/openapi-spec/v3/apis__certificates.k8s.io__v1_openapi.json +++ b/api/openapi-spec/v3/apis__certificates.k8s.io__v1_openapi.json @@ -365,6 +365,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1469,6 +1473,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -1878,6 +1891,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__certificates.k8s.io__v1alpha1_openapi.json b/api/openapi-spec/v3/apis__certificates.k8s.io__v1alpha1_openapi.json index 8fa095e06fc23..117602b5cc261 100644 --- a/api/openapi-spec/v3/apis__certificates.k8s.io__v1alpha1_openapi.json +++ b/api/openapi-spec/v3/apis__certificates.k8s.io__v1alpha1_openapi.json @@ -241,6 +241,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1345,6 +1349,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -1754,6 +1767,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__coordination.k8s.io__v1_openapi.json b/api/openapi-spec/v3/apis__coordination.k8s.io__v1_openapi.json index 3c78fd7bcab59..4a839adde1b45 100644 --- a/api/openapi-spec/v3/apis__coordination.k8s.io__v1_openapi.json +++ b/api/openapi-spec/v3/apis__coordination.k8s.io__v1_openapi.json @@ -264,6 +264,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1524,6 +1528,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -1943,6 +1956,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__coordination.k8s.io__v1alpha1_openapi.json b/api/openapi-spec/v3/apis__coordination.k8s.io__v1alpha1_openapi.json index b9f161dcfd969..32a287ec54488 100644 --- a/api/openapi-spec/v3/apis__coordination.k8s.io__v1alpha1_openapi.json +++ b/api/openapi-spec/v3/apis__coordination.k8s.io__v1alpha1_openapi.json @@ -268,6 +268,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1528,6 +1532,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -1947,6 +1960,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__discovery.k8s.io__v1_openapi.json b/api/openapi-spec/v3/apis__discovery.k8s.io__v1_openapi.json index 83f8def3438c4..de6a138700145 100644 --- a/api/openapi-spec/v3/apis__discovery.k8s.io__v1_openapi.json +++ b/api/openapi-spec/v3/apis__discovery.k8s.io__v1_openapi.json @@ -419,6 +419,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1674,6 +1678,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -2093,6 +2106,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__events.k8s.io__v1_openapi.json b/api/openapi-spec/v3/apis__events.k8s.io__v1_openapi.json index 11699fc44d3b5..3eb172b657684 100644 --- a/api/openapi-spec/v3/apis__events.k8s.io__v1_openapi.json +++ b/api/openapi-spec/v3/apis__events.k8s.io__v1_openapi.json @@ -374,6 +374,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1634,6 +1638,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -2053,6 +2066,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__flowcontrol.apiserver.k8s.io__v1_openapi.json b/api/openapi-spec/v3/apis__flowcontrol.apiserver.k8s.io__v1_openapi.json index 592fbea366d59..4be95cd620c25 100644 --- a/api/openapi-spec/v3/apis__flowcontrol.apiserver.k8s.io__v1_openapi.json +++ b/api/openapi-spec/v3/apis__flowcontrol.apiserver.k8s.io__v1_openapi.json @@ -865,6 +865,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1969,6 +1973,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -2378,6 +2391,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -3059,6 +3081,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -3468,6 +3499,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__flowcontrol.apiserver.k8s.io__v1beta3_openapi.json b/api/openapi-spec/v3/apis__flowcontrol.apiserver.k8s.io__v1beta3_openapi.json index 0d8d99ce65d7d..3622c794d4fa3 100644 --- a/api/openapi-spec/v3/apis__flowcontrol.apiserver.k8s.io__v1beta3_openapi.json +++ b/api/openapi-spec/v3/apis__flowcontrol.apiserver.k8s.io__v1beta3_openapi.json @@ -866,6 +866,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1970,6 +1974,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -2379,6 +2392,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -3060,6 +3082,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -3469,6 +3500,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__internal.apiserver.k8s.io__v1alpha1_openapi.json b/api/openapi-spec/v3/apis__internal.apiserver.k8s.io__v1alpha1_openapi.json index 3160b90d681e5..a22e445e9e902 100644 --- a/api/openapi-spec/v3/apis__internal.apiserver.k8s.io__v1alpha1_openapi.json +++ b/api/openapi-spec/v3/apis__internal.apiserver.k8s.io__v1alpha1_openapi.json @@ -355,6 +355,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1459,6 +1463,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -1868,6 +1881,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__networking.k8s.io__v1_openapi.json b/api/openapi-spec/v3/apis__networking.k8s.io__v1_openapi.json index a0dfccd2050b6..52f30330f2c45 100644 --- a/api/openapi-spec/v3/apis__networking.k8s.io__v1_openapi.json +++ b/api/openapi-spec/v3/apis__networking.k8s.io__v1_openapi.json @@ -937,6 +937,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -2110,6 +2114,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -2519,6 +2532,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -3072,6 +3094,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -3491,6 +3522,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -4192,6 +4232,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -4611,6 +4660,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__networking.k8s.io__v1beta1_openapi.json b/api/openapi-spec/v3/apis__networking.k8s.io__v1beta1_openapi.json index f0704ad98283f..3a3555c2fdb08 100644 --- a/api/openapi-spec/v3/apis__networking.k8s.io__v1beta1_openapi.json +++ b/api/openapi-spec/v3/apis__networking.k8s.io__v1beta1_openapi.json @@ -441,6 +441,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1545,6 +1549,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -1954,6 +1967,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -2356,6 +2378,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -2765,6 +2796,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__node.k8s.io__v1_openapi.json b/api/openapi-spec/v3/apis__node.k8s.io__v1_openapi.json index fe41a7b56c1ce..06b4bd1e66a86 100644 --- a/api/openapi-spec/v3/apis__node.k8s.io__v1_openapi.json +++ b/api/openapi-spec/v3/apis__node.k8s.io__v1_openapi.json @@ -314,6 +314,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1418,6 +1422,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -1827,6 +1840,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__policy__v1_openapi.json b/api/openapi-spec/v3/apis__policy__v1_openapi.json index 335df48c613b7..94c443d576f59 100644 --- a/api/openapi-spec/v3/apis__policy__v1_openapi.json +++ b/api/openapi-spec/v3/apis__policy__v1_openapi.json @@ -376,6 +376,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1549,6 +1553,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -1968,6 +1981,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__rbac.authorization.k8s.io__v1_openapi.json b/api/openapi-spec/v3/apis__rbac.authorization.k8s.io__v1_openapi.json index 8a5428b82a997..63ecdb02adff0 100644 --- a/api/openapi-spec/v3/apis__rbac.authorization.k8s.io__v1_openapi.json +++ b/api/openapi-spec/v3/apis__rbac.authorization.k8s.io__v1_openapi.json @@ -649,6 +649,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1810,6 +1814,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -2219,6 +2232,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -2621,6 +2643,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -3030,6 +3061,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -3432,6 +3472,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -3851,6 +3900,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -4263,6 +4321,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -4682,6 +4749,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha3_openapi.json b/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha3_openapi.json index c107e1d1f2f2e..6c546fa756169 100644 --- a/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha3_openapi.json +++ b/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha3_openapi.json @@ -1193,6 +1193,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -2297,6 +2301,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -2706,6 +2719,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -3108,6 +3130,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -3527,6 +3558,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -4228,6 +4268,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -4647,6 +4696,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -5361,6 +5419,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -5770,6 +5837,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__scheduling.k8s.io__v1_openapi.json b/api/openapi-spec/v3/apis__scheduling.k8s.io__v1_openapi.json index b7f5bbfc93f0b..608c5e4ac1a3a 100644 --- a/api/openapi-spec/v3/apis__scheduling.k8s.io__v1_openapi.json +++ b/api/openapi-spec/v3/apis__scheduling.k8s.io__v1_openapi.json @@ -232,6 +232,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1336,6 +1340,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -1745,6 +1758,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__storage.k8s.io__v1_openapi.json b/api/openapi-spec/v3/apis__storage.k8s.io__v1_openapi.json index 79307196936ec..30d76193f10ad 100644 --- a/api/openapi-spec/v3/apis__storage.k8s.io__v1_openapi.json +++ b/api/openapi-spec/v3/apis__storage.k8s.io__v1_openapi.json @@ -2094,6 +2094,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -3255,6 +3259,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -3664,6 +3677,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -4066,6 +4088,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -4475,6 +4506,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -5028,6 +5068,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -5447,6 +5496,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -5859,6 +5917,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -6268,6 +6335,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", @@ -6670,6 +6746,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -7079,6 +7164,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__storage.k8s.io__v1alpha1_openapi.json b/api/openapi-spec/v3/apis__storage.k8s.io__v1alpha1_openapi.json index 22a86a5045a4c..696a49896a89d 100644 --- a/api/openapi-spec/v3/apis__storage.k8s.io__v1alpha1_openapi.json +++ b/api/openapi-spec/v3/apis__storage.k8s.io__v1alpha1_openapi.json @@ -227,6 +227,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1331,6 +1335,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -1740,6 +1753,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__storage.k8s.io__v1beta1_openapi.json b/api/openapi-spec/v3/apis__storage.k8s.io__v1beta1_openapi.json index 1fa0f1a463326..99b70376c8b11 100644 --- a/api/openapi-spec/v3/apis__storage.k8s.io__v1beta1_openapi.json +++ b/api/openapi-spec/v3/apis__storage.k8s.io__v1beta1_openapi.json @@ -227,6 +227,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1331,6 +1335,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -1740,6 +1753,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/api/openapi-spec/v3/apis__storagemigration.k8s.io__v1alpha1_openapi.json b/api/openapi-spec/v3/apis__storagemigration.k8s.io__v1alpha1_openapi.json index 5da9ff7598234..194c07a9b72a0 100644 --- a/api/openapi-spec/v3/apis__storagemigration.k8s.io__v1alpha1_openapi.json +++ b/api/openapi-spec/v3/apis__storagemigration.k8s.io__v1alpha1_openapi.json @@ -339,6 +339,10 @@ "format": "int64", "type": "integer" }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "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" @@ -1443,6 +1447,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, { "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", "in": "query", @@ -1852,6 +1865,15 @@ "uniqueItems": true } }, + { + "description": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + "in": "query", + "name": "ignoreStoreReadErrorWithClusterBreakingPotential", + "schema": { + "type": "boolean", + "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", diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index d2109d378dbe2..8a302df7ea9df 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -53984,6 +53984,13 @@ func schema_pkg_apis_meta_v1_DeleteOptions(ref common.ReferenceCallback) common. }, }, }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + SchemaProps: spec.SchemaProps{ + Description: "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + Type: []string{"boolean"}, + Format: "", + }, + }, }, }, }, diff --git a/staging/src/k8s.io/api/testdata/HEAD/core.v1.DeleteOptions.json b/staging/src/k8s.io/api/testdata/HEAD/core.v1.DeleteOptions.json index 2e581c55fffc8..efe609bb3f898 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/core.v1.DeleteOptions.json +++ b/staging/src/k8s.io/api/testdata/HEAD/core.v1.DeleteOptions.json @@ -10,5 +10,6 @@ "propagationPolicy": "propagationPolicyValue", "dryRun": [ "dryRunValue" - ] + ], + "ignoreStoreReadErrorWithClusterBreakingPotential": true } \ No newline at end of file diff --git a/staging/src/k8s.io/api/testdata/HEAD/core.v1.DeleteOptions.pb b/staging/src/k8s.io/api/testdata/HEAD/core.v1.DeleteOptions.pb index 73272f6ddbe074b3945d8e0f7edb5e2a94ba2f3d..833a9b976a1e8c066e88e8b020d6dd82745dac71 100644 GIT binary patch delta 16 Xcmd1GnIOgJJ5k!3&45vgL5TqXB!L4t delta 14 Vcmd1FnjppKJyF`5MT$X*0RSDU0|Wp7 diff --git a/staging/src/k8s.io/api/testdata/HEAD/core.v1.DeleteOptions.yaml b/staging/src/k8s.io/api/testdata/HEAD/core.v1.DeleteOptions.yaml index 1f7c2652a1060..3c15f8e6bff0d 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/core.v1.DeleteOptions.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/core.v1.DeleteOptions.yaml @@ -2,6 +2,7 @@ apiVersion: v1 dryRun: - dryRunValue gracePeriodSeconds: 1 +ignoreStoreReadErrorWithClusterBreakingPotential: true kind: DeleteOptions orphanDependents: true preconditions: diff --git a/staging/src/k8s.io/api/testdata/HEAD/policy.v1.Eviction.json b/staging/src/k8s.io/api/testdata/HEAD/policy.v1.Eviction.json index e62982589d4f7..5037089fad439 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/policy.v1.Eviction.json +++ b/staging/src/k8s.io/api/testdata/HEAD/policy.v1.Eviction.json @@ -53,6 +53,7 @@ "propagationPolicy": "propagationPolicyValue", "dryRun": [ "dryRunValue" - ] + ], + "ignoreStoreReadErrorWithClusterBreakingPotential": true } } \ No newline at end of file diff --git a/staging/src/k8s.io/api/testdata/HEAD/policy.v1.Eviction.pb b/staging/src/k8s.io/api/testdata/HEAD/policy.v1.Eviction.pb index bc507093e494b88a35f2f645b6c73fc7892967cc..767c0a5761a0e1b19de22838a76ed26be863b207 100644 GIT binary patch delta 25 gcmcb_e1&;}4CAJavZ;)WzLT37z1a*Hr5KbL0BObsV*mgE delta 23 ecmcb@e2IC24C984vZ;)W-jkady;-Cflo$Y9dj>23 diff --git a/staging/src/k8s.io/api/testdata/HEAD/policy.v1.Eviction.yaml b/staging/src/k8s.io/api/testdata/HEAD/policy.v1.Eviction.yaml index ac359dbed12f5..243516131249b 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/policy.v1.Eviction.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/policy.v1.Eviction.yaml @@ -3,6 +3,7 @@ deleteOptions: dryRun: - dryRunValue gracePeriodSeconds: 1 + ignoreStoreReadErrorWithClusterBreakingPotential: true orphanDependents: true preconditions: resourceVersion: resourceVersionValue diff --git a/staging/src/k8s.io/api/testdata/HEAD/policy.v1beta1.Eviction.json b/staging/src/k8s.io/api/testdata/HEAD/policy.v1beta1.Eviction.json index 6abf803d6b260..0e6e890407e7d 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/policy.v1beta1.Eviction.json +++ b/staging/src/k8s.io/api/testdata/HEAD/policy.v1beta1.Eviction.json @@ -53,6 +53,7 @@ "propagationPolicy": "propagationPolicyValue", "dryRun": [ "dryRunValue" - ] + ], + "ignoreStoreReadErrorWithClusterBreakingPotential": true } } \ No newline at end of file diff --git a/staging/src/k8s.io/api/testdata/HEAD/policy.v1beta1.Eviction.pb b/staging/src/k8s.io/api/testdata/HEAD/policy.v1beta1.Eviction.pb index df6e8fc884e1911cadc45d87c7665a5f4dd5dabc..c5399ef982f16ed43fbad5826aaf6b9e21d4a5e4 100644 GIT binary patch delta 25 gcmcc4e3N;CBIBlwN~w&DzLPr`z1a*Hr5KbL0Bf8Ed;kCd delta 23 ecmcb~e4TlMBIAaQN~w&D-jh2Ry;-Cflo$YB9|lDL diff --git a/staging/src/k8s.io/api/testdata/HEAD/policy.v1beta1.Eviction.yaml b/staging/src/k8s.io/api/testdata/HEAD/policy.v1beta1.Eviction.yaml index 2464b402dc871..d48b01a4d779e 100644 --- a/staging/src/k8s.io/api/testdata/HEAD/policy.v1beta1.Eviction.yaml +++ b/staging/src/k8s.io/api/testdata/HEAD/policy.v1beta1.Eviction.yaml @@ -3,6 +3,7 @@ deleteOptions: dryRun: - dryRunValue gracePeriodSeconds: 1 + ignoreStoreReadErrorWithClusterBreakingPotential: true orphanDependents: true preconditions: resourceVersion: resourceVersionValue diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/generated/openapi/zz_generated.openapi.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/generated/openapi/zz_generated.openapi.go index 1817de7070258..50b2339983012 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/generated/openapi/zz_generated.openapi.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/generated/openapi/zz_generated.openapi.go @@ -4705,6 +4705,13 @@ func schema_pkg_apis_meta_v1_DeleteOptions(ref common.ReferenceCallback) common. }, }, }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + SchemaProps: spec.SchemaProps{ + Description: "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + Type: []string{"boolean"}, + Format: "", + }, + }, }, }, }, diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go index 229ea2c2c2076..9ee6c05918537 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go @@ -1355,187 +1355,190 @@ func init() { } var fileDescriptor_a8431b6e0aeeb761 = []byte{ - // 2873 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x1a, 0x5d, 0x6f, 0x23, 0x57, - 0x35, 0x63, 0xc7, 0x89, 0x7d, 0x6c, 0xe7, 0xe3, 0x6e, 0x16, 0xbc, 0x41, 0xc4, 0xe9, 0xb4, 0xaa, - 0xb6, 0xd0, 0x3a, 0xdd, 0xa5, 0x54, 0xdb, 0x2d, 0x2d, 0xc4, 0xf1, 0x66, 0x9b, 0x76, 0xd3, 0x44, - 0x37, 0xbb, 0x0b, 0x94, 0x0a, 0x75, 0xe2, 0xb9, 0x71, 0x86, 0x8c, 0x67, 0xdc, 0x7b, 0xc7, 0x49, - 0x0d, 0x0f, 0xf4, 0x01, 0x04, 0x48, 0xa8, 0x2a, 0x6f, 0x3c, 0xa1, 0x56, 0xf0, 0x03, 0x10, 0x4f, - 0xbc, 0x83, 0x44, 0x1f, 0x8b, 0x78, 0xa9, 0x04, 0xb2, 0xba, 0xe1, 0x81, 0x47, 0xc4, 0x6b, 0x84, - 0x04, 0xba, 0x1f, 0x33, 0x73, 0xc7, 0x1f, 0x9b, 0xf1, 0xee, 0x52, 0xf1, 0xe6, 0x39, 0xdf, 0xf7, - 0xde, 0x73, 0xce, 0x3d, 0xe7, 0x5c, 0xc3, 0x73, 0x47, 0xd7, 0x58, 0xcd, 0xf1, 0xd7, 0xac, 0x8e, - 0xd3, 0xb6, 0x9a, 0x87, 0x8e, 0x47, 0x68, 0x6f, 0xad, 0x73, 0xd4, 0xe2, 0x00, 0xb6, 0xd6, 0x26, - 0x81, 0xb5, 0x76, 0x7c, 0x65, 0xad, 0x45, 0x3c, 0x42, 0xad, 0x80, 0xd8, 0xb5, 0x0e, 0xf5, 0x03, - 0x1f, 0x3d, 0x21, 0xb9, 0x6a, 0x3a, 0x57, 0xad, 0x73, 0xd4, 0xe2, 0x00, 0x56, 0xe3, 0x5c, 0xb5, - 0xe3, 0x2b, 0xcb, 0xcf, 0xb4, 0x9c, 0xe0, 0xb0, 0xbb, 0x5f, 0x6b, 0xfa, 0xed, 0xb5, 0x96, 0xdf, - 0xf2, 0xd7, 0x04, 0xf3, 0x7e, 0xf7, 0x40, 0x7c, 0x89, 0x0f, 0xf1, 0x4b, 0x0a, 0x5d, 0x5e, 0x1b, - 0x67, 0x0a, 0xed, 0x7a, 0x81, 0xd3, 0x26, 0x83, 0x56, 0x2c, 0x3f, 0x7f, 0x1e, 0x03, 0x6b, 0x1e, - 0x92, 0xb6, 0x35, 0xc8, 0x67, 0xfe, 0x29, 0x0b, 0xf9, 0xf5, 0xdd, 0xad, 0x9b, 0xd4, 0xef, 0x76, - 0xd0, 0x2a, 0x4c, 0x7b, 0x56, 0x9b, 0x54, 0x8c, 0x55, 0xe3, 0x72, 0xa1, 0x5e, 0xfa, 0xa8, 0x5f, - 0x9d, 0x3a, 0xed, 0x57, 0xa7, 0x5f, 0xb7, 0xda, 0x04, 0x0b, 0x0c, 0x72, 0x21, 0x7f, 0x4c, 0x28, - 0x73, 0x7c, 0x8f, 0x55, 0x32, 0xab, 0xd9, 0xcb, 0xc5, 0xab, 0x2f, 0xd7, 0xd2, 0xac, 0xbf, 0x26, - 0x14, 0xdc, 0x95, 0xac, 0x9b, 0x3e, 0x6d, 0x38, 0xac, 0xe9, 0x1f, 0x13, 0xda, 0xab, 0x2f, 0x28, - 0x2d, 0x79, 0x85, 0x64, 0x38, 0xd2, 0x80, 0x7e, 0x64, 0xc0, 0x42, 0x87, 0x92, 0x03, 0x42, 0x29, - 0xb1, 0x15, 0xbe, 0x92, 0x5d, 0x35, 0x1e, 0x81, 0xda, 0x8a, 0x52, 0xbb, 0xb0, 0x3b, 0x20, 0x1f, - 0x0f, 0x69, 0x44, 0xbf, 0x36, 0x60, 0x99, 0x11, 0x7a, 0x4c, 0xe8, 0xba, 0x6d, 0x53, 0xc2, 0x58, - 0xbd, 0xb7, 0xe1, 0x3a, 0xc4, 0x0b, 0x36, 0xb6, 0x1a, 0x98, 0x55, 0xa6, 0xc5, 0x3e, 0x7c, 0x3d, - 0x9d, 0x41, 0x7b, 0xe3, 0xe4, 0xd4, 0x4d, 0x65, 0xd1, 0xf2, 0x58, 0x12, 0x86, 0xef, 0x63, 0x86, - 0x79, 0x00, 0xa5, 0xf0, 0x20, 0x6f, 0x39, 0x2c, 0x40, 0x77, 0x61, 0xa6, 0xc5, 0x3f, 0x58, 0xc5, - 0x10, 0x06, 0xd6, 0xd2, 0x19, 0x18, 0xca, 0xa8, 0xcf, 0x29, 0x7b, 0x66, 0xc4, 0x27, 0xc3, 0x4a, - 0x9a, 0xf9, 0xb3, 0x69, 0x28, 0xae, 0xef, 0x6e, 0x61, 0xc2, 0xfc, 0x2e, 0x6d, 0x92, 0x14, 0x4e, - 0x73, 0x0d, 0x4a, 0xcc, 0xf1, 0x5a, 0x5d, 0xd7, 0xa2, 0x1c, 0x5a, 0x99, 0x11, 0x94, 0x4b, 0x8a, - 0xb2, 0xb4, 0xa7, 0xe1, 0x70, 0x82, 0x12, 0x5d, 0x05, 0xe0, 0x12, 0x58, 0xc7, 0x6a, 0x12, 0xbb, - 0x92, 0x59, 0x35, 0x2e, 0xe7, 0xeb, 0x48, 0xf1, 0xc1, 0xeb, 0x11, 0x06, 0x6b, 0x54, 0xe8, 0x71, - 0xc8, 0x09, 0x4b, 0x2b, 0x79, 0xa1, 0xa6, 0xac, 0xc8, 0x73, 0x62, 0x19, 0x58, 0xe2, 0xd0, 0x53, - 0x30, 0xab, 0xbc, 0xac, 0x52, 0x10, 0x64, 0xf3, 0x8a, 0x6c, 0x36, 0x74, 0x83, 0x10, 0xcf, 0xd7, - 0x77, 0xe4, 0x78, 0xb6, 0xf0, 0x3b, 0x6d, 0x7d, 0xaf, 0x39, 0x9e, 0x8d, 0x05, 0x06, 0xdd, 0x82, - 0xdc, 0x31, 0xa1, 0xfb, 0xdc, 0x13, 0xb8, 0x6b, 0x7e, 0x39, 0xdd, 0x46, 0xdf, 0xe5, 0x2c, 0xf5, - 0x02, 0x37, 0x4d, 0xfc, 0xc4, 0x52, 0x08, 0xaa, 0x01, 0xb0, 0x43, 0x9f, 0x06, 0x62, 0x79, 0x95, - 0xdc, 0x6a, 0xf6, 0x72, 0xa1, 0x3e, 0xc7, 0xd7, 0xbb, 0x17, 0x41, 0xb1, 0x46, 0xc1, 0xe9, 0x9b, - 0x56, 0x40, 0x5a, 0x3e, 0x75, 0x08, 0xab, 0xcc, 0xc6, 0xf4, 0x1b, 0x11, 0x14, 0x6b, 0x14, 0xe8, - 0x55, 0x40, 0x2c, 0xf0, 0xa9, 0xd5, 0x22, 0x6a, 0xa9, 0xaf, 0x58, 0xec, 0xb0, 0x02, 0x62, 0x75, - 0xcb, 0x6a, 0x75, 0x68, 0x6f, 0x88, 0x02, 0x8f, 0xe0, 0x32, 0x7f, 0x67, 0xc0, 0xbc, 0xe6, 0x0b, - 0xc2, 0xef, 0xae, 0x41, 0xa9, 0xa5, 0x45, 0x9d, 0xf2, 0x8b, 0xe8, 0xb4, 0xf5, 0x88, 0xc4, 0x09, - 0x4a, 0x44, 0xa0, 0x40, 0x95, 0xa4, 0x30, 0xbb, 0x5c, 0x49, 0xed, 0xb4, 0xa1, 0x0d, 0xb1, 0x26, - 0x0d, 0xc8, 0x70, 0x2c, 0xd9, 0xfc, 0x87, 0x21, 0x1c, 0x38, 0xcc, 0x37, 0xe8, 0xb2, 0x96, 0xd3, - 0x0c, 0xb1, 0x7d, 0xa5, 0x31, 0xf9, 0xe8, 0x9c, 0x44, 0x90, 0xf9, 0xbf, 0x48, 0x04, 0xd7, 0xf3, - 0xbf, 0xfc, 0xa0, 0x3a, 0xf5, 0xee, 0xdf, 0x56, 0xa7, 0xcc, 0x5f, 0x18, 0x50, 0x5a, 0xef, 0x74, - 0xdc, 0xde, 0x4e, 0x27, 0x10, 0x0b, 0x30, 0x61, 0xc6, 0xa6, 0x3d, 0xdc, 0xf5, 0xd4, 0x42, 0x81, - 0xc7, 0x77, 0x43, 0x40, 0xb0, 0xc2, 0xf0, 0xf8, 0x39, 0xf0, 0x69, 0x93, 0xa8, 0x70, 0x8b, 0xe2, - 0x67, 0x93, 0x03, 0xb1, 0xc4, 0xf1, 0x43, 0x3e, 0x70, 0x88, 0x6b, 0x6f, 0x5b, 0x9e, 0xd5, 0x22, - 0x54, 0x05, 0x47, 0xb4, 0xf5, 0x9b, 0x1a, 0x0e, 0x27, 0x28, 0xcd, 0xff, 0x64, 0xa0, 0xb0, 0xe1, - 0x7b, 0xb6, 0x13, 0xa8, 0xe0, 0x0a, 0x7a, 0x9d, 0xa1, 0xe4, 0x71, 0xbb, 0xd7, 0x21, 0x58, 0x60, - 0xd0, 0x0b, 0x30, 0xc3, 0x02, 0x2b, 0xe8, 0x32, 0x61, 0x4f, 0xa1, 0xfe, 0x58, 0x98, 0x96, 0xf6, - 0x04, 0xf4, 0xac, 0x5f, 0x9d, 0x8f, 0xc4, 0x49, 0x10, 0x56, 0x0c, 0xdc, 0xd3, 0xfd, 0x7d, 0xb1, - 0x51, 0xf6, 0x4d, 0x79, 0xed, 0x85, 0xf7, 0x47, 0x36, 0xf6, 0xf4, 0x9d, 0x21, 0x0a, 0x3c, 0x82, - 0x0b, 0x1d, 0x03, 0x72, 0x2d, 0x16, 0xdc, 0xa6, 0x96, 0xc7, 0x84, 0xae, 0xdb, 0x4e, 0x9b, 0xa8, - 0x80, 0xff, 0x52, 0xba, 0x13, 0xe7, 0x1c, 0xb1, 0xde, 0x5b, 0x43, 0xd2, 0xf0, 0x08, 0x0d, 0xe8, - 0x49, 0x98, 0xa1, 0xc4, 0x62, 0xbe, 0x57, 0xc9, 0x89, 0xe5, 0x47, 0x59, 0x19, 0x0b, 0x28, 0x56, - 0x58, 0x9e, 0xd0, 0xda, 0x84, 0x31, 0xab, 0x15, 0xa6, 0xd7, 0x28, 0xa1, 0x6d, 0x4b, 0x30, 0x0e, - 0xf1, 0xe6, 0x6f, 0x0d, 0x28, 0x6f, 0x50, 0x62, 0x05, 0x64, 0x12, 0xb7, 0x78, 0xe0, 0x13, 0x47, - 0xeb, 0x30, 0x2f, 0xbe, 0xef, 0x5a, 0xae, 0x63, 0xcb, 0x33, 0x98, 0x16, 0xcc, 0x9f, 0x57, 0xcc, - 0xf3, 0x9b, 0x49, 0x34, 0x1e, 0xa4, 0x37, 0x7f, 0x92, 0x85, 0x72, 0x83, 0xb8, 0x24, 0x36, 0x79, - 0x13, 0x50, 0x8b, 0x5a, 0x4d, 0xb2, 0x4b, 0xa8, 0xe3, 0xdb, 0x7b, 0xa4, 0xe9, 0x7b, 0x36, 0x13, - 0x6e, 0x94, 0xad, 0x7f, 0x8e, 0xef, 0xef, 0xcd, 0x21, 0x2c, 0x1e, 0xc1, 0x81, 0x5c, 0x28, 0x77, - 0xa8, 0xf8, 0x2d, 0xf6, 0x5c, 0x7a, 0x59, 0xf1, 0xea, 0x57, 0xd2, 0x1d, 0xe9, 0xae, 0xce, 0x5a, - 0x5f, 0x3c, 0xed, 0x57, 0xcb, 0x09, 0x10, 0x4e, 0x0a, 0x47, 0xdf, 0x80, 0x05, 0x9f, 0x76, 0x0e, - 0x2d, 0xaf, 0x41, 0x3a, 0xc4, 0xb3, 0x89, 0x17, 0x30, 0xb1, 0x91, 0xf9, 0xfa, 0x12, 0xaf, 0x45, - 0x76, 0x06, 0x70, 0x78, 0x88, 0x1a, 0xbd, 0x01, 0x8b, 0x1d, 0xea, 0x77, 0xac, 0x96, 0xd8, 0x98, - 0x5d, 0xdf, 0x75, 0x9a, 0x3d, 0xb5, 0x9d, 0x4f, 0x9f, 0xf6, 0xab, 0x8b, 0xbb, 0x83, 0xc8, 0xb3, - 0x7e, 0xf5, 0x82, 0xd8, 0x3a, 0x0e, 0x89, 0x91, 0x78, 0x58, 0x8c, 0xe6, 0x06, 0xb9, 0x71, 0x6e, - 0x60, 0x6e, 0x41, 0xbe, 0xd1, 0x55, 0x31, 0xf1, 0x12, 0xe4, 0x6d, 0xf5, 0x5b, 0xed, 0x7c, 0x18, - 0x9c, 0x11, 0xcd, 0x59, 0xbf, 0x5a, 0xe6, 0xe5, 0x67, 0x2d, 0x04, 0xe0, 0x88, 0xc5, 0xfc, 0x8d, - 0x01, 0x15, 0x71, 0xf2, 0x7b, 0xc4, 0x25, 0xcd, 0xc0, 0xa7, 0x98, 0xbc, 0xdd, 0x75, 0x28, 0x69, - 0x13, 0x2f, 0x40, 0x5f, 0x84, 0xec, 0x11, 0xe9, 0xa9, 0xbc, 0x50, 0x54, 0x62, 0xb3, 0xaf, 0x91, - 0x1e, 0xe6, 0x70, 0x74, 0x03, 0xf2, 0x7e, 0x87, 0xc7, 0xa6, 0x4f, 0x55, 0x5e, 0x78, 0x2a, 0x54, - 0xbd, 0xa3, 0xe0, 0x67, 0xfd, 0xea, 0xc5, 0x84, 0xf8, 0x10, 0x81, 0x23, 0x56, 0xbe, 0xe2, 0x63, - 0xcb, 0xed, 0x12, 0x7e, 0x0a, 0xd1, 0x8a, 0xef, 0x0a, 0x08, 0x56, 0x18, 0xf3, 0x49, 0xc8, 0x0b, - 0x31, 0xec, 0xee, 0x15, 0xb4, 0x00, 0x59, 0x6c, 0x9d, 0x08, 0xab, 0x4a, 0x98, 0xff, 0xd4, 0x92, - 0xed, 0x0e, 0xc0, 0x4d, 0x12, 0x84, 0xfe, 0xb9, 0x0e, 0xf3, 0xe1, 0x8d, 0x93, 0xbc, 0x08, 0x23, - 0xa7, 0xc7, 0x49, 0x34, 0x1e, 0xa4, 0x37, 0xdf, 0x84, 0x82, 0xb8, 0x2c, 0x79, 0xa5, 0x11, 0x57, - 0x35, 0xc6, 0x7d, 0xaa, 0x9a, 0xb0, 0x54, 0xc9, 0x8c, 0x2b, 0x55, 0x34, 0x73, 0x5d, 0x28, 0x4b, - 0xde, 0xb0, 0x8e, 0x4b, 0xa5, 0xe1, 0x69, 0xc8, 0x87, 0x66, 0x2a, 0x2d, 0x51, 0xfd, 0x1e, 0x0a, - 0xc2, 0x11, 0x85, 0xa6, 0xed, 0x10, 0x12, 0x17, 0x7f, 0x3a, 0x65, 0x5a, 0x91, 0x96, 0xb9, 0x7f, - 0x91, 0xa6, 0x69, 0xfa, 0x21, 0x54, 0xc6, 0x15, 0xfd, 0x0f, 0x51, 0x9a, 0xa4, 0x37, 0xc5, 0x7c, - 0xcf, 0x80, 0x05, 0x5d, 0x52, 0xfa, 0xe3, 0x4b, 0xaf, 0xe4, 0xfc, 0xa2, 0x54, 0xdb, 0x91, 0x5f, - 0x19, 0xb0, 0x94, 0x58, 0xda, 0x44, 0x27, 0x3e, 0x81, 0x51, 0xba, 0x73, 0x64, 0x27, 0x70, 0x8e, - 0xbf, 0x64, 0xa0, 0x7c, 0xcb, 0xda, 0x27, 0x6e, 0x18, 0xa9, 0xe8, 0x07, 0x50, 0x6c, 0x5b, 0x41, - 0xf3, 0x50, 0x40, 0xc3, 0x06, 0xa6, 0x91, 0x2e, 0x27, 0x27, 0x24, 0xd5, 0xb6, 0x63, 0x31, 0x37, - 0xbc, 0x80, 0xf6, 0xea, 0x17, 0x94, 0x49, 0x45, 0x0d, 0x83, 0x75, 0x6d, 0xa2, 0xeb, 0x14, 0xdf, - 0x37, 0xde, 0xe9, 0xf0, 0xea, 0x6a, 0xf2, 0x66, 0x37, 0x61, 0x82, 0x96, 0xd5, 0xe2, 0xae, 0x73, - 0x7b, 0x40, 0x3e, 0x1e, 0xd2, 0xb8, 0xfc, 0x32, 0x2c, 0x0c, 0x1a, 0xcf, 0xf3, 0x4f, 0x94, 0x15, - 0x65, 0x22, 0x5c, 0x82, 0x9c, 0xc8, 0x53, 0xf2, 0x70, 0xb0, 0xfc, 0xb8, 0x9e, 0xb9, 0x66, 0x88, - 0xf4, 0x3a, 0xce, 0x90, 0x47, 0x94, 0x5e, 0x13, 0xe2, 0x1f, 0x30, 0xbd, 0xfe, 0xde, 0x80, 0x69, - 0xd1, 0x37, 0xbc, 0x09, 0x79, 0xbe, 0x7f, 0xb6, 0x15, 0x58, 0xc2, 0xae, 0xd4, 0x1d, 0x2b, 0xe7, - 0xde, 0x26, 0x81, 0x15, 0x7b, 0x5b, 0x08, 0xc1, 0x91, 0x44, 0x84, 0x21, 0xe7, 0x04, 0xa4, 0x1d, - 0x1e, 0xe4, 0x33, 0x63, 0x45, 0xab, 0x79, 0x49, 0x0d, 0x5b, 0x27, 0x37, 0xde, 0x09, 0x88, 0xc7, - 0x0f, 0x23, 0x0e, 0x8d, 0x2d, 0x2e, 0x03, 0x4b, 0x51, 0xe6, 0xbf, 0x0c, 0x88, 0x54, 0x71, 0xe7, - 0x67, 0xc4, 0x3d, 0xb8, 0xe5, 0x78, 0x47, 0x6a, 0x5b, 0x23, 0x73, 0xf6, 0x14, 0x1c, 0x47, 0x14, - 0xa3, 0xae, 0x87, 0xcc, 0x64, 0xd7, 0x03, 0x57, 0xd8, 0xf4, 0xbd, 0xc0, 0xf1, 0xba, 0x43, 0xd1, - 0xb6, 0xa1, 0xe0, 0x38, 0xa2, 0xe0, 0xf5, 0x12, 0x25, 0x6d, 0xcb, 0xf1, 0x1c, 0xaf, 0xc5, 0x17, - 0xb1, 0xe1, 0x77, 0xbd, 0x40, 0x14, 0x0e, 0xaa, 0x5e, 0xc2, 0x43, 0x58, 0x3c, 0x82, 0xc3, 0xfc, - 0xf7, 0x34, 0x14, 0xf9, 0x9a, 0xc3, 0x7b, 0xee, 0x45, 0x28, 0xbb, 0xba, 0x17, 0xa8, 0xb5, 0x5f, - 0x54, 0xa6, 0x24, 0xe3, 0x1a, 0x27, 0x69, 0x39, 0xf3, 0x81, 0x7e, 0x43, 0xab, 0x3d, 0x88, 0x98, - 0x93, 0xd5, 0x41, 0x92, 0x96, 0x67, 0xaf, 0x13, 0x1e, 0x1f, 0xaa, 0x80, 0x8a, 0x8e, 0xe8, 0x9b, - 0x1c, 0x88, 0x25, 0x0e, 0x6d, 0xc3, 0x05, 0xcb, 0x75, 0xfd, 0x13, 0x01, 0xac, 0xfb, 0xfe, 0x51, - 0xdb, 0xa2, 0x47, 0x4c, 0xf4, 0xfc, 0xf9, 0xfa, 0x17, 0x14, 0xcb, 0x85, 0xf5, 0x61, 0x12, 0x3c, - 0x8a, 0x6f, 0xd4, 0xb1, 0x4d, 0x4f, 0x78, 0x6c, 0x87, 0xb0, 0x34, 0x00, 0x12, 0x51, 0xae, 0x1a, - 0xf0, 0xe7, 0x94, 0x9c, 0x25, 0x3c, 0x82, 0xe6, 0x6c, 0x0c, 0x1c, 0x8f, 0x94, 0x88, 0xae, 0xc3, - 0x1c, 0xf7, 0x64, 0xbf, 0x1b, 0x84, 0xe5, 0x71, 0x4e, 0x1c, 0x37, 0x3a, 0xed, 0x57, 0xe7, 0x6e, - 0x27, 0x30, 0x78, 0x80, 0x92, 0x6f, 0xae, 0xeb, 0xb4, 0x9d, 0xa0, 0x32, 0x2b, 0x58, 0xa2, 0xcd, - 0xbd, 0xc5, 0x81, 0x58, 0xe2, 0x12, 0x1e, 0x98, 0x3f, 0xd7, 0x03, 0x37, 0x60, 0x91, 0x11, 0xcf, - 0xde, 0xf2, 0x9c, 0xc0, 0xb1, 0xdc, 0x1b, 0xc7, 0xa2, 0xf8, 0x2d, 0x8a, 0x83, 0xb8, 0xc8, 0x2b, - 0xd7, 0xbd, 0x41, 0x24, 0x1e, 0xa6, 0x37, 0xff, 0x9c, 0x05, 0x24, 0xfb, 0x0a, 0x5b, 0x16, 0x65, - 0x32, 0x2f, 0xf2, 0xee, 0x47, 0xf5, 0x25, 0xc6, 0x40, 0xf7, 0xa3, 0x5a, 0x92, 0x10, 0x8f, 0xb6, - 0xa1, 0x20, 0xf3, 0x53, 0x1c, 0x73, 0x6b, 0x8a, 0xb8, 0xb0, 0x13, 0x22, 0xce, 0xfa, 0xd5, 0xe5, - 0x84, 0x9a, 0x08, 0x23, 0x3a, 0xd3, 0x58, 0x02, 0xba, 0x0a, 0x60, 0x75, 0x1c, 0x7d, 0x36, 0x59, - 0x88, 0x27, 0x54, 0xf1, 0x94, 0x01, 0x6b, 0x54, 0xe8, 0x15, 0x98, 0x0e, 0x1e, 0xac, 0x7b, 0xcc, - 0x8b, 0xe6, 0x98, 0xf7, 0x8a, 0x42, 0x02, 0xd7, 0x2e, 0x82, 0x82, 0x71, 0xb3, 0x54, 0xe3, 0x17, - 0x69, 0xdf, 0x8c, 0x30, 0x58, 0xa3, 0x42, 0xdf, 0x82, 0xfc, 0x81, 0xaa, 0x67, 0xc5, 0xe9, 0xa6, - 0xce, 0xb3, 0x61, 0x15, 0x2c, 0xc7, 0x23, 0xe1, 0x17, 0x8e, 0xa4, 0xa1, 0xaf, 0x42, 0x91, 0x75, - 0xf7, 0xa3, 0x12, 0x40, 0xba, 0x44, 0x74, 0xdf, 0xee, 0xc5, 0x28, 0xac, 0xd3, 0x99, 0x6f, 0x43, - 0x61, 0xdb, 0x69, 0x52, 0x5f, 0xf4, 0xbb, 0x4f, 0xc1, 0x2c, 0x4b, 0x34, 0x73, 0xd1, 0x49, 0x86, - 0xae, 0x1a, 0xe2, 0xb9, 0x8f, 0x7a, 0x96, 0xe7, 0xcb, 0x96, 0x2d, 0x17, 0xfb, 0xe8, 0xeb, 0x1c, - 0x88, 0x25, 0xee, 0xfa, 0x12, 0xaf, 0x32, 0x7e, 0xfa, 0x61, 0x75, 0xea, 0xfd, 0x0f, 0xab, 0x53, - 0x1f, 0x7c, 0xa8, 0x2a, 0x8e, 0x3f, 0x00, 0xc0, 0xce, 0xfe, 0xf7, 0x48, 0x53, 0xe6, 0xee, 0x54, - 0x23, 0xcc, 0x70, 0x72, 0x2e, 0x46, 0x98, 0x99, 0x81, 0xca, 0x51, 0xc3, 0xe1, 0x04, 0x25, 0x5a, - 0x83, 0x42, 0x34, 0x9c, 0x54, 0xfe, 0xb1, 0x18, 0xfa, 0x5b, 0x34, 0xc1, 0xc4, 0x31, 0x4d, 0xe2, - 0x22, 0x99, 0x3e, 0xf7, 0x22, 0xa9, 0x43, 0xb6, 0xeb, 0xd8, 0x6a, 0x38, 0xf0, 0x6c, 0x78, 0x91, - 0xdf, 0xd9, 0x6a, 0x9c, 0xf5, 0xab, 0x8f, 0x8d, 0x7b, 0x13, 0x08, 0x7a, 0x1d, 0xc2, 0x6a, 0x77, - 0xb6, 0x1a, 0x98, 0x33, 0x8f, 0xca, 0x6a, 0x33, 0x13, 0x66, 0xb5, 0xab, 0x00, 0xad, 0x78, 0xc4, - 0x22, 0x93, 0x46, 0xe4, 0x88, 0xda, 0x68, 0x45, 0xa3, 0x42, 0x0c, 0x16, 0x9b, 0x94, 0x58, 0xe1, - 0xa8, 0x83, 0x05, 0x56, 0x5b, 0x0e, 0x6d, 0x27, 0x8b, 0x89, 0x4b, 0x4a, 0xcd, 0xe2, 0xc6, 0xa0, - 0x30, 0x3c, 0x2c, 0x1f, 0xf9, 0xb0, 0x68, 0xab, 0x6e, 0x38, 0x56, 0x5a, 0x98, 0x58, 0xa9, 0xc8, - 0x58, 0x8d, 0x41, 0x41, 0x78, 0x58, 0x36, 0xfa, 0x2e, 0x2c, 0x87, 0xc0, 0xe1, 0x91, 0x84, 0xc8, - 0xfa, 0xd9, 0xfa, 0xca, 0x69, 0xbf, 0xba, 0xdc, 0x18, 0x4b, 0x85, 0xef, 0x23, 0x01, 0xd9, 0x30, - 0xe3, 0xca, 0x2a, 0xb9, 0x28, 0x2a, 0x9b, 0xaf, 0xa5, 0x5b, 0x45, 0xec, 0xfd, 0x35, 0xbd, 0x3a, - 0x8e, 0xc6, 0x4b, 0xaa, 0x30, 0x56, 0xb2, 0xd1, 0x3b, 0x50, 0xb4, 0x3c, 0xcf, 0x0f, 0x2c, 0x39, - 0x24, 0x29, 0x09, 0x55, 0xeb, 0x13, 0xab, 0x5a, 0x8f, 0x65, 0x0c, 0x54, 0xe3, 0x1a, 0x06, 0xeb, - 0xaa, 0xd0, 0x09, 0xcc, 0xfb, 0x27, 0x1e, 0xa1, 0x98, 0x1c, 0x10, 0x4a, 0xbc, 0x26, 0x61, 0x95, - 0xb2, 0xd0, 0xfe, 0x5c, 0x4a, 0xed, 0x09, 0xe6, 0xd8, 0xa5, 0x93, 0x70, 0x86, 0x07, 0xb5, 0xa0, - 0x1a, 0xcf, 0xad, 0x9e, 0xe5, 0x3a, 0xdf, 0x27, 0x94, 0x55, 0xe6, 0xe2, 0xb9, 0xfa, 0x66, 0x04, - 0xc5, 0x1a, 0x05, 0xea, 0x42, 0xb9, 0xad, 0x5f, 0x19, 0x95, 0x45, 0x61, 0xe6, 0xb5, 0x74, 0x66, - 0x0e, 0x5f, 0x6a, 0x71, 0x19, 0x94, 0xc0, 0xe1, 0xa4, 0x96, 0xe5, 0x17, 0xa0, 0xf8, 0x80, 0x1d, - 0x02, 0xef, 0x30, 0x06, 0x0f, 0x64, 0xa2, 0x0e, 0xe3, 0x8f, 0x19, 0x98, 0x4b, 0x6e, 0xe3, 0xc0, - 0x75, 0x98, 0x4b, 0x75, 0x1d, 0x86, 0xbd, 0xac, 0x31, 0xf6, 0x81, 0x25, 0xcc, 0xcf, 0xd9, 0xb1, - 0xf9, 0x59, 0xa5, 0xc1, 0xe9, 0x87, 0x49, 0x83, 0x35, 0x00, 0x5e, 0xac, 0x50, 0xdf, 0x75, 0x09, - 0x15, 0x19, 0x30, 0xaf, 0x1e, 0x52, 0x22, 0x28, 0xd6, 0x28, 0x78, 0x49, 0xbd, 0xef, 0xfa, 0xcd, - 0x23, 0xb1, 0x05, 0x61, 0xf4, 0x8a, 0xdc, 0x97, 0x97, 0x25, 0x75, 0x7d, 0x08, 0x8b, 0x47, 0x70, - 0x98, 0x3d, 0xb8, 0xb8, 0x6b, 0x51, 0x5e, 0xe4, 0xc4, 0x91, 0x22, 0x7a, 0x96, 0xb7, 0x86, 0x3a, - 0xa2, 0x67, 0x27, 0x8d, 0xb8, 0x78, 0xf3, 0x63, 0x58, 0xdc, 0x15, 0x99, 0x7f, 0x35, 0xe0, 0xd2, - 0x48, 0xdd, 0x9f, 0x41, 0x47, 0xf6, 0x56, 0xb2, 0x23, 0x7b, 0x31, 0xe5, 0xc4, 0x75, 0x94, 0xb5, - 0x63, 0xfa, 0xb3, 0x59, 0xc8, 0xed, 0xf2, 0x4a, 0xd8, 0xfc, 0xd8, 0x80, 0x92, 0xf8, 0x35, 0xc9, - 0xc0, 0xbb, 0x9a, 0x7c, 0x07, 0x29, 0x3c, 0xba, 0x37, 0x90, 0x47, 0x31, 0x11, 0x7f, 0xcf, 0x80, - 0xe4, 0xa8, 0x19, 0xbd, 0x2c, 0x43, 0xc0, 0x88, 0x66, 0xc1, 0x13, 0xba, 0xff, 0x4b, 0xe3, 0x5a, - 0xd2, 0x0b, 0xa9, 0xa6, 0x95, 0x4f, 0x43, 0x01, 0xfb, 0x7e, 0xb0, 0x6b, 0x05, 0x87, 0x8c, 0xef, - 0x5d, 0x87, 0xff, 0x50, 0xdb, 0x2b, 0xf6, 0x4e, 0x60, 0xb0, 0x84, 0x9b, 0x3f, 0x37, 0xe0, 0xd2, - 0xd8, 0xe7, 0x2d, 0x9e, 0x45, 0x9a, 0xd1, 0x97, 0x5a, 0x51, 0xe4, 0xc8, 0x31, 0x1d, 0xd6, 0xa8, - 0x78, 0x2f, 0x99, 0x78, 0x13, 0x1b, 0xec, 0x25, 0x13, 0xda, 0x70, 0x92, 0xd6, 0xfc, 0x67, 0x06, - 0xd4, 0x7b, 0xd2, 0xff, 0xd8, 0xe9, 0x9f, 0x1c, 0x78, 0xcd, 0x9a, 0x4b, 0xbe, 0x66, 0x45, 0x4f, - 0x57, 0xda, 0x73, 0x4e, 0xf6, 0xfe, 0xcf, 0x39, 0xe8, 0xf9, 0xe8, 0x85, 0x48, 0xfa, 0xd0, 0x4a, - 0xf2, 0x85, 0xe8, 0xac, 0x5f, 0x2d, 0x29, 0xe1, 0xc9, 0x17, 0xa3, 0x37, 0x60, 0xd6, 0x26, 0x81, - 0xe5, 0xb8, 0xb2, 0x2f, 0x4c, 0xfd, 0xe6, 0x21, 0x85, 0x35, 0x24, 0x6b, 0xbd, 0xc8, 0x6d, 0x52, - 0x1f, 0x38, 0x14, 0xc8, 0x13, 0x76, 0xd3, 0xb7, 0x65, 0x47, 0x92, 0x8b, 0x13, 0xf6, 0x86, 0x6f, - 0x13, 0x2c, 0x30, 0xe6, 0xfb, 0x06, 0x14, 0xa5, 0xa4, 0x0d, 0xab, 0xcb, 0x08, 0xba, 0x12, 0xad, - 0x42, 0x1e, 0xf7, 0x25, 0xfd, 0x29, 0xf0, 0xac, 0x5f, 0x2d, 0x08, 0x32, 0xd1, 0xcc, 0x8c, 0x78, - 0xf2, 0xca, 0x9c, 0xb3, 0x47, 0x8f, 0x43, 0x4e, 0x04, 0x90, 0xda, 0xcc, 0xf8, 0x4d, 0x93, 0x03, - 0xb1, 0xc4, 0x99, 0x9f, 0x66, 0xa0, 0x9c, 0x58, 0x5c, 0x8a, 0xbe, 0x20, 0x1a, 0xa1, 0x66, 0x52, - 0x8c, 0xe5, 0xc7, 0xff, 0x83, 0x40, 0x5d, 0x5f, 0x33, 0x0f, 0x73, 0x7d, 0x7d, 0x1b, 0x66, 0x9a, - 0x7c, 0x8f, 0xc2, 0x3f, 0xa4, 0x5c, 0x99, 0xe4, 0x38, 0xc5, 0xee, 0xc6, 0xde, 0x28, 0x3e, 0x19, - 0x56, 0x02, 0xd1, 0x4d, 0x58, 0xa4, 0x24, 0xa0, 0xbd, 0xf5, 0x83, 0x80, 0x50, 0x7d, 0x98, 0x90, - 0x8b, 0xab, 0x6f, 0x3c, 0x48, 0x80, 0x87, 0x79, 0xcc, 0x7d, 0x28, 0xdd, 0xb6, 0xf6, 0xdd, 0xe8, - 0x15, 0x0f, 0x43, 0xd9, 0xf1, 0x9a, 0x6e, 0xd7, 0x26, 0x32, 0xa1, 0x87, 0xd9, 0x2b, 0x0c, 0xda, - 0x2d, 0x1d, 0x79, 0xd6, 0xaf, 0x5e, 0x48, 0x00, 0xe4, 0xb3, 0x15, 0x4e, 0x8a, 0x30, 0x5d, 0x98, - 0xfe, 0x0c, 0x3b, 0xc9, 0xef, 0x40, 0x21, 0xae, 0xf5, 0x1f, 0xb1, 0x4a, 0xf3, 0x2d, 0xc8, 0x73, - 0x8f, 0x0f, 0x7b, 0xd4, 0x73, 0xaa, 0xa4, 0x64, 0xed, 0x95, 0x49, 0x53, 0x7b, 0x89, 0xb7, 0xe0, - 0x3b, 0x1d, 0xfb, 0x21, 0xdf, 0x82, 0x33, 0x0f, 0x73, 0xf3, 0x65, 0x27, 0xbc, 0xf9, 0xae, 0x82, - 0xfc, 0xbf, 0x0c, 0xbf, 0x64, 0x64, 0x01, 0xa1, 0x5d, 0x32, 0xfa, 0xfd, 0xaf, 0xbd, 0x30, 0xfc, - 0xd8, 0x00, 0x10, 0xa3, 0x3c, 0x31, 0x46, 0x4a, 0xf1, 0xaf, 0x83, 0x3b, 0x30, 0xe3, 0x4b, 0x8f, - 0x94, 0xef, 0xc1, 0x13, 0xce, 0x8b, 0xa3, 0x40, 0x92, 0x3e, 0x89, 0x95, 0xb0, 0xfa, 0xab, 0x1f, - 0xdd, 0x5b, 0x99, 0xfa, 0xf8, 0xde, 0xca, 0xd4, 0x27, 0xf7, 0x56, 0xa6, 0xde, 0x3d, 0x5d, 0x31, - 0x3e, 0x3a, 0x5d, 0x31, 0x3e, 0x3e, 0x5d, 0x31, 0x3e, 0x39, 0x5d, 0x31, 0x3e, 0x3d, 0x5d, 0x31, - 0xde, 0xff, 0xfb, 0xca, 0xd4, 0x1b, 0x4f, 0xa4, 0xf9, 0x1f, 0xe2, 0x7f, 0x03, 0x00, 0x00, 0xff, - 0xff, 0xd3, 0xee, 0xe4, 0x1c, 0xae, 0x28, 0x00, 0x00, + // 2928 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x3a, 0x4d, 0x6c, 0x24, 0x47, + 0xd5, 0xee, 0xf9, 0xb1, 0x67, 0xde, 0x78, 0xfc, 0x53, 0xeb, 0xfd, 0xbe, 0x59, 0x23, 0x3c, 0x4e, + 0x27, 0x8a, 0x36, 0x90, 0x8c, 0x77, 0x97, 0x25, 0xda, 0x6c, 0x48, 0xc0, 0xe3, 0x59, 0x6f, 0x9c, + 0xac, 0x63, 0xab, 0xbc, 0xbb, 0x81, 0x10, 0xa1, 0x94, 0xa7, 0xcb, 0xe3, 0xc6, 0x3d, 0xdd, 0x93, + 0xaa, 0x1e, 0x6f, 0x06, 0x0e, 0xe4, 0x00, 0x12, 0x48, 0x28, 0x0a, 0x37, 0x4e, 0x28, 0x11, 0x9c, + 0x38, 0x21, 0x4e, 0xdc, 0x41, 0x22, 0xc7, 0x20, 0x2e, 0x91, 0x40, 0xa3, 0xac, 0x39, 0x70, 0x44, + 0x5c, 0x2d, 0x24, 0x50, 0xfd, 0xf4, 0xdf, 0xfc, 0xac, 0x7b, 0x76, 0x97, 0x88, 0xdb, 0xf4, 0xfb, + 0xaf, 0xaa, 0xf7, 0x5e, 0xbd, 0xf7, 0x6a, 0xe0, 0xea, 0xd1, 0x35, 0x5e, 0xb3, 0xbd, 0x35, 0xd2, + 0xb1, 0xdb, 0xa4, 0x79, 0x68, 0xbb, 0x94, 0xf5, 0xd6, 0x3a, 0x47, 0x2d, 0x01, 0xe0, 0x6b, 0x6d, + 0xea, 0x93, 0xb5, 0xe3, 0xcb, 0x6b, 0x2d, 0xea, 0x52, 0x46, 0x7c, 0x6a, 0xd5, 0x3a, 0xcc, 0xf3, + 0x3d, 0xf4, 0x94, 0xe2, 0xaa, 0xc5, 0xb9, 0x6a, 0x9d, 0xa3, 0x96, 0x00, 0xf0, 0x9a, 0xe0, 0xaa, + 0x1d, 0x5f, 0x5e, 0x7e, 0xae, 0x65, 0xfb, 0x87, 0xdd, 0xfd, 0x5a, 0xd3, 0x6b, 0xaf, 0xb5, 0xbc, + 0x96, 0xb7, 0x26, 0x99, 0xf7, 0xbb, 0x07, 0xf2, 0x4b, 0x7e, 0xc8, 0x5f, 0x4a, 0xe8, 0xf2, 0xda, + 0x38, 0x53, 0x58, 0xd7, 0xf5, 0xed, 0x36, 0x1d, 0xb4, 0x62, 0xf9, 0xf9, 0xb3, 0x18, 0x78, 0xf3, + 0x90, 0xb6, 0xc9, 0x20, 0x9f, 0xf9, 0xc7, 0x2c, 0x14, 0xd6, 0x77, 0xb7, 0x6e, 0x32, 0xaf, 0xdb, + 0x41, 0xab, 0x90, 0x73, 0x49, 0x9b, 0x56, 0x8c, 0x55, 0xe3, 0x62, 0xb1, 0x3e, 0xfb, 0x71, 0xbf, + 0x3a, 0x75, 0xd2, 0xaf, 0xe6, 0x5e, 0x27, 0x6d, 0x8a, 0x25, 0x06, 0x39, 0x50, 0x38, 0xa6, 0x8c, + 0xdb, 0x9e, 0xcb, 0x2b, 0x99, 0xd5, 0xec, 0xc5, 0xd2, 0x95, 0x97, 0x6b, 0x69, 0xd6, 0x5f, 0x93, + 0x0a, 0xee, 0x2a, 0xd6, 0x4d, 0x8f, 0x35, 0x6c, 0xde, 0xf4, 0x8e, 0x29, 0xeb, 0xd5, 0x17, 0xb4, + 0x96, 0x82, 0x46, 0x72, 0x1c, 0x6a, 0x40, 0x3f, 0x34, 0x60, 0xa1, 0xc3, 0xe8, 0x01, 0x65, 0x8c, + 0x5a, 0x1a, 0x5f, 0xc9, 0xae, 0x1a, 0x8f, 0x41, 0x6d, 0x45, 0xab, 0x5d, 0xd8, 0x1d, 0x90, 0x8f, + 0x87, 0x34, 0xa2, 0x5f, 0x1a, 0xb0, 0xcc, 0x29, 0x3b, 0xa6, 0x6c, 0xdd, 0xb2, 0x18, 0xe5, 0xbc, + 0xde, 0xdb, 0x70, 0x6c, 0xea, 0xfa, 0x1b, 0x5b, 0x0d, 0xcc, 0x2b, 0x39, 0xb9, 0x0f, 0x5f, 0x4f, + 0x67, 0xd0, 0xde, 0x38, 0x39, 0x75, 0x53, 0x5b, 0xb4, 0x3c, 0x96, 0x84, 0xe3, 0x07, 0x98, 0x61, + 0x1e, 0xc0, 0x6c, 0x70, 0x90, 0xb7, 0x6c, 0xee, 0xa3, 0xbb, 0x30, 0xdd, 0x12, 0x1f, 0xbc, 0x62, + 0x48, 0x03, 0x6b, 0xe9, 0x0c, 0x0c, 0x64, 0xd4, 0xe7, 0xb4, 0x3d, 0xd3, 0xf2, 0x93, 0x63, 0x2d, + 0xcd, 0xfc, 0x49, 0x0e, 0x4a, 0xeb, 0xbb, 0x5b, 0x98, 0x72, 0xaf, 0xcb, 0x9a, 0x34, 0x85, 0xd3, + 0x5c, 0x83, 0x59, 0x6e, 0xbb, 0xad, 0xae, 0x43, 0x98, 0x80, 0x56, 0xa6, 0x25, 0xe5, 0x92, 0xa6, + 0x9c, 0xdd, 0x8b, 0xe1, 0x70, 0x82, 0x12, 0x5d, 0x01, 0x10, 0x12, 0x78, 0x87, 0x34, 0xa9, 0x55, + 0xc9, 0xac, 0x1a, 0x17, 0x0b, 0x75, 0xa4, 0xf9, 0xe0, 0xf5, 0x10, 0x83, 0x63, 0x54, 0xe8, 0x49, + 0xc8, 0x4b, 0x4b, 0x2b, 0x05, 0xa9, 0xa6, 0xac, 0xc9, 0xf3, 0x72, 0x19, 0x58, 0xe1, 0xd0, 0x33, + 0x30, 0xa3, 0xbd, 0xac, 0x52, 0x94, 0x64, 0xf3, 0x9a, 0x6c, 0x26, 0x70, 0x83, 0x00, 0x2f, 0xd6, + 0x77, 0x64, 0xbb, 0x96, 0xf4, 0xbb, 0xd8, 0xfa, 0x5e, 0xb3, 0x5d, 0x0b, 0x4b, 0x0c, 0xba, 0x05, + 0xf9, 0x63, 0xca, 0xf6, 0x85, 0x27, 0x08, 0xd7, 0xfc, 0x72, 0xba, 0x8d, 0xbe, 0x2b, 0x58, 0xea, + 0x45, 0x61, 0x9a, 0xfc, 0x89, 0x95, 0x10, 0x54, 0x03, 0xe0, 0x87, 0x1e, 0xf3, 0xe5, 0xf2, 0x2a, + 0xf9, 0xd5, 0xec, 0xc5, 0x62, 0x7d, 0x4e, 0xac, 0x77, 0x2f, 0x84, 0xe2, 0x18, 0x85, 0xa0, 0x6f, + 0x12, 0x9f, 0xb6, 0x3c, 0x66, 0x53, 0x5e, 0x99, 0x89, 0xe8, 0x37, 0x42, 0x28, 0x8e, 0x51, 0xa0, + 0x57, 0x01, 0x71, 0xdf, 0x63, 0xa4, 0x45, 0xf5, 0x52, 0x5f, 0x21, 0xfc, 0xb0, 0x02, 0x72, 0x75, + 0xcb, 0x7a, 0x75, 0x68, 0x6f, 0x88, 0x02, 0x8f, 0xe0, 0x32, 0x7f, 0x6b, 0xc0, 0x7c, 0xcc, 0x17, + 0xa4, 0xdf, 0x5d, 0x83, 0xd9, 0x56, 0x2c, 0xea, 0xb4, 0x5f, 0x84, 0xa7, 0x1d, 0x8f, 0x48, 0x9c, + 0xa0, 0x44, 0x14, 0x8a, 0x4c, 0x4b, 0x0a, 0xb2, 0xcb, 0xe5, 0xd4, 0x4e, 0x1b, 0xd8, 0x10, 0x69, + 0x8a, 0x01, 0x39, 0x8e, 0x24, 0x9b, 0x7f, 0x37, 0xa4, 0x03, 0x07, 0xf9, 0x06, 0x5d, 0x8c, 0xe5, + 0x34, 0x43, 0x6e, 0xdf, 0xec, 0x98, 0x7c, 0x74, 0x46, 0x22, 0xc8, 0xfc, 0x4f, 0x24, 0x82, 0xeb, + 0x85, 0x9f, 0x7f, 0x58, 0x9d, 0x7a, 0xef, 0xaf, 0xab, 0x53, 0xe6, 0xcf, 0x0c, 0x98, 0x5d, 0xef, + 0x74, 0x9c, 0xde, 0x4e, 0xc7, 0x97, 0x0b, 0x30, 0x61, 0xda, 0x62, 0x3d, 0xdc, 0x75, 0xf5, 0x42, + 0x41, 0xc4, 0x77, 0x43, 0x42, 0xb0, 0xc6, 0x88, 0xf8, 0x39, 0xf0, 0x58, 0x93, 0xea, 0x70, 0x0b, + 0xe3, 0x67, 0x53, 0x00, 0xb1, 0xc2, 0x89, 0x43, 0x3e, 0xb0, 0xa9, 0x63, 0x6d, 0x13, 0x97, 0xb4, + 0x28, 0xd3, 0xc1, 0x11, 0x6e, 0xfd, 0x66, 0x0c, 0x87, 0x13, 0x94, 0xe6, 0xbf, 0x33, 0x50, 0xdc, + 0xf0, 0x5c, 0xcb, 0xf6, 0x75, 0x70, 0xf9, 0xbd, 0xce, 0x50, 0xf2, 0xb8, 0xdd, 0xeb, 0x50, 0x2c, + 0x31, 0xe8, 0x05, 0x98, 0xe6, 0x3e, 0xf1, 0xbb, 0x5c, 0xda, 0x53, 0xac, 0x3f, 0x11, 0xa4, 0xa5, + 0x3d, 0x09, 0x3d, 0xed, 0x57, 0xe7, 0x43, 0x71, 0x0a, 0x84, 0x35, 0x83, 0xf0, 0x74, 0x6f, 0x5f, + 0x6e, 0x94, 0x75, 0x53, 0x5d, 0x7b, 0xc1, 0xfd, 0x91, 0x8d, 0x3c, 0x7d, 0x67, 0x88, 0x02, 0x8f, + 0xe0, 0x42, 0xc7, 0x80, 0x1c, 0xc2, 0xfd, 0xdb, 0x8c, 0xb8, 0x5c, 0xea, 0xba, 0x6d, 0xb7, 0xa9, + 0x0e, 0xf8, 0x2f, 0xa5, 0x3b, 0x71, 0xc1, 0x11, 0xe9, 0xbd, 0x35, 0x24, 0x0d, 0x8f, 0xd0, 0x80, + 0x9e, 0x86, 0x69, 0x46, 0x09, 0xf7, 0xdc, 0x4a, 0x5e, 0x2e, 0x3f, 0xcc, 0xca, 0x58, 0x42, 0xb1, + 0xc6, 0x8a, 0x84, 0xd6, 0xa6, 0x9c, 0x93, 0x56, 0x90, 0x5e, 0xc3, 0x84, 0xb6, 0xad, 0xc0, 0x38, + 0xc0, 0x9b, 0xbf, 0x31, 0xa0, 0xbc, 0xc1, 0x28, 0xf1, 0xe9, 0x24, 0x6e, 0xf1, 0xd0, 0x27, 0x8e, + 0xd6, 0x61, 0x5e, 0x7e, 0xdf, 0x25, 0x8e, 0x6d, 0xa9, 0x33, 0xc8, 0x49, 0xe6, 0xff, 0xd7, 0xcc, + 0xf3, 0x9b, 0x49, 0x34, 0x1e, 0xa4, 0x37, 0x7f, 0x9d, 0x83, 0x72, 0x83, 0x3a, 0x34, 0x32, 0x79, + 0x13, 0x50, 0x8b, 0x91, 0x26, 0xdd, 0xa5, 0xcc, 0xf6, 0xac, 0x3d, 0xda, 0xf4, 0x5c, 0x8b, 0x4b, + 0x37, 0xca, 0xd6, 0xff, 0x4f, 0xec, 0xef, 0xcd, 0x21, 0x2c, 0x1e, 0xc1, 0x81, 0x1c, 0x28, 0x77, + 0x98, 0xfc, 0x2d, 0xf7, 0x5c, 0x79, 0x59, 0xe9, 0xca, 0x57, 0xd2, 0x1d, 0xe9, 0x6e, 0x9c, 0xb5, + 0xbe, 0x78, 0xd2, 0xaf, 0x96, 0x13, 0x20, 0x9c, 0x14, 0x8e, 0xbe, 0x01, 0x0b, 0x1e, 0xeb, 0x1c, + 0x12, 0xb7, 0x41, 0x3b, 0xd4, 0xb5, 0xa8, 0xeb, 0x73, 0xb9, 0x91, 0x85, 0xfa, 0x92, 0xa8, 0x45, + 0x76, 0x06, 0x70, 0x78, 0x88, 0x1a, 0xbd, 0x09, 0x8b, 0x1d, 0xe6, 0x75, 0x48, 0x4b, 0x6e, 0xcc, + 0xae, 0xe7, 0xd8, 0xcd, 0x9e, 0xde, 0xce, 0x67, 0x4f, 0xfa, 0xd5, 0xc5, 0xdd, 0x41, 0xe4, 0x69, + 0xbf, 0x7a, 0x4e, 0x6e, 0x9d, 0x80, 0x44, 0x48, 0x3c, 0x2c, 0x26, 0xe6, 0x06, 0xf9, 0xb1, 0x6e, + 0xf0, 0xa1, 0x01, 0x97, 0xec, 0x96, 0xeb, 0x31, 0x2a, 0xae, 0x08, 0x8a, 0x29, 0xb1, 0x6e, 0x30, + 0xe6, 0xb1, 0x37, 0x6c, 0xff, 0x70, 0xc3, 0xe9, 0x72, 0x9f, 0xb2, 0x3a, 0xa3, 0xe4, 0xc8, 0x76, + 0x5b, 0xbb, 0x9e, 0x4f, 0x5d, 0xdf, 0x26, 0x8e, 0xf4, 0xc8, 0x42, 0xfd, 0xea, 0x49, 0xbf, 0x7a, + 0x69, 0x6b, 0x42, 0x5e, 0x3c, 0xb1, 0x36, 0x73, 0x0b, 0x0a, 0x8d, 0xae, 0x0e, 0xdb, 0x97, 0xa0, + 0x60, 0xe9, 0xdf, 0xda, 0x39, 0x82, 0xfc, 0x11, 0xd2, 0x9c, 0xf6, 0xab, 0x65, 0x51, 0x21, 0xd7, + 0x02, 0x00, 0x0e, 0x59, 0xcc, 0x5f, 0x19, 0x50, 0x91, 0xce, 0xb9, 0x47, 0x1d, 0xda, 0xf4, 0x3d, + 0x86, 0xe9, 0x3b, 0x5d, 0x9b, 0xd1, 0x36, 0x75, 0x7d, 0xf4, 0x45, 0xc8, 0x1e, 0xd1, 0x9e, 0x4e, + 0x5d, 0x25, 0x2d, 0x36, 0xfb, 0x1a, 0xed, 0x61, 0x01, 0x47, 0x37, 0xa0, 0xe0, 0x75, 0x44, 0xfa, + 0xf0, 0x98, 0x4e, 0x5d, 0xcf, 0x04, 0xaa, 0x77, 0x34, 0xfc, 0xb4, 0x5f, 0x3d, 0x9f, 0x10, 0x1f, + 0x20, 0x70, 0xc8, 0x2a, 0x0e, 0xe5, 0x98, 0x38, 0x5d, 0x2a, 0x1c, 0x25, 0x3c, 0x94, 0xbb, 0x12, + 0x82, 0x35, 0xc6, 0x7c, 0x1a, 0x0a, 0x52, 0x0c, 0xbf, 0x7b, 0x19, 0x2d, 0x40, 0x16, 0x93, 0x7b, + 0xd2, 0xaa, 0x59, 0x2c, 0x7e, 0xc6, 0xee, 0x83, 0x1d, 0x80, 0x9b, 0xd4, 0x0f, 0x42, 0x68, 0x1d, + 0xe6, 0x83, 0x4b, 0x31, 0x79, 0x57, 0x87, 0x71, 0x89, 0x93, 0x68, 0x3c, 0x48, 0x6f, 0xbe, 0x05, + 0x45, 0x79, 0x9f, 0x8b, 0x62, 0x28, 0x2a, 0xbc, 0x8c, 0x07, 0x14, 0x5e, 0x41, 0x35, 0x95, 0x19, + 0x57, 0x4d, 0xc5, 0xcc, 0x75, 0xa0, 0xac, 0x78, 0x83, 0x52, 0x33, 0x95, 0x86, 0x67, 0xa1, 0x10, + 0x98, 0xa9, 0xb5, 0x84, 0x2d, 0x46, 0x20, 0x08, 0x87, 0x14, 0x31, 0x6d, 0x87, 0x90, 0xa8, 0x4d, + 0xd2, 0x29, 0x8b, 0xd5, 0x91, 0x99, 0x07, 0xd7, 0x91, 0x31, 0x4d, 0x3f, 0x80, 0xca, 0xb8, 0xbe, + 0xe4, 0x11, 0xaa, 0xa7, 0xf4, 0xa6, 0x98, 0xef, 0x1b, 0xb0, 0x10, 0x97, 0x94, 0xfe, 0xf8, 0xd2, + 0x2b, 0x39, 0xbb, 0x6e, 0x8e, 0xed, 0xc8, 0x2f, 0x0c, 0x58, 0x4a, 0x2c, 0x6d, 0xa2, 0x13, 0x9f, + 0xc0, 0xa8, 0xb8, 0x73, 0x64, 0x27, 0x70, 0x8e, 0x3f, 0x67, 0xa0, 0x7c, 0x8b, 0xec, 0x53, 0x27, + 0x88, 0x54, 0xf4, 0x7d, 0x28, 0xb5, 0x89, 0xdf, 0x3c, 0x94, 0xd0, 0xa0, 0xc7, 0x6a, 0xa4, 0xbb, + 0x36, 0x12, 0x92, 0x6a, 0xdb, 0x91, 0x98, 0x1b, 0xae, 0xcf, 0x7a, 0xf5, 0x73, 0xda, 0xa4, 0x52, + 0x0c, 0x83, 0xe3, 0xda, 0x64, 0x63, 0x2c, 0xbf, 0x6f, 0xbc, 0xdb, 0x11, 0x05, 0xe0, 0xe4, 0xfd, + 0x78, 0xc2, 0x84, 0x58, 0x56, 0x8b, 0x1a, 0xe3, 0xed, 0x01, 0xf9, 0x78, 0x48, 0xe3, 0xf2, 0xcb, + 0xb0, 0x30, 0x68, 0xbc, 0xc8, 0x3f, 0x61, 0x56, 0x54, 0x89, 0x70, 0x09, 0xf2, 0x32, 0x4f, 0xa9, + 0xc3, 0xc1, 0xea, 0xe3, 0x7a, 0xe6, 0x9a, 0x21, 0xd3, 0xeb, 0x38, 0x43, 0x1e, 0x53, 0x7a, 0x4d, + 0x88, 0x7f, 0xc8, 0xf4, 0xfa, 0x3b, 0x03, 0x72, 0xb2, 0xb5, 0x79, 0x0b, 0x0a, 0x62, 0xff, 0x2c, + 0xe2, 0x13, 0x69, 0x57, 0xea, 0xa6, 0x5a, 0x70, 0x6f, 0x53, 0x9f, 0x44, 0xde, 0x16, 0x40, 0x70, + 0x28, 0x11, 0x61, 0xc8, 0xdb, 0x3e, 0x6d, 0x07, 0x07, 0xf9, 0xdc, 0x58, 0xd1, 0x7a, 0xa4, 0x53, + 0xc3, 0xe4, 0xde, 0x8d, 0x77, 0x7d, 0xea, 0x8a, 0xc3, 0x88, 0x42, 0x63, 0x4b, 0xc8, 0xc0, 0x4a, + 0x94, 0xf9, 0x4f, 0x03, 0x42, 0x55, 0xc2, 0xf9, 0x39, 0x75, 0x0e, 0x6e, 0xd9, 0xee, 0x91, 0xde, + 0xd6, 0xd0, 0x9c, 0x3d, 0x0d, 0xc7, 0x21, 0xc5, 0xa8, 0xeb, 0x21, 0x33, 0xd9, 0xf5, 0x20, 0x14, + 0x36, 0x3d, 0xd7, 0xb7, 0xdd, 0xee, 0x50, 0xb4, 0x6d, 0x68, 0x38, 0x0e, 0x29, 0x44, 0x49, 0xc7, + 0x68, 0x9b, 0xd8, 0xae, 0xed, 0xb6, 0xc4, 0x22, 0x36, 0xbc, 0xae, 0xeb, 0xcb, 0xda, 0x46, 0x97, + 0x74, 0x78, 0x08, 0x8b, 0x47, 0x70, 0x98, 0xff, 0xca, 0x41, 0x49, 0xac, 0x39, 0xb8, 0xe7, 0x5e, + 0x84, 0xb2, 0x13, 0xf7, 0x02, 0xbd, 0xf6, 0xf3, 0xda, 0x94, 0x64, 0x5c, 0xe3, 0x24, 0xad, 0x60, + 0x3e, 0x88, 0xdf, 0xd0, 0x7a, 0x0f, 0x42, 0xe6, 0x64, 0x75, 0x90, 0xa4, 0x15, 0xd9, 0xeb, 0x9e, + 0x88, 0x0f, 0x5d, 0xe3, 0x85, 0x47, 0xf4, 0x86, 0x00, 0x62, 0x85, 0x43, 0xdb, 0x70, 0x8e, 0x38, + 0x8e, 0x77, 0x4f, 0x02, 0xeb, 0x9e, 0x77, 0xd4, 0x26, 0xec, 0x88, 0xcb, 0xb1, 0x44, 0xa1, 0xfe, + 0x05, 0xcd, 0x72, 0x6e, 0x7d, 0x98, 0x04, 0x8f, 0xe2, 0x1b, 0x75, 0x6c, 0xb9, 0x09, 0x8f, 0xed, + 0x10, 0x96, 0x06, 0x40, 0x32, 0xca, 0xf5, 0x8c, 0xe0, 0xaa, 0x96, 0xb3, 0x84, 0x47, 0xd0, 0x9c, + 0x8e, 0x81, 0xe3, 0x91, 0x12, 0xd1, 0x75, 0x98, 0x13, 0x9e, 0xec, 0x75, 0xfd, 0xa0, 0x82, 0xcf, + 0xcb, 0xe3, 0x46, 0x27, 0xfd, 0xea, 0xdc, 0xed, 0x04, 0x06, 0x0f, 0x50, 0x8a, 0xcd, 0x75, 0xec, + 0xb6, 0xed, 0x57, 0x66, 0x24, 0x4b, 0xb8, 0xb9, 0xb7, 0x04, 0x10, 0x2b, 0x5c, 0xc2, 0x03, 0x0b, + 0x67, 0x7a, 0xe0, 0x06, 0x2c, 0x72, 0xea, 0x5a, 0x5b, 0xae, 0x2d, 0x0a, 0xc9, 0x1b, 0xc7, 0xb2, + 0x3e, 0x2f, 0xc9, 0x83, 0x38, 0x2f, 0x8a, 0xeb, 0xbd, 0x41, 0x24, 0x1e, 0xa6, 0x37, 0xff, 0x94, + 0x05, 0xa4, 0x5a, 0x1f, 0x4b, 0x15, 0x65, 0x2a, 0x2f, 0x8a, 0x06, 0x4d, 0xb7, 0x4e, 0xc6, 0x40, + 0x83, 0xa6, 0xbb, 0xa6, 0x00, 0x8f, 0xb6, 0xa1, 0xa8, 0xf2, 0x53, 0x14, 0x73, 0x6b, 0x9a, 0xb8, + 0xb8, 0x13, 0x20, 0x4e, 0xfb, 0xd5, 0xe5, 0x84, 0x9a, 0x10, 0x23, 0x9b, 0xe7, 0x48, 0x02, 0xba, + 0x02, 0x40, 0x3a, 0x76, 0x7c, 0x7c, 0x5a, 0x8c, 0x86, 0x68, 0xd1, 0x20, 0x04, 0xc7, 0xa8, 0xd0, + 0x2b, 0x90, 0xf3, 0x1f, 0xae, 0xc1, 0x2d, 0xc8, 0xfe, 0x5d, 0xb4, 0xb3, 0x52, 0x82, 0xd0, 0x2e, + 0x83, 0x82, 0x0b, 0xb3, 0x74, 0x6f, 0x1a, 0x6a, 0xdf, 0x0c, 0x31, 0x38, 0x46, 0x85, 0xbe, 0x09, + 0x85, 0x03, 0x5d, 0xcf, 0xca, 0xd3, 0x4d, 0x9d, 0x67, 0x83, 0x2a, 0x58, 0x4d, 0x70, 0x82, 0x2f, + 0x1c, 0x4a, 0x43, 0x5f, 0x85, 0x12, 0xef, 0xee, 0x87, 0x25, 0x80, 0x72, 0x89, 0xf0, 0xbe, 0xdd, + 0x8b, 0x50, 0x38, 0x4e, 0x67, 0xbe, 0x03, 0xc5, 0x6d, 0xbb, 0xc9, 0x3c, 0xd9, 0x92, 0x3f, 0x03, + 0x33, 0x3c, 0xd1, 0x6f, 0x86, 0x27, 0x19, 0xb8, 0x6a, 0x80, 0x17, 0x3e, 0xea, 0x12, 0xd7, 0x53, + 0x5d, 0x65, 0x3e, 0xf2, 0xd1, 0xd7, 0x05, 0x10, 0x2b, 0xdc, 0xf5, 0x25, 0x51, 0x65, 0xfc, 0xf8, + 0xa3, 0xea, 0xd4, 0x07, 0x1f, 0x55, 0xa7, 0x3e, 0xfc, 0x48, 0x57, 0x1c, 0xbf, 0x07, 0x80, 0x9d, + 0xfd, 0xef, 0xd2, 0xa6, 0xca, 0xdd, 0xa9, 0xa6, 0xac, 0xc1, 0x70, 0x5f, 0x4e, 0x59, 0x33, 0x03, + 0x95, 0x63, 0x0c, 0x87, 0x13, 0x94, 0x68, 0x0d, 0x8a, 0xe1, 0xfc, 0x54, 0xfb, 0xc7, 0x62, 0xe0, + 0x6f, 0xe1, 0x90, 0x15, 0x47, 0x34, 0x89, 0x8b, 0x24, 0x77, 0xe6, 0x45, 0x52, 0x87, 0x6c, 0xd7, + 0xb6, 0xf4, 0xfc, 0xe2, 0x52, 0x70, 0x91, 0xdf, 0xd9, 0x6a, 0x9c, 0xf6, 0xab, 0x4f, 0x8c, 0x7b, + 0xb6, 0xf0, 0x7b, 0x1d, 0xca, 0x6b, 0x77, 0xb6, 0x1a, 0x58, 0x30, 0x8f, 0xca, 0x6a, 0xd3, 0x13, + 0x66, 0xb5, 0x2b, 0x00, 0xad, 0x68, 0x0a, 0xa4, 0x92, 0x46, 0xe8, 0x88, 0xb1, 0xe9, 0x4f, 0x8c, + 0x0a, 0x71, 0x58, 0x6c, 0x32, 0x4a, 0x82, 0x69, 0x0c, 0xf7, 0x49, 0x5b, 0xcd, 0x95, 0x27, 0x8b, + 0x89, 0x0b, 0x5a, 0xcd, 0xe2, 0xc6, 0xa0, 0x30, 0x3c, 0x2c, 0x1f, 0x79, 0xb0, 0x68, 0xe9, 0x86, + 0x3d, 0x52, 0x5a, 0x9c, 0x58, 0xa9, 0xcc, 0x58, 0x8d, 0x41, 0x41, 0x78, 0x58, 0x36, 0xfa, 0x0e, + 0x2c, 0x07, 0xc0, 0xe1, 0xa9, 0x89, 0xcc, 0xfa, 0xd9, 0xfa, 0xca, 0x49, 0xbf, 0xba, 0xdc, 0x18, + 0x4b, 0x85, 0x1f, 0x20, 0x01, 0x59, 0x30, 0xed, 0xa8, 0x2a, 0xb9, 0x24, 0x2b, 0x9b, 0xaf, 0xa5, + 0x5b, 0x45, 0xe4, 0xfd, 0xb5, 0x78, 0x75, 0x1c, 0x4e, 0xc0, 0x74, 0x61, 0xac, 0x65, 0xa3, 0x77, + 0xa1, 0x44, 0x5c, 0xd7, 0xf3, 0x89, 0x9a, 0xe3, 0xcc, 0x4a, 0x55, 0xeb, 0x13, 0xab, 0x5a, 0x8f, + 0x64, 0x0c, 0x54, 0xe3, 0x31, 0x0c, 0x8e, 0xab, 0x42, 0xf7, 0x60, 0xde, 0xbb, 0xe7, 0x52, 0x86, + 0xe9, 0x01, 0x65, 0xd4, 0x6d, 0x52, 0x5e, 0x29, 0x4b, 0xed, 0x57, 0x53, 0x6a, 0x4f, 0x30, 0x47, + 0x2e, 0x9d, 0x84, 0x73, 0x3c, 0xa8, 0x05, 0xd5, 0x44, 0x6e, 0x75, 0x89, 0x63, 0x7f, 0x8f, 0x32, + 0x5e, 0x99, 0x8b, 0x46, 0xff, 0x9b, 0x21, 0x14, 0xc7, 0x28, 0x50, 0x17, 0xca, 0xed, 0xf8, 0x95, + 0x51, 0x59, 0x94, 0x66, 0x5e, 0x4b, 0x67, 0xe6, 0xf0, 0xa5, 0x16, 0x95, 0x41, 0x09, 0x1c, 0x4e, + 0x6a, 0x59, 0x7e, 0x01, 0x4a, 0x0f, 0xd9, 0x21, 0x88, 0x0e, 0x63, 0xf0, 0x40, 0x26, 0xea, 0x30, + 0xfe, 0x90, 0x81, 0xb9, 0xe4, 0x36, 0x0e, 0x5c, 0x87, 0xf9, 0x54, 0xd7, 0x61, 0xd0, 0xcb, 0x1a, + 0x63, 0xdf, 0x80, 0x82, 0xfc, 0x9c, 0x1d, 0x9b, 0x9f, 0x75, 0x1a, 0xcc, 0x3d, 0x4a, 0x1a, 0xac, + 0x01, 0x88, 0x62, 0x85, 0x79, 0x8e, 0x43, 0x99, 0x1e, 0xab, 0xa9, 0xb7, 0x9e, 0x10, 0x8a, 0x63, + 0x14, 0xa2, 0xa4, 0xde, 0x77, 0xbc, 0xe6, 0x91, 0xdc, 0x82, 0x20, 0x7a, 0x65, 0xee, 0x2b, 0xa8, + 0x92, 0xba, 0x3e, 0x84, 0xc5, 0x23, 0x38, 0xcc, 0x1e, 0x9c, 0xdf, 0x25, 0x4c, 0x14, 0x39, 0x51, + 0xa4, 0xc8, 0x9e, 0xe5, 0xed, 0xa1, 0x8e, 0xe8, 0xd2, 0xa4, 0x11, 0x17, 0x6d, 0x7e, 0x04, 0x8b, + 0xba, 0x22, 0xf3, 0x2f, 0x06, 0x5c, 0x18, 0xa9, 0xfb, 0x73, 0xe8, 0xc8, 0xde, 0x4e, 0x76, 0x64, + 0x2f, 0xa6, 0x1c, 0x0a, 0x8f, 0xb2, 0x76, 0x4c, 0x7f, 0x36, 0x03, 0xf9, 0x5d, 0x51, 0x09, 0x9b, + 0x9f, 0x18, 0x30, 0x2b, 0x7f, 0x4d, 0x32, 0x93, 0xaf, 0x26, 0x9f, 0x6a, 0x8a, 0x8f, 0xef, 0x99, + 0xe6, 0x71, 0x0c, 0xed, 0xdf, 0x37, 0x20, 0x39, 0x0d, 0x47, 0x2f, 0xab, 0x10, 0x30, 0xc2, 0x71, + 0xf5, 0x84, 0xee, 0xff, 0xd2, 0xb8, 0x96, 0xf4, 0x5c, 0xaa, 0x69, 0xe5, 0xb3, 0x50, 0xc4, 0x9e, + 0xe7, 0xef, 0x12, 0xff, 0x90, 0x8b, 0xbd, 0xeb, 0x88, 0x1f, 0x7a, 0x7b, 0xe5, 0xde, 0x49, 0x0c, + 0x56, 0x70, 0xf3, 0xa7, 0x06, 0x5c, 0x18, 0xfb, 0x02, 0x27, 0xb2, 0x48, 0x33, 0xfc, 0xd2, 0x2b, + 0x0a, 0x1d, 0x39, 0xa2, 0xc3, 0x31, 0x2a, 0xd1, 0x4b, 0x26, 0x9e, 0xed, 0x06, 0x7b, 0xc9, 0x84, + 0x36, 0x9c, 0xa4, 0x35, 0xff, 0x91, 0x01, 0xfd, 0xe4, 0xf5, 0x5f, 0x76, 0xfa, 0xa7, 0x07, 0x1e, + 0xdc, 0xe6, 0x92, 0x0f, 0x6e, 0xe1, 0xeb, 0x5a, 0xec, 0xc5, 0x29, 0xfb, 0xe0, 0x17, 0x27, 0xf4, + 0x7c, 0xf8, 0x88, 0xa5, 0x7c, 0x68, 0x25, 0xf9, 0x88, 0x75, 0xda, 0xaf, 0xce, 0x6a, 0xe1, 0xc9, + 0x47, 0xad, 0x37, 0x61, 0xc6, 0xa2, 0x3e, 0xb1, 0x1d, 0xd5, 0x17, 0xa6, 0x7e, 0x96, 0x51, 0xc2, + 0x1a, 0x8a, 0xb5, 0x5e, 0x12, 0x36, 0xe9, 0x0f, 0x1c, 0x08, 0x14, 0x09, 0xbb, 0xe9, 0x59, 0xaa, + 0x23, 0xc9, 0x47, 0x09, 0x7b, 0xc3, 0xb3, 0x28, 0x96, 0x18, 0xf3, 0x03, 0x03, 0x4a, 0x4a, 0xd2, + 0x06, 0xe9, 0x72, 0x8a, 0x2e, 0x87, 0xab, 0x50, 0xc7, 0x7d, 0x21, 0xfe, 0x5a, 0x79, 0xda, 0xaf, + 0x16, 0x25, 0x99, 0x6c, 0x66, 0x46, 0xbc, 0xca, 0x65, 0xce, 0xd8, 0xa3, 0x27, 0x21, 0x2f, 0x03, + 0x48, 0x6f, 0x66, 0xf4, 0xec, 0x2a, 0x80, 0x58, 0xe1, 0xcc, 0xcf, 0x32, 0x50, 0x4e, 0x2c, 0x2e, + 0x45, 0x5f, 0x10, 0x8e, 0x50, 0x33, 0x29, 0xc6, 0xf2, 0xe3, 0xff, 0xe4, 0xa0, 0xaf, 0xaf, 0xe9, + 0x47, 0xb9, 0xbe, 0xbe, 0x05, 0xd3, 0x4d, 0xb1, 0x47, 0xc1, 0x7f, 0x66, 0x2e, 0x4f, 0x72, 0x9c, + 0x72, 0x77, 0x23, 0x6f, 0x94, 0x9f, 0x1c, 0x6b, 0x81, 0xe8, 0x26, 0x2c, 0x32, 0xea, 0xb3, 0xde, + 0xfa, 0x81, 0x4f, 0x59, 0x7c, 0x98, 0x90, 0x8f, 0xaa, 0x6f, 0x3c, 0x48, 0x80, 0x87, 0x79, 0xcc, + 0x7d, 0x98, 0xbd, 0x4d, 0xf6, 0x9d, 0xf0, 0xa1, 0x11, 0x43, 0xd9, 0x76, 0x9b, 0x4e, 0xd7, 0xa2, + 0x2a, 0xa1, 0x07, 0xd9, 0x2b, 0x08, 0xda, 0xad, 0x38, 0xf2, 0xb4, 0x5f, 0x3d, 0x97, 0x00, 0xa8, + 0x97, 0x35, 0x9c, 0x14, 0x61, 0x3a, 0x90, 0xfb, 0x1c, 0x3b, 0xc9, 0x6f, 0x43, 0x31, 0xaa, 0xf5, + 0x1f, 0xb3, 0x4a, 0xf3, 0x6d, 0x28, 0x08, 0x8f, 0x0f, 0x7a, 0xd4, 0x33, 0xaa, 0xa4, 0x64, 0xed, + 0x95, 0x49, 0x53, 0x7b, 0xc9, 0xe7, 0xea, 0x3b, 0x1d, 0xeb, 0x11, 0x9f, 0xab, 0x33, 0x8f, 0x72, + 0xf3, 0x65, 0x27, 0xbc, 0xf9, 0xae, 0x80, 0xfa, 0x4b, 0x8f, 0xb8, 0x64, 0x54, 0x01, 0x11, 0xbb, + 0x64, 0xe2, 0xf7, 0x7f, 0xec, 0x85, 0xe1, 0x47, 0x06, 0x80, 0x1c, 0xe5, 0xc9, 0x31, 0x52, 0x8a, + 0x3f, 0x46, 0xdc, 0x81, 0x69, 0x4f, 0x79, 0xa4, 0x7a, 0xb2, 0x9e, 0x70, 0x5e, 0x1c, 0x06, 0x92, + 0xf2, 0x49, 0xac, 0x85, 0xd5, 0x5f, 0xfd, 0xf8, 0xfe, 0xca, 0xd4, 0x27, 0xf7, 0x57, 0xa6, 0x3e, + 0xbd, 0xbf, 0x32, 0xf5, 0xde, 0xc9, 0x8a, 0xf1, 0xf1, 0xc9, 0x8a, 0xf1, 0xc9, 0xc9, 0x8a, 0xf1, + 0xe9, 0xc9, 0x8a, 0xf1, 0xd9, 0xc9, 0x8a, 0xf1, 0xc1, 0xdf, 0x56, 0xa6, 0xde, 0x7c, 0x2a, 0xcd, + 0x5f, 0x25, 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0xf8, 0xda, 0x63, 0x4c, 0x51, 0x29, 0x00, 0x00, } func (m *APIGroup) Marshal() (dAtA []byte, err error) { @@ -1983,6 +1986,16 @@ func (m *DeleteOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.IgnoreStoreReadErrorWithClusterBreakingPotential != nil { + i-- + if *m.IgnoreStoreReadErrorWithClusterBreakingPotential { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + } if len(m.DryRun) > 0 { for iNdEx := len(m.DryRun) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.DryRun[iNdEx]) @@ -3773,6 +3786,9 @@ func (m *DeleteOptions) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + if m.IgnoreStoreReadErrorWithClusterBreakingPotential != nil { + n += 2 + } return n } @@ -4506,6 +4522,7 @@ func (this *DeleteOptions) String() string { `OrphanDependents:` + valueToStringGenerated(this.OrphanDependents) + `,`, `PropagationPolicy:` + valueToStringGenerated(this.PropagationPolicy) + `,`, `DryRun:` + fmt.Sprintf("%v", this.DryRun) + `,`, + `IgnoreStoreReadErrorWithClusterBreakingPotential:` + valueToStringGenerated(this.IgnoreStoreReadErrorWithClusterBreakingPotential) + `,`, `}`, }, "") return s @@ -6456,6 +6473,27 @@ func (m *DeleteOptions) Unmarshal(dAtA []byte) error { } m.DryRun = append(m.DryRun, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IgnoreStoreReadErrorWithClusterBreakingPotential", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.IgnoreStoreReadErrorWithClusterBreakingPotential = &b default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto index 18dd0b067cc43..7d01a6e5f340d 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto @@ -315,6 +315,23 @@ message DeleteOptions { // +optional // +listType=atomic repeated string dryRun = 5; + + // IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, + // will trigger an unsafe deletion of the resource in case the + // normal deletion flow fails with a corrupt object error. + // A resource is considered corrupt if it can not be retrieved from + // the underlying storage because of a) its data can not be transformed + // successfully, or b) it fails to decode into an object. + // NOTE: unsafe deletion ignores finalzer constraints, skips + // precondition checks, or any post deletion hooks and + // removes the object from the storage. + // WARNING: This will break the cluster if the resource has any + // dependencies. Use only if you REALLY know what you are doing. + // WARNING: Vendor(s) will most likely consider enablement of this + // option to be in violation of the support of their product. + // The default value is nil, and the user must opt in to enable it + // +optional + optional bool ignoreStoreReadErrorWithClusterBreakingPotential = 6; } // Duration is a wrapper around time.Duration which supports correct diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go index 1fa37215cd074..5a8a518800b30 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go @@ -129,6 +129,7 @@ var map_DeleteOptions = map[string]string{ "orphanDependents": "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.", "propagationPolicy": "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.", "dryRun": "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", + "ignoreStoreReadErrorWithClusterBreakingPotential": "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", } func (DeleteOptions) SwaggerDoc() map[string]string { diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go index afe01ed5a44a5..82e2722404c57 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go @@ -339,6 +339,13 @@ func autoConvert_url_Values_To_v1_DeleteOptions(in *url.Values, out *DeleteOptio } else { out.DryRun = nil } + if values, ok := map[string][]string(*in)["ignoreStoreReadErrorWithClusterBreakingPotential"]; ok && len(values) > 0 { + if err := runtime.Convert_Slice_string_To_Pointer_bool(&values, &out.IgnoreStoreReadErrorWithClusterBreakingPotential, s); err != nil { + return err + } + } else { + out.IgnoreStoreReadErrorWithClusterBreakingPotential = nil + } return nil } diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go index 90cc54a7e7655..6b0d0dfee9608 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go @@ -290,6 +290,11 @@ func (in *DeleteOptions) DeepCopyInto(out *DeleteOptions) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.IgnoreStoreReadErrorWithClusterBreakingPotential != nil { + in, out := &in.IgnoreStoreReadErrorWithClusterBreakingPotential, &out.IgnoreStoreReadErrorWithClusterBreakingPotential + *out = new(bool) + **out = **in + } return } diff --git a/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go b/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go index c5c674fcd53a0..12b20e35ced41 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/internal/internal.go @@ -13470,6 +13470,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: gracePeriodSeconds type: scalar: numeric + - name: ignoreStoreReadErrorWithClusterBreakingPotential + type: + scalar: boolean - name: kind type: scalar: string diff --git a/staging/src/k8s.io/client-go/applyconfigurations/meta/v1/deleteoptions.go b/staging/src/k8s.io/client-go/applyconfigurations/meta/v1/deleteoptions.go index a3b2b4ea3ff7d..ab398ef563420 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/meta/v1/deleteoptions.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/meta/v1/deleteoptions.go @@ -25,12 +25,13 @@ import ( // DeleteOptionsApplyConfiguration represents a declarative configuration of the DeleteOptions type for use // with apply. type DeleteOptionsApplyConfiguration struct { - TypeMetaApplyConfiguration `json:",inline"` - GracePeriodSeconds *int64 `json:"gracePeriodSeconds,omitempty"` - Preconditions *PreconditionsApplyConfiguration `json:"preconditions,omitempty"` - OrphanDependents *bool `json:"orphanDependents,omitempty"` - PropagationPolicy *metav1.DeletionPropagation `json:"propagationPolicy,omitempty"` - DryRun []string `json:"dryRun,omitempty"` + TypeMetaApplyConfiguration `json:",inline"` + GracePeriodSeconds *int64 `json:"gracePeriodSeconds,omitempty"` + Preconditions *PreconditionsApplyConfiguration `json:"preconditions,omitempty"` + OrphanDependents *bool `json:"orphanDependents,omitempty"` + PropagationPolicy *metav1.DeletionPropagation `json:"propagationPolicy,omitempty"` + DryRun []string `json:"dryRun,omitempty"` + IgnoreStoreReadErrorWithClusterBreakingPotential *bool `json:"ignoreStoreReadErrorWithClusterBreakingPotential,omitempty"` } // DeleteOptionsApplyConfiguration constructs a declarative configuration of the DeleteOptions type for use with @@ -99,3 +100,11 @@ func (b *DeleteOptionsApplyConfiguration) WithDryRun(values ...string) *DeleteOp } return b } + +// WithIgnoreStoreReadErrorWithClusterBreakingPotential sets the IgnoreStoreReadErrorWithClusterBreakingPotential field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the IgnoreStoreReadErrorWithClusterBreakingPotential field is set to the value of the last call. +func (b *DeleteOptionsApplyConfiguration) WithIgnoreStoreReadErrorWithClusterBreakingPotential(value bool) *DeleteOptionsApplyConfiguration { + b.IgnoreStoreReadErrorWithClusterBreakingPotential = &value + return b +} diff --git a/staging/src/k8s.io/code-generator/examples/apiserver/openapi/zz_generated.openapi.go b/staging/src/k8s.io/code-generator/examples/apiserver/openapi/zz_generated.openapi.go index 2c1d8713b8a79..0e88aae2a9040 100644 --- a/staging/src/k8s.io/code-generator/examples/apiserver/openapi/zz_generated.openapi.go +++ b/staging/src/k8s.io/code-generator/examples/apiserver/openapi/zz_generated.openapi.go @@ -731,6 +731,13 @@ func schema_pkg_apis_meta_v1_DeleteOptions(ref common.ReferenceCallback) common. }, }, }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + SchemaProps: spec.SchemaProps{ + Description: "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + Type: []string{"boolean"}, + Format: "", + }, + }, }, }, }, diff --git a/staging/src/k8s.io/kube-aggregator/pkg/generated/openapi/zz_generated.openapi.go b/staging/src/k8s.io/kube-aggregator/pkg/generated/openapi/zz_generated.openapi.go index 1163748c3593c..a4b6473e67771 100644 --- a/staging/src/k8s.io/kube-aggregator/pkg/generated/openapi/zz_generated.openapi.go +++ b/staging/src/k8s.io/kube-aggregator/pkg/generated/openapi/zz_generated.openapi.go @@ -731,6 +731,13 @@ func schema_pkg_apis_meta_v1_DeleteOptions(ref common.ReferenceCallback) common. }, }, }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + SchemaProps: spec.SchemaProps{ + Description: "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + Type: []string{"boolean"}, + Format: "", + }, + }, }, }, }, diff --git a/staging/src/k8s.io/sample-apiserver/pkg/generated/openapi/zz_generated.openapi.go b/staging/src/k8s.io/sample-apiserver/pkg/generated/openapi/zz_generated.openapi.go index 5359248daf41d..176075714b244 100644 --- a/staging/src/k8s.io/sample-apiserver/pkg/generated/openapi/zz_generated.openapi.go +++ b/staging/src/k8s.io/sample-apiserver/pkg/generated/openapi/zz_generated.openapi.go @@ -729,6 +729,13 @@ func schema_pkg_apis_meta_v1_DeleteOptions(ref common.ReferenceCallback) common. }, }, }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + SchemaProps: spec.SchemaProps{ + Description: "IgnoreStoreReadErrorWithClusterBreakingPotential, if set to true, will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage because of a) its data can not be transformed successfully, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalzer constraints, skips precondition checks, or any post deletion hooks and removes the object from the storage. WARNING: This will break the cluster if the resource has any dependencies. Use only if you REALLY know what you are doing. WARNING: Vendor(s) will most likely consider enablement of this option to be in violation of the support of their product. The default value is nil, and the user must opt in to enable it", + Type: []string{"boolean"}, + Format: "", + }, + }, }, }, }, From a382f2f67ec295a6da1746cfb11b23459d88e82f Mon Sep 17 00:00:00 2001 From: Abu Kashem Date: Mon, 7 Oct 2024 10:13:22 -0400 Subject: [PATCH 03/14] add validation for the new delete option add validation for the new field in the delete options ignoreStoreReadErrorWithClusterBreakingPotential --- .../pkg/apis/meta/v1/validation/validation.go | 28 ++++++ .../meta/v1/validation/validation_test.go | 94 +++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go index 3eba5ba541727..05bd21332da92 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation.go @@ -26,6 +26,8 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" + + "k8s.io/utils/ptr" ) // LabelSelectorValidationOptions is a struct that can be passed to ValidateLabelSelector to record the validate options @@ -165,6 +167,7 @@ func ValidateDeleteOptions(options *metav1.DeleteOptions) field.ErrorList { allErrs = append(allErrs, field.NotSupported(field.NewPath("propagationPolicy"), options.PropagationPolicy, []string{string(metav1.DeletePropagationForeground), string(metav1.DeletePropagationBackground), string(metav1.DeletePropagationOrphan), "nil"})) } allErrs = append(allErrs, ValidateDryRun(field.NewPath("dryRun"), options.DryRun)...) + allErrs = append(allErrs, ValidateIgnoreStoreReadError(field.NewPath("ignoreStoreReadErrorWithClusterBreakingPotential"), options)...) return allErrs } @@ -357,3 +360,28 @@ func isValidConditionReason(value string) []string { } return nil } + +// ValidateIgnoreStoreReadError validates that delete options are valid when +// ignoreStoreReadErrorWithClusterBreakingPotential is enabled +func ValidateIgnoreStoreReadError(fldPath *field.Path, options *metav1.DeleteOptions) field.ErrorList { + allErrs := field.ErrorList{} + if ignore := ptr.Deref[bool](options.IgnoreStoreReadErrorWithClusterBreakingPotential, false); ignore { + if len(options.DryRun) > 0 { + allErrs = append(allErrs, field.Invalid(fldPath, ignore, "ignoreStoreReadErrorWithClusterBreakingPotential and dryRun cannot be both set")) + } + if options.PropagationPolicy != nil { + allErrs = append(allErrs, field.Invalid(fldPath, ignore, "ignoreStoreReadErrorWithClusterBreakingPotential and propagationPolicy cannot be both set")) + } + //nolint:staticcheck // Keep validation for deprecated OrphanDependents option until it's being removed + if options.OrphanDependents != nil { + allErrs = append(allErrs, field.Invalid(fldPath, ignore, "ignoreStoreReadErrorWithClusterBreakingPotential and orphanDependents cannot be both set")) + } + if options.GracePeriodSeconds != nil { + allErrs = append(allErrs, field.Invalid(fldPath, ignore, "ignoreStoreReadErrorWithClusterBreakingPotential and gracePeriodSeconds cannot be both set")) + } + if options.Preconditions != nil { + allErrs = append(allErrs, field.Invalid(fldPath, ignore, "ignoreStoreReadErrorWithClusterBreakingPotential and preconditions cannot be both set")) + } + } + return allErrs +} diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation_test.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation_test.go index 3296d4f61b2c2..ea8d0aae2bfc5 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation_test.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation_test.go @@ -21,9 +21,13 @@ import ( "strings" "testing" + "github.com/google/go-cmp/cmp" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/validation/field" + + "k8s.io/utils/ptr" ) func TestValidateLabels(t *testing.T) { @@ -132,6 +136,96 @@ func boolPtr(b bool) *bool { return &b } +func TestValidateDeleteOptionsWithIgnoreStoreReadError(t *testing.T) { + fieldPath := field.NewPath("ignoreStoreReadErrorWithClusterBreakingPotential") + tests := []struct { + name string + opts metav1.DeleteOptions + expectedErrors field.ErrorList + }{ + { + name: "option is nil", + opts: metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: nil, + DryRun: []string{"All"}, + }, + expectedErrors: field.ErrorList{}, + }, + { + name: "option is false, PropagationPolicy is set", + opts: metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](false), + DryRun: []string{"All"}, + PropagationPolicy: ptr.To[metav1.DeletionPropagation](metav1.DeletePropagationBackground), + GracePeriodSeconds: ptr.To[int64](0), + Preconditions: &metav1.Preconditions{}, + }, + expectedErrors: field.ErrorList{}, + }, + { + name: "option is false, OrphanDependents is set", + opts: metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](false), + DryRun: []string{"All"}, + //nolint:staticcheck // until it's being removed + OrphanDependents: ptr.To[bool](true), + GracePeriodSeconds: ptr.To[int64](0), + Preconditions: &metav1.Preconditions{}, + }, + expectedErrors: field.ErrorList{}, + }, + { + name: "option is true, PropagationPolicy is set", + opts: metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + DryRun: []string{"All"}, + PropagationPolicy: ptr.To[metav1.DeletionPropagation](metav1.DeletePropagationBackground), + GracePeriodSeconds: ptr.To[int64](0), + Preconditions: &metav1.Preconditions{}, + }, + expectedErrors: field.ErrorList{ + field.Invalid(fieldPath, true, "ignoreStoreReadErrorWithClusterBreakingPotential and dryRun cannot be both set"), + field.Invalid(fieldPath, true, "ignoreStoreReadErrorWithClusterBreakingPotential and propagationPolicy cannot be both set"), + field.Invalid(fieldPath, true, "ignoreStoreReadErrorWithClusterBreakingPotential and gracePeriodSeconds cannot be both set"), + field.Invalid(fieldPath, true, "ignoreStoreReadErrorWithClusterBreakingPotential and preconditions cannot be both set"), + }, + }, + { + name: "option is true, OrphanDependents is set", + opts: metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + DryRun: []string{"All"}, + //nolint:staticcheck // until it's being removed + OrphanDependents: ptr.To[bool](true), + GracePeriodSeconds: ptr.To[int64](0), + Preconditions: &metav1.Preconditions{}, + }, + expectedErrors: field.ErrorList{ + field.Invalid(fieldPath, true, "ignoreStoreReadErrorWithClusterBreakingPotential and dryRun cannot be both set"), + field.Invalid(fieldPath, true, "ignoreStoreReadErrorWithClusterBreakingPotential and orphanDependents cannot be both set"), + field.Invalid(fieldPath, true, "ignoreStoreReadErrorWithClusterBreakingPotential and gracePeriodSeconds cannot be both set"), + field.Invalid(fieldPath, true, "ignoreStoreReadErrorWithClusterBreakingPotential and preconditions cannot be both set"), + }, + }, + { + name: "option is true, no other option is set", + opts: metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](false), + }, + expectedErrors: field.ErrorList{}, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + errGot := ValidateDeleteOptions(&test.opts) + if !cmp.Equal(test.expectedErrors, errGot) { + t.Errorf("expected error(s) to match, diff: %s", cmp.Diff(test.expectedErrors, errGot)) + } + }) + } +} + func TestValidPatchOptions(t *testing.T) { tests := []struct { opts metav1.PatchOptions From 887587fc903e8642b2005a620fed8b5e9973c4c5 Mon Sep 17 00:00:00 2001 From: Abu Kashem Date: Fri, 20 Sep 2024 17:36:27 -0400 Subject: [PATCH 04/14] extend storage error extend storage error: a) add a new type ErrCodeCorruptObj to represent a corrupt object: b) add a new member 'InnerErr error' to StorageError to hold the inner error --- .../k8s.io/apiserver/pkg/storage/errors.go | 56 +++++++++++++++---- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/storage/errors.go b/staging/src/k8s.io/apiserver/pkg/storage/errors.go index d67235a53aefc..9259cc7573476 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/errors.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/errors.go @@ -37,6 +37,7 @@ const ( ErrCodeInvalidObj ErrCodeUnreachable ErrCodeTimeout + ErrCodeCorruptObj ) var errCodeToMessage = map[int]string{ @@ -46,6 +47,7 @@ var errCodeToMessage = map[int]string{ ErrCodeInvalidObj: "invalid object", ErrCodeUnreachable: "server unreachable", ErrCodeTimeout: "request timeout", + ErrCodeCorruptObj: "corrupt object", } func NewKeyNotFoundError(key string, rv int64) *StorageError { @@ -82,30 +84,45 @@ func NewUnreachableError(key string, rv int64) *StorageError { func NewTimeoutError(key, msg string) *StorageError { return &StorageError{ - Code: ErrCodeTimeout, - Key: key, - AdditionalErrorMsg: msg, + Code: ErrCodeTimeout, + Key: key, + err: errors.New(msg), } } func NewInvalidObjError(key, msg string) *StorageError { return &StorageError{ - Code: ErrCodeInvalidObj, - Key: key, - AdditionalErrorMsg: msg, + Code: ErrCodeInvalidObj, + Key: key, + err: errors.New(msg), + } +} + +// NewCorruptObjError returns a new StorageError, it represents a corrupt object: +// a) object data retrieved from the storage failed to transform with the given err. +// b) the given object failed to decode with the given err +func NewCorruptObjError(key string, err error) *StorageError { + return &StorageError{ + Code: ErrCodeCorruptObj, + Key: key, + err: err, } } type StorageError struct { - Code int - Key string - ResourceVersion int64 - AdditionalErrorMsg string + Code int + Key string + ResourceVersion int64 + + // inner error + err error } +func (e *StorageError) Unwrap() error { return e.err } + func (e *StorageError) Error() string { - return fmt.Sprintf("StorageError: %s, Code: %d, Key: %s, ResourceVersion: %d, AdditionalErrorMsg: %s", - errCodeToMessage[e.Code], e.Code, e.Key, e.ResourceVersion, e.AdditionalErrorMsg) + return fmt.Sprintf("StorageError: %s, Code: %d, Key: %s, ResourceVersion: %d, err: %v", + errCodeToMessage[e.Code], e.Code, e.Key, e.ResourceVersion, e.err) } // IsNotFound returns true if and only if err is "key" not found error. @@ -138,6 +155,21 @@ func IsInvalidObj(err error) bool { return isErrCode(err, ErrCodeInvalidObj) } +// IsCorruptObject returns true if and only if: +// a) the given object data retrieved from the storage is not transformable, or +// b) the given object failed to decode properly +func IsCorruptObject(err error) bool { + if err == nil { + return false + } + var storageErr *StorageError + if !errors.As(err, &storageErr) { + return false + } + + return storageErr.Code == ErrCodeCorruptObj +} + func isErrCode(err error, code int) bool { if err == nil { return false From 7126932b13647eba802f8ea44e03523f0a2ca43d Mon Sep 17 00:00:00 2001 From: Abu Kashem Date: Fri, 20 Sep 2024 17:41:03 -0400 Subject: [PATCH 05/14] implement unsafe deletion --- .../generic/registry/corrupt_obj_deleter.go | 144 ++++++++++ .../registry/corrupt_obj_deleter_test.go | 251 ++++++++++++++++++ .../apiserver/pkg/storage/errors/storage.go | 12 + .../pkg/storage/etcd3/corrupt_obj_deleter.go | 136 ++++++++++ .../apiserver/pkg/storage/etcd3/store.go | 2 +- .../apiserver/pkg/storage/interfaces.go | 7 + 6 files changed, 551 insertions(+), 1 deletion(-) create mode 100644 staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter.go create mode 100644 staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter_test.go create mode 100644 staging/src/k8s.io/apiserver/pkg/storage/etcd3/corrupt_obj_deleter.go diff --git a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter.go b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter.go new file mode 100644 index 0000000000000..a288615034d5c --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter.go @@ -0,0 +1,144 @@ +/* +Copyright 2024 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 registry + +import ( + "context" + "fmt" + "strings" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + 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/registry/rest" + "k8s.io/apiserver/pkg/storage" + storeerr "k8s.io/apiserver/pkg/storage/errors" + + "k8s.io/klog/v2" + "k8s.io/utils/ptr" +) + +// the corrupt object deleter has the same interface as rest.GracefulDeleter +var _ rest.GracefulDeleter = &corruptObjectDeleter{} + +// NewCorruptObjectDeleter returns a deleter that can perform unsafe deletion +// of corrupt objects, it makes an attempt to perform a normal deletion flow +// first, and if the normal deletion flow fails with a corrupt object error +// then it performs the unsafe delete of the object. +// +// NOTE: it skips precondition checks, finalizer constraints, and any +// post deletion hook defined in 'AfterDelete' of the registry. +// +// WARNING: This may break the cluster if the resource being deleted has dependencies. +func NewCorruptObjectDeleter(store *Store) *corruptObjectDeleter { + return &corruptObjectDeleter{ + GracefulDeleter: store, + KeyFunc: store.KeyFunc, + NewFunc: store.NewFunc, + DefaultQualifiedResource: store.DefaultQualifiedResource, + Storage: store.Storage.Storage, + } +} + +// corruptObjectDeleter implements unsafe object deletion flow +type corruptObjectDeleter struct { + rest.GracefulDeleter + + KeyFunc func(ctx context.Context, name string) (string, error) + NewFunc func() runtime.Object + DefaultQualifiedResource schema.GroupResource + // NOTE: not holding the DryRunnableStorage wrapper, + // directly using the storage interface + Storage storage.Interface +} + +// Delete performs an unsafe deletion of the given resource from the storage. +// +// NOTE: This function should NEVER be used for any normal deletion +// flow, it is exclusively used when the delete option +// 'IgnoreStoreReadErrorWithClusterBreakingPotential' is enabled by the user. +func (s *corruptObjectDeleter) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, opts *metav1.DeleteOptions) (runtime.Object, bool, error) { + const optionName = "ignoreStoreReadErrorWithClusterBreakingPotential" + if opts == nil || !ptr.Deref[bool](opts.IgnoreStoreReadErrorWithClusterBreakingPotential, false) { + // developer error, unsafe deleter should be invoked only when + // IgnoreStoreReadErrorWithClusterBreakingPotential is true + return nil, false, apierrors.NewInternalError(fmt.Errorf("expected %s to be enabled", optionName)) + } + + key, err := s.KeyFunc(ctx, name) + if err != nil { + return nil, false, err + } + obj := s.NewFunc() + + qualifiedResource := s.qualifiedResourceFromContext(ctx) + // TODO: what if Get returns the object from cache, in this case the + // apiserver must restart for unsafe deletion to work + err = s.Storage.Get(ctx, key, storage.GetOptions{}, obj) + if err == nil || !storage.IsCorruptObject(err) { + // TODO: The Invalid error should have a field for Resource. + // After that field is added, we should fill the Resource and + // leave the Kind field empty. See the discussion in #18526. + qualifiedKind := schema.GroupKind{Group: qualifiedResource.Group, Kind: qualifiedResource.Resource} + fieldErrList := field.ErrorList{ + field.Invalid(field.NewPath(optionName), true, "it is exclusively used to delete corrupt object(s), try again by removing this option"), + } + return nil, false, apierrors.NewInvalid(qualifiedKind, name, fieldErrList) + } + + // try normal deletetion anyway, it is expected to fail + obj, deleted, err := s.GracefulDeleter.Delete(ctx, name, deleteValidation, opts) + if err == nil { + return obj, deleted, err + } + // TODO: unfortunately we can't do storage.IsCorruptObject(err), + // conversion to API error drops the inner error chain + if !strings.Contains(err.Error(), "corrupt object") { + return obj, deleted, err + } + + // TODO: at this instant, some actor may have managed to recreate this + // object by doing a delete+create, or the underlying error has resolved + // and the object is readable now + + klog.V(1).InfoS("Going to perform unsafe object deletion", "object", klog.KRef(genericapirequest.NamespaceValue(ctx), name)) + out := s.NewFunc() + storageOpts := storage.DeleteOptions{IgnoreStoreReadError: true} + // dropping preconditions, and keeping the admission + if err := s.Storage.Delete(ctx, key, out, nil, storage.ValidateObjectFunc(deleteValidation), nil, storageOpts); err != nil { + if storage.IsNotFound(err) { + // the DELETE succeeded, but we don't have the object since it's + // not retrievable from the storage, so we send a nil object + return nil, false, nil + } + return nil, false, storeerr.InterpretDeleteError(err, qualifiedResource, name) + } + // the DELETE succeeded, but we don't have the object sine it's + // not retrievable from the storage, so we send a nil objct + return nil, true, nil +} + +func (s *corruptObjectDeleter) qualifiedResourceFromContext(ctx context.Context) schema.GroupResource { + if info, ok := genericapirequest.RequestInfoFrom(ctx); ok { + return schema.GroupResource{Group: info.APIGroup, Resource: info.Resource} + } + // some implementations access storage directly and thus the context has no RequestInfo + return s.DefaultQualifiedResource +} diff --git a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter_test.go b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter_test.go new file mode 100644 index 0000000000000..cbdb1c8db64a6 --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter_test.go @@ -0,0 +1,251 @@ +/* +Copyright 2024 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 registry + +import ( + "context" + "fmt" + "strings" + "testing" + + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/apis/example" + genericapirequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/registry/rest" + "k8s.io/apiserver/pkg/storage" + + "k8s.io/utils/ptr" +) + +func TestUnsafeDeletePrecondition(t *testing.T) { + tests := []struct { + name string + err error + opts *metav1.DeleteOptions + invoked int + }{ + { + name: "no error, want: not invoked", + opts: &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + }, + }, + { + name: "corrupt object error, options is nil, want: not invoked", + err: storage.NewCorruptObjError("foo", fmt.Errorf("object not decodable")), + opts: nil, + }, + { + name: "corrupt object error, IgnoreStoreReadErrorWithClusterBreakingPotential is nil, want: not invoked", + err: storage.NewCorruptObjError("foo", fmt.Errorf("object not decodable")), + opts: nil, + }, + { + name: "corrupt object error, IgnoreStoreReadErrorWithClusterBreakingPotential is false, want: not invoked", + err: storage.NewCorruptObjError("foo", fmt.Errorf("object not decodable")), + opts: &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](false), + }, + }, + { + name: "error is not corrupt object, IgnoreStoreReadErrorWithClusterBreakingPotential is true, want: not invoked", + err: fmt.Errorf("unexpected error"), + opts: &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + }, + }, + { + name: "internal storage error, IgnoreStoreReadErrorWithClusterBreakingPotential is true, want: not invoked", + err: storage.NewInternalError(fmt.Errorf("unexpected error")), + opts: &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + }, + }, + { + name: "corrupt object error, IgnoreStoreReadErrorWithClusterBreakingPotential is true, want: invoked", + err: storage.NewCorruptObjError("key", fmt.Errorf("object not decodable")), + opts: &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + }, + invoked: 1, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") + destroyFunc, registry := NewTestGenericStoreRegistry(t) + defer destroyFunc() + + // wrap the storage so it returns the error we want to + cs := &corruptStorage{ + Interface: registry.Storage.Storage, + err: test.err, + } + registry.Storage.Storage = cs + deleter := NewCorruptObjectDeleter(registry) + + _, _, err := deleter.Delete(testContext, "foo", rest.ValidateAllObjectFunc, test.opts) + if err != nil { + t.Logf("Registry Delete returned error: %v", err) + } + + if want, got := test.invoked, cs.deleteInvoked; want != got { + t.Errorf("Expected unsafe delete to be invoked %d time(s), but got: %d", want, got) + } + }) + } +} + +func TestUnsafeDeleteWithCorruptObject(t *testing.T) { + podA := &example.Pod{ + ObjectMeta: metav1.ObjectMeta{Name: "foo"}, + Spec: example.PodSpec{NodeName: "machine"}, + } + + testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") + destroyFunc, registry := NewTestGenericStoreRegistry(t) + defer destroyFunc() + + // a) prerequisite: try deleting the object, we expect a not found error + _, _, err := registry.Delete(testContext, podA.Name, rest.ValidateAllObjectFunc, nil) + if !errors.IsNotFound(err) { + t.Errorf("Unexpected error: %v", err) + } + + // b) create the target object + _, err = registry.Create(testContext, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + + // c) wrap the storage to return corrupt object error + cs := &corruptStorage{ + Interface: registry.Storage.Storage, + err: storage.NewCorruptObjError("key", fmt.Errorf("unexpected error")), + } + registry.Storage.Storage = cs + + // d) try deleting the traget object + _, wasDeleted, err := registry.Delete(testContext, podA.Name, rest.ValidateAllObjectFunc, nil) + if !errors.IsInternalError(err) { + t.Errorf("Unexpected failure with the normal deletion flow, got: %v", err) + } + if wasDeleted { + t.Errorf("Unexpected, normal deletion flow did not fail") + } + + // e) set up a corrupt object deleter for the registry + deleter := NewCorruptObjectDeleter(registry) + + // f) try to delete the target object now, but note that the user + // has not set the ignore store read error option yet + _, wasDeleted, err = deleter.Delete(testContext, podA.Name, rest.ValidateAllObjectFunc, nil) + if !errors.IsInternalError(err) { + t.Errorf("Unexpected error: %v", err) + } + if wasDeleted { + t.Errorf("Unexpected, the user did not set the delete option") + } + + // g) this time, set the delete option to ignore store read error + _, wasDeleted, err = deleter.Delete(testContext, podA.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + }) + if err != nil { + t.Errorf("Expected the corrupt object deletion flow to have worked, but got: %v", err) + } + if !wasDeleted { + t.Errorf("Expected the corrupt object deletion flow to have worked") + } + if want, got := 1, cs.deleteInvoked; want != got { + t.Errorf("Expected unsafe delete to be invoked %d time(s), but got: %d", want, got) + } +} + +func TestUnsafeDeleteWithReadableObject(t *testing.T) { + podA := &example.Pod{ + ObjectMeta: metav1.ObjectMeta{Name: "foo"}, + Spec: example.PodSpec{NodeName: "machine"}, + } + + testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") + destroyFunc, registry := NewTestGenericStoreRegistry(t) + defer destroyFunc() + + // a) prerequisite: try deleting the object, we expect a not found error + _, _, err := registry.Delete(testContext, podA.Name, rest.ValidateAllObjectFunc, nil) + if !errors.IsNotFound(err) { + t.Errorf("Unexpected error: %v", err) + } + + // b) create the target object + _, err = registry.Create(testContext, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + + // c) wrap the storage to return corrupt object error + cs := &corruptStorage{ + Interface: registry.Storage.Storage, + err: storage.NewInternalError(fmt.Errorf("unexpected error")), + } + registry.Storage.Storage = cs + + // d) try deleting the traget object using the registry + _, wasDeleted, err := registry.Delete(testContext, podA.Name, rest.ValidateAllObjectFunc, nil) + if !errors.IsInternalError(err) { + t.Errorf("Unexpected failure with the normal deletion flow, got: %v", err) + } + if wasDeleted { + t.Errorf("Unexpected, normal deletion flow did not fail") + } + + // e) set up a corrupt object deleter for the registry + deleter := NewCorruptObjectDeleter(registry) + + // g) this time, set the delete option to ignore store read error + _, _, err = deleter.Delete(testContext, podA.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + }) + if want := "it is exclusively used to delete corrupt object(s), try again by removing this option"; err == nil || !strings.Contains(err.Error(), want) { + t.Errorf("Expected the error to contain: %q, but got: %v", want, err) + } + if want, got := 0, cs.deleteInvoked; want != got { + t.Errorf("Expected unsafe delete to be invoked %d time(s), but got: %d", want, got) + } +} + +type corruptStorage struct { + storage.Interface + err error + deleteInvoked int +} + +func (s *corruptStorage) Get(ctx context.Context, key string, opts storage.GetOptions, objPtr runtime.Object) error { + if s.err != nil { + return s.err + } + return s.Interface.Get(ctx, key, opts, objPtr) +} + +func (s *corruptStorage) Delete(ctx context.Context, key string, out runtime.Object, preconditions *storage.Preconditions, deleteValidation storage.ValidateObjectFunc, cachedExistingObject runtime.Object, opts storage.DeleteOptions) error { + s.deleteInvoked++ + return s.Interface.Delete(ctx, key, out, preconditions, deleteValidation, cachedExistingObject, opts) +} diff --git a/staging/src/k8s.io/apiserver/pkg/storage/errors/storage.go b/staging/src/k8s.io/apiserver/pkg/storage/errors/storage.go index 60a6d5cd869f8..3980288eca4c6 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/errors/storage.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/errors/storage.go @@ -32,6 +32,8 @@ func InterpretListError(err error, qualifiedResource schema.GroupResource) error return errors.NewServerTimeout(qualifiedResource, "list", 2) // TODO: make configurable or handled at a higher level case storage.IsInternalError(err): return errors.NewInternalError(err) + case storage.IsCorruptObject(err): + return errors.NewInternalError(err) default: return err } @@ -47,6 +49,8 @@ func InterpretGetError(err error, qualifiedResource schema.GroupResource, name s return errors.NewServerTimeout(qualifiedResource, "get", 2) // TODO: make configurable or handled at a higher level case storage.IsInternalError(err): return errors.NewInternalError(err) + case storage.IsCorruptObject(err): + return errors.NewInternalError(err) default: return err } @@ -62,6 +66,8 @@ func InterpretCreateError(err error, qualifiedResource schema.GroupResource, nam return errors.NewServerTimeout(qualifiedResource, "create", 2) // TODO: make configurable or handled at a higher level case storage.IsInternalError(err): return errors.NewInternalError(err) + case storage.IsCorruptObject(err): + return errors.NewInternalError(err) default: return err } @@ -79,6 +85,8 @@ func InterpretUpdateError(err error, qualifiedResource schema.GroupResource, nam return errors.NewNotFound(qualifiedResource, name) case storage.IsInternalError(err): return errors.NewInternalError(err) + case storage.IsCorruptObject(err): + return errors.NewInternalError(err) default: return err } @@ -96,6 +104,8 @@ func InterpretDeleteError(err error, qualifiedResource schema.GroupResource, nam return errors.NewConflict(qualifiedResource, name, err) case storage.IsInternalError(err): return errors.NewInternalError(err) + case storage.IsCorruptObject(err): + return errors.NewInternalError(err) default: return err } @@ -110,6 +120,8 @@ func InterpretWatchError(err error, resource schema.GroupResource, name string) return errors.NewInvalid(schema.GroupKind{Group: resource.Group, Kind: resource.Resource}, name, invalidError.Errs) case storage.IsInternalError(err): return errors.NewInternalError(err) + case storage.IsCorruptObject(err): + return errors.NewInternalError(err) default: return err } diff --git a/staging/src/k8s.io/apiserver/pkg/storage/etcd3/corrupt_obj_deleter.go b/staging/src/k8s.io/apiserver/pkg/storage/etcd3/corrupt_obj_deleter.go new file mode 100644 index 0000000000000..a1ba85970066b --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/storage/etcd3/corrupt_obj_deleter.go @@ -0,0 +1,136 @@ +/* +Copyright 2024 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 etcd3 + +import ( + "context" + "errors" + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/value" +) + +// NewStoreWithUnsafeCorruptObjectDeletion wraps the given store implementation +// and adds support for unsafe deletion of corrupt objects +func NewStoreWithUnsafeCorruptObjectDeletion(delegate storage.Interface) storage.Interface { + return &corruptObjectDeleter{Interface: delegate} +} + +// WithCorruptObjErrorHandlingDecoder decorates the given decoder, it determines +// if the error returned by the given decoder represents a corrupt object (the +// object is undecodable), and then it wraps the error appropriately so the +// unsafe deleter can determine if the object is a candidate for unsafe deletion +func WithCorruptObjErrorHandlingDecoder(decoder Decoder) Decoder { + return &corruptObjErrorInterpretingDecoder{Decoder: decoder} +} + +// WithCorruptObjErrorHandlingTransformer decorates the given decoder, it +// determines if the error returned by the given transformer represents a +// corrupt object (the data from the storage is untransformable), and then it +// wraps the error appropriately so the unsafe deleter can determine +// if the object is a candidate for unsafe deletion +func WithCorruptObjErrorHandlingTransformer(transformer value.Transformer) value.Transformer { + return &corruptObjErrorInterpretingTransformer{Transformer: transformer} +} + +// corruptObjectDeleter facilitates unsafe deletion of corrupt objects for etcd +type corruptObjectDeleter struct { + storage.Interface +} + +func (s *corruptObjectDeleter) Get(ctx context.Context, key string, opts storage.GetOptions, out runtime.Object) error { + if err := s.Interface.Get(ctx, key, opts, out); err != nil { + var corruptObjErr *corruptObjectError + if !errors.As(err, &corruptObjErr) { + // this error does not represent a corrupt object + return err + } + // the unsafe deleter at the registry layer will check whether + // the given err represents a corrupt object in order to + // initiate the unsafe deletion flow. + return storage.NewCorruptObjError(key, corruptObjErr) + } + return nil +} + +// corruptObjErrorInterpretingDecoder wraps the error returned by the decorated decoder +type corruptObjErrorInterpretingDecoder struct { + Decoder +} + +func (d *corruptObjErrorInterpretingDecoder) Decode(value []byte, objPtr runtime.Object, rev int64) error { + // TODO: right now any error is deemed as undecodable, in + // the future, we can apply some filter, if need be. + if err := d.Decoder.Decode(value, objPtr, rev); err != nil { + return &corruptObjectError{err: err, errType: undecodable} + } + return nil +} + +// decodeListItem decodes bytes value in array into object. +func (d *corruptObjErrorInterpretingDecoder) DecodeListItem(ctx context.Context, data []byte, rev uint64, newItemFunc func() runtime.Object) (runtime.Object, error) { + // TODO: right now any error is deemed as undecodable, in + // the future, we can apply some filter, if need be. + obj, err := d.Decoder.DecodeListItem(ctx, data, rev, newItemFunc) + if err != nil { + err = &corruptObjectError{err: err, errType: undecodable} + } + return obj, err +} + +// corruptObjErrorInterpretingTransformer wraps the error returned by the transformer +type corruptObjErrorInterpretingTransformer struct { + value.Transformer +} + +func (t *corruptObjErrorInterpretingTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) { + // TODO: right now any error is deemed as undecodable, in the future, we + // can apply some filter, if need be. For example, any network error + out, stale, err := t.Transformer.TransformFromStorage(ctx, data, dataCtx) + if err != nil { + err = &corruptObjectError{err: err, errType: untransformable} + } + return out, stale, err +} + +// corruptObjectError is used internally, only by the corrupt object +// deleter, this error represents a corrup object: +// a) the data from the storage failed to transform, or +// b) the data failed to decode into an object +// NOTE: this error does not have any information to identify the object +// that is corrupt, for example the storage key associated with the object +type corruptObjectError struct { + err error + errType int +} + +const ( + untransformable int = iota + 1 + undecodable +) + +var typeToMessage = map[int]string{ + untransformable: "data from the storage is not transformable", + undecodable: "object not decodable", +} + +func (e *corruptObjectError) Unwrap() error { return e.err } +func (e *corruptObjectError) Error() string { + return fmt.Sprintf("%s: %v", typeToMessage[e.errType], e.err) +} diff --git a/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go b/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go index 37e454e90e9ff..581f7f923d6ad 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go @@ -272,7 +272,7 @@ func (s *store) Delete( return fmt.Errorf("unable to convert output object to pointer: %v", err) } - skipTransformDecode := false + skipTransformDecode := opts.IgnoreStoreReadError return s.conditionalDelete(ctx, preparedKey, out, v, preconditions, validateDeletion, cachedExistingObject, skipTransformDecode) } diff --git a/staging/src/k8s.io/apiserver/pkg/storage/interfaces.go b/staging/src/k8s.io/apiserver/pkg/storage/interfaces.go index 0d6dee0b10475..3932f0caee22f 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/interfaces.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/interfaces.go @@ -317,4 +317,11 @@ type ListOptions struct { // DeleteOptions provides the options that may be provided for storage delete operations. type DeleteOptions struct { + // IgnoreStoreReadError, if enabled, will ignore store read error + // such as transformation or decode failure and go ahead with the + // deletion of the object. + // NOTE: for normal deletion flow it should always be false, it may be + // enabled by the caller only to facilitate unsafe deletion of corrupt + // object which otherwise can not be deleted using the normal flow + IgnoreStoreReadError bool } From b4c2e6e66359df3910ec01cbd130716dc5cc1547 Mon Sep 17 00:00:00 2001 From: Abu Kashem Date: Fri, 20 Sep 2024 17:21:43 -0400 Subject: [PATCH 06/14] wire up unsafe deletion from the delete resource handler --- pkg/features/versioned_kube_features.go | 4 +++ .../pkg/endpoints/handlers/delete.go | 4 +++ .../apiserver/pkg/features/kube_features.go | 13 ++++++++++ .../pkg/registry/generic/registry/store.go | 25 +++++++++++++++++++ .../apiserver/pkg/registry/rest/delete.go | 20 +++++++++++++++ .../apiserver/pkg/registry/rest/rest.go | 9 +++++++ .../storage/storagebackend/factory/etcd3.go | 12 ++++++++- .../test_data/versioned_feature_list.yaml | 6 +++++ 8 files changed, 92 insertions(+), 1 deletion(-) diff --git a/pkg/features/versioned_kube_features.go b/pkg/features/versioned_kube_features.go index 6029bfe7a6ac5..44586c35f7d05 100644 --- a/pkg/features/versioned_kube_features.go +++ b/pkg/features/versioned_kube_features.go @@ -195,6 +195,10 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, }, + genericfeatures.AllowUnsafeMalformedObjectDeletion: { + {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, + }, + genericfeatures.AnonymousAuthConfigurableEndpoints: { {Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.Beta}, diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go index edd6b4da021cb..fe51702d09ea7 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go @@ -122,6 +122,10 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope *RequestSc } options.TypeMeta.SetGroupVersionKind(metav1.SchemeGroupVersion.WithKind("DeleteOptions")) + if utilfeature.DefaultFeatureGate.Enabled(features.AllowUnsafeMalformedObjectDeletion) { + r = rest.WithCorruptObjDeleter(r, options) + } + span.AddEvent("About to delete object from database") wasDeleted := true userInfo, _ := request.UserFrom(ctx) diff --git a/staging/src/k8s.io/apiserver/pkg/features/kube_features.go b/staging/src/k8s.io/apiserver/pkg/features/kube_features.go index f4c6fb3a7564f..7e9c50cc0d5de 100644 --- a/staging/src/k8s.io/apiserver/pkg/features/kube_features.go +++ b/staging/src/k8s.io/apiserver/pkg/features/kube_features.go @@ -54,6 +54,15 @@ const ( // Allows us to enable anonymous auth for only certain apiserver endpoints. AnonymousAuthConfigurableEndpoints featuregate.Feature = "AnonymousAuthConfigurableEndpoints" + // owner: @stlaz @tkashem @dgrisonnet + // kep: https://kep.k8s.io/3926 + // + // Enables the cluster admin to identify resources that fail to + // decrypt or fail to be decoded into an object, and introduces + // a new delete option to allow deletion of such corrupt + // resources using the Kubernetes API only. + AllowUnsafeMalformedObjectDeletion featuregate.Feature = "AllowUnsafeMalformedObjectDeletion" + // owner: @smarterclayton // stable: 1.29 // @@ -259,6 +268,10 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, }, + AllowUnsafeMalformedObjectDeletion: { + {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, + }, + AnonymousAuthConfigurableEndpoints: { {Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.Beta}, diff --git a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go index 90602ad0d4ed4..db18a9476a1a4 100644 --- a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go +++ b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go @@ -234,6 +234,23 @@ type Store struct { // If set, DestroyFunc has to be implemented in thread-safe way and // be prepared for being called more than once. DestroyFunc func() + + // CorruptObjDeleter, if initialized, will make an attempt to + // perform the normal deletion flow, but if either of the below occurs: + // a) the data (associated with the resource being deleted) retrieved + // from the storage failed to transform properly (eg. decryption failure) + // b) the data (associated with the resource being deleted) failed to + // decode properly (eg. corrupt data) + // it will disregard these errors, bypass the finalzer constraints, + // deletion hook(s) and go ahead with the deletion of the object. + // + // WARNING: This may break the cluster if the resource has + // dependencies. Use when the cluster is broken, and there is no + // other viable option to repair the cluster. + // + // TODO: it's located here for convenience so we can wire it + // from inside the handler.DeleteResource function + CorruptObjDeleter rest.GracefulDeleter } // Note: the rest.StandardStorage interface aggregates the common REST verbs @@ -1631,9 +1648,17 @@ func (e *Store) CompleteWithOptions(options *generic.StoreOptions) error { e.ReadinessCheckFunc = e.Storage.Storage.ReadinessCheck } + if utilfeature.DefaultFeatureGate.Enabled(features.AllowUnsafeMalformedObjectDeletion) { + e.CorruptObjDeleter = NewCorruptObjectDeleter(e) + } + return nil } +func (e *Store) GetCorruptObjDeleter() rest.GracefulDeleter { + return e.CorruptObjDeleter +} + // startObservingCount starts monitoring given prefix and periodically updating metrics. It returns a function to stop collection. func (e *Store) startObservingCount(period time.Duration, objectCountTracker flowcontrolrequest.StorageObjectCountTracker) func() { prefix := e.KeyRootFunc(genericapirequest.NewContext()) diff --git a/staging/src/k8s.io/apiserver/pkg/registry/rest/delete.go b/staging/src/k8s.io/apiserver/pkg/registry/rest/delete.go index 34102690e865b..8ed6477548d38 100644 --- a/staging/src/k8s.io/apiserver/pkg/registry/rest/delete.go +++ b/staging/src/k8s.io/apiserver/pkg/registry/rest/delete.go @@ -200,3 +200,23 @@ func AdmissionToValidateObjectDeleteFunc(admit admission.Interface, staticAttrib return nil } } + +// WithCorruptObjDeleter wraps the given rest.GracefulDeleter that is used for normal +// deletion flow with an unsafe deleter to facilitate deletion of corrupt object +func WithCorruptObjDeleter(deleter GracefulDeleter, opts *metav1.DeleteOptions) GracefulDeleter { + if opts == nil { + return deleter + } + if ignore := opts.IgnoreStoreReadErrorWithClusterBreakingPotential; ignore == nil || !*ignore { + return deleter + } + + provider, ok := deleter.(CorruptObjectDeleterProvider) + if !ok { + return deleter + } + if unsafe := provider.GetCorruptObjDeleter(); unsafe != nil { + return unsafe + } + return deleter +} diff --git a/staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go b/staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go index 03cea7bb70b81..58a79fff1e4b4 100644 --- a/staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go +++ b/staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go @@ -400,3 +400,12 @@ type UpdateResetFieldsStrategy interface { RESTUpdateStrategy ResetFieldsStrategy } + +// CorruptObjectDeleterProvider is an optional interface a storage object can +// implement to support unsafe deletion of corrupt object. +// It returns a GracefulDeleter that can be used to perform unsafe deletion +// of corrupt object, it may return nil if the store does not support +// unsafe deletion of corrupt object. +type CorruptObjectDeleterProvider interface { + GetCorruptObjDeleter() GracefulDeleter +} diff --git a/staging/src/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go b/staging/src/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go index d629087d7d187..65c7e25354109 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go @@ -462,7 +462,17 @@ func newETCD3Storage(c storagebackend.ConfigForResource, newFunc, newListFunc fu versioner := storage.APIObjectVersioner{} decoder := etcd3.NewDefaultDecoder(c.Codec, versioner) - return etcd3.New(client, c.Codec, newFunc, newListFunc, c.Prefix, resourcePrefix, c.GroupResource, transformer, c.LeaseManagerConfig, decoder, versioner), destroyFunc, nil + if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.AllowUnsafeMalformedObjectDeletion) { + transformer = etcd3.WithCorruptObjErrorHandlingTransformer(transformer) + decoder = etcd3.WithCorruptObjErrorHandlingDecoder(decoder) + } + + store := etcd3.New(client, c.Codec, newFunc, newListFunc, c.Prefix, resourcePrefix, c.GroupResource, transformer, c.LeaseManagerConfig, decoder, versioner) + if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.AllowUnsafeMalformedObjectDeletion) { + store = etcd3.NewStoreWithUnsafeCorruptObjectDeletion(store) + } + + return store, destroyFunc, nil } // startDBSizeMonitorPerEndpoint starts a loop to monitor etcd database size and update the diff --git a/test/featuregates_linter/test_data/versioned_feature_list.yaml b/test/featuregates_linter/test_data/versioned_feature_list.yaml index c21e54f9fd710..09c7eb2d46997 100644 --- a/test/featuregates_linter/test_data/versioned_feature_list.yaml +++ b/test/featuregates_linter/test_data/versioned_feature_list.yaml @@ -44,6 +44,12 @@ lockToDefault: false preRelease: Deprecated version: "1.32" +- name: AllowUnsafeMalformedObjectDeletion + versionedSpecs: + - default: false + lockToDefault: false + preRelease: Alpha + version: "1.32" - name: AnonymousAuthConfigurableEndpoints versionedSpecs: - default: false From 4aed65ab4c61f78204e3f552dbb1420737517e31 Mon Sep 17 00:00:00 2001 From: Abu Kashem Date: Fri, 20 Sep 2024 17:46:16 -0400 Subject: [PATCH 07/14] aggregate a list of errors identifying objects that are corrupt aggregate a list of errors identifying objects that are corrupt: - data from the storage failed to transform - the object failed to decode properly --- .../pkg/storage/etcd3/corrupt_obj_deleter.go | 59 ++++++++++++++++++- .../apiserver/pkg/storage/etcd3/store.go | 20 ++++++- .../apiserver/pkg/storage/interfaces.go | 9 +++ 3 files changed, 85 insertions(+), 3 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/storage/etcd3/corrupt_obj_deleter.go b/staging/src/k8s.io/apiserver/pkg/storage/etcd3/corrupt_obj_deleter.go index a1ba85970066b..ca191aa28a89e 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/etcd3/corrupt_obj_deleter.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/etcd3/corrupt_obj_deleter.go @@ -20,16 +20,22 @@ import ( "context" "errors" "fmt" + "strings" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/storage" "k8s.io/apiserver/pkg/storage/value" + "k8s.io/klog/v2" ) // NewStoreWithUnsafeCorruptObjectDeletion wraps the given store implementation // and adds support for unsafe deletion of corrupt objects func NewStoreWithUnsafeCorruptObjectDeletion(delegate storage.Interface) storage.Interface { - return &corruptObjectDeleter{Interface: delegate} + return &corruptObjectDeleter{ + Interface: delegate, + // TODO: make it configurable? + aggregateErrMaxCount: 100, + } } // WithCorruptObjErrorHandlingDecoder decorates the given decoder, it determines @@ -52,6 +58,7 @@ func WithCorruptObjErrorHandlingTransformer(transformer value.Transformer) value // corruptObjectDeleter facilitates unsafe deletion of corrupt objects for etcd type corruptObjectDeleter struct { storage.Interface + aggregateErrMaxCount int } func (s *corruptObjectDeleter) Get(ctx context.Context, key string, opts storage.GetOptions, out runtime.Object) error { @@ -69,6 +76,33 @@ func (s *corruptObjectDeleter) Get(ctx context.Context, key string, opts storage return nil } +func (s *corruptObjectDeleter) GetList(ctx context.Context, key string, opts storage.ListOptions, listObj runtime.Object) error { + aggregateErr := &aggregatedStorageError{resourcePrefix: "list"} + opts.AggregateErrFn = func(itemKey string, err error) (done bool) { + if len(aggregateErr.errs) >= s.aggregateErrMaxCount { + return true + } + var corruptObjErr *corruptObjectError + if !errors.As(err, &corruptObjErr) { + // this error does not represent a corrupt object, so we + // will abort aggregating error from the list operation + return true + } + + aggregateErr.errs = append(aggregateErr.errs, storage.NewCorruptObjError(itemKey, corruptObjErr)) + return false + } + + err := s.Interface.GetList(ctx, key, opts, listObj) + + if len(aggregateErr.errs) > 0 { + // we have aggregated a list of corrupt objects + klog.V(5).ErrorS(aggregateErr, "listing corrupt objects") + return aggregateErr + } + return err +} + // corruptObjErrorInterpretingDecoder wraps the error returned by the decorated decoder type corruptObjErrorInterpretingDecoder struct { Decoder @@ -134,3 +168,26 @@ func (e *corruptObjectError) Unwrap() error { return e.err } func (e *corruptObjectError) Error() string { return fmt.Sprintf("%s: %v", typeToMessage[e.errType], e.err) } + +// aggregatedStorageError holds an aggregated list of storage.StorageError +type aggregatedStorageError struct { + resourcePrefix string + errs []*storage.StorageError +} + +func (e *aggregatedStorageError) Error() string { + if len(e.errs) == 0 { + return "" + } + if len(e.errs) == 1 { + return e.errs[0].Error() + } + + var b strings.Builder + fmt.Fprintf(&b, "unable to transform or decode %d objects: {\n", len(e.errs)) + for _, err := range e.errs { + fmt.Fprintf(&b, "\t%s\n", err.Error()) + } + b.WriteString("}") + return b.String() +} diff --git a/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go b/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go index 581f7f923d6ad..f398fff3700f8 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go @@ -768,7 +768,15 @@ func (s *store) GetList(ctx context.Context, key string, opts storage.ListOption data, _, err := s.transformer.TransformFromStorage(ctx, kv.Value, authenticatedDataString(kv.Key)) if err != nil { - return storage.NewInternalError(fmt.Errorf("unable to transform key %q: %w", kv.Key, err)) + switch { + case opts.AggregateErrFn != nil: + if done := opts.AggregateErrFn(string(kv.Key), err); done { + return storage.NewInternalError(fmt.Errorf("unable to transform key %q: %w", kv.Key, err)) + } + continue + default: + return storage.NewInternalError(fmt.Errorf("unable to transform key %q: %w", kv.Key, err)) + } } // Check if the request has already timed out before decode object @@ -782,7 +790,15 @@ func (s *store) GetList(ctx context.Context, key string, opts storage.ListOption obj, err := s.decoder.DecodeListItem(ctx, data, uint64(kv.ModRevision), newItemFunc) if err != nil { recordDecodeError(s.groupResourceString, string(kv.Key)) - return err + switch { + case opts.AggregateErrFn != nil: + if done := opts.AggregateErrFn(string(kv.Key), err); done { + return err + } + continue + default: + return err + } } // being unable to set the version does not prevent the object from being extracted diff --git a/staging/src/k8s.io/apiserver/pkg/storage/interfaces.go b/staging/src/k8s.io/apiserver/pkg/storage/interfaces.go index 3932f0caee22f..8a5653b56a5b0 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/interfaces.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/interfaces.go @@ -313,6 +313,15 @@ type ListOptions struct { // event containing a ResourceVersion after which the server // continues streaming events. SendInitialEvents *bool + + // AggregateErrFn, if provided, will be invoked so the error(s) + // incurred during the list operation can be aggregated. + // The default is nil, and and maintains backward compatibility, which is + // the list operation will abort and return the first error it encounters. + // - key: identifies the object in the underlying storage + // - err: the error that occurred while retrieving the given object from the storage + // - done: if true, the list operation will abort, otherwise, it will continue + AggregateErrFn func(key string, err error) (done bool) } // DeleteOptions provides the options that may be provided for storage delete operations. From e3a79fa78781fbe6e9356c0214a1510d8416372e Mon Sep 17 00:00:00 2001 From: Abu Kashem Date: Fri, 20 Sep 2024 17:44:55 -0400 Subject: [PATCH 08/14] add API status error --- .../apimachinery/pkg/api/errors/errors.go | 7 ++++ .../apimachinery/pkg/apis/meta/v1/types.go | 16 ++++++++ .../pkg/storage/etcd3/corrupt_obj_deleter.go | 39 ++++++++++++++++++- .../storage/storagebackend/factory/etcd3.go | 2 +- 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go b/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go index 57e0e71f672be..6a3ab8f24e21b 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go +++ b/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go @@ -54,6 +54,7 @@ var knownReasons = map[metav1.StatusReason]struct{}{ metav1.StatusReasonGone: {}, metav1.StatusReasonInvalid: {}, metav1.StatusReasonServerTimeout: {}, + metav1.StatusReasonStoreReadError: {}, metav1.StatusReasonTimeout: {}, metav1.StatusReasonTooManyRequests: {}, metav1.StatusReasonBadRequest: {}, @@ -775,6 +776,12 @@ func IsUnexpectedObjectError(err error) bool { return err != nil && (ok || errors.As(err, &uoe)) } +// IsStoreReadError determines if err is due to either failure to transform the +// data from the storage, or failure to decode the object appropriately. +func IsStoreReadError(err error) bool { + return ReasonForError(err) == metav1.StatusReasonStoreReadError +} + // SuggestsClientDelay returns true if this error suggests a client delay as well as the // suggested seconds to wait, or false if the error does not imply a wait. It does not // address whether the error *should* be retried, since some errors (like a 3xx) may diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go index f108a0e0b7675..910856896257a 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go @@ -933,6 +933,22 @@ const ( // Status code 500 StatusReasonServerTimeout StatusReason = "ServerTimeout" + // StatusReasonStoreReadError means that the server encountered an error while + // retrieving resources from the backend object store. + // This may be due to backend database error, or because processing of the read + // resource failed. + // Details: + // "kind" string - the kind attribute of the resource being acted on. + // "name" string - the prefix where the reading error(s) occurred + // "causes" []StatusCause + // - (optional): + // - "type" CauseType - CauseTypeUnexpectedServerResponse + // - "message" string - the error message from the store backend + // - "field" string - the full path with the key of the resource that failed reading + // + // Status code 500 + StatusReasonStoreReadError StatusReason = "StorageReadError" + // StatusReasonTimeout means that the request could not be completed within the given time. // Clients can get this response only when they specified a timeout param in the request, // or if the server cannot complete the operation within a reasonable amount of time. diff --git a/staging/src/k8s.io/apiserver/pkg/storage/etcd3/corrupt_obj_deleter.go b/staging/src/k8s.io/apiserver/pkg/storage/etcd3/corrupt_obj_deleter.go index ca191aa28a89e..b883c952a9711 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/etcd3/corrupt_obj_deleter.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/etcd3/corrupt_obj_deleter.go @@ -20,9 +20,13 @@ import ( "context" "errors" "fmt" + "net/http" "strings" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/storage" "k8s.io/apiserver/pkg/storage/value" "k8s.io/klog/v2" @@ -30,11 +34,12 @@ import ( // NewStoreWithUnsafeCorruptObjectDeletion wraps the given store implementation // and adds support for unsafe deletion of corrupt objects -func NewStoreWithUnsafeCorruptObjectDeletion(delegate storage.Interface) storage.Interface { +func NewStoreWithUnsafeCorruptObjectDeletion(delegate storage.Interface, gr schema.GroupResource) storage.Interface { return &corruptObjectDeleter{ Interface: delegate, // TODO: make it configurable? aggregateErrMaxCount: 100, + groupResource: gr, } } @@ -58,6 +63,7 @@ func WithCorruptObjErrorHandlingTransformer(transformer value.Transformer) value // corruptObjectDeleter facilitates unsafe deletion of corrupt objects for etcd type corruptObjectDeleter struct { storage.Interface + groupResource schema.GroupResource aggregateErrMaxCount int } @@ -98,7 +104,7 @@ func (s *corruptObjectDeleter) GetList(ctx context.Context, key string, opts sto if len(aggregateErr.errs) > 0 { // we have aggregated a list of corrupt objects klog.V(5).ErrorS(aggregateErr, "listing corrupt objects") - return aggregateErr + return aggregateErr.NewAPIStatusError(s.groupResource) } return err } @@ -191,3 +197,32 @@ func (e *aggregatedStorageError) Error() string { b.WriteString("}") return b.String() } + +// NewAPIStatusError creates a new APIStatus object from the +// aggregated list of StorageError +func (e *aggregatedStorageError) NewAPIStatusError(qualifiedResource schema.GroupResource) *apierrors.StatusError { + var causes []metav1.StatusCause + for _, err := range e.errs { + causes = append(causes, metav1.StatusCause{ + Type: metav1.CauseTypeUnexpectedServerResponse, + Field: err.Key, + // TODO: do we need to expose the internal error message here? + Message: err.Error(), + }) + } + + return &apierrors.StatusError{ + ErrStatus: metav1.Status{ + Status: metav1.StatusFailure, + Code: http.StatusInternalServerError, + Reason: metav1.StatusReasonStoreReadError, + Details: &metav1.StatusDetails{ + Group: qualifiedResource.Group, + Kind: qualifiedResource.Resource, + Name: e.resourcePrefix, + Causes: causes, + }, + Message: fmt.Sprintf("failed to read one or more %s from the storage", qualifiedResource.String()), + }, + } +} diff --git a/staging/src/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go b/staging/src/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go index 65c7e25354109..fd41153f64408 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go @@ -469,7 +469,7 @@ func newETCD3Storage(c storagebackend.ConfigForResource, newFunc, newListFunc fu store := etcd3.New(client, c.Codec, newFunc, newListFunc, c.Prefix, resourcePrefix, c.GroupResource, transformer, c.LeaseManagerConfig, decoder, versioner) if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.AllowUnsafeMalformedObjectDeletion) { - store = etcd3.NewStoreWithUnsafeCorruptObjectDeletion(store) + store = etcd3.NewStoreWithUnsafeCorruptObjectDeletion(store, c.GroupResource) } return store, destroyFunc, nil From b545da79897ba308a4cb6404e944ecb106f6ad55 Mon Sep 17 00:00:00 2001 From: Abu Kashem Date: Tue, 8 Oct 2024 09:27:00 -0400 Subject: [PATCH 09/14] refactor: extend newTransformTest to enable/disable RBAC extend newTransformTest with a bool parameter so we can enable RBAC for the transformation tests. --- .../transformation/all_transformation_test.go | 2 +- .../transformation/kms_transformation_test.go | 16 +++++++------- .../kmsv2_transformation_test.go | 22 +++++++++---------- .../secrets_transformation_test.go | 4 ++-- .../transformation/transformation_test.go | 14 ++++++++---- 5 files changed, 32 insertions(+), 26 deletions(-) diff --git a/test/integration/controlplane/transformation/all_transformation_test.go b/test/integration/controlplane/transformation/all_transformation_test.go index 4ca250f234a89..70ed833586305 100644 --- a/test/integration/controlplane/transformation/all_transformation_test.go +++ b/test/integration/controlplane/transformation/all_transformation_test.go @@ -94,7 +94,7 @@ resources: - name: key1 secret: c2VjcmV0IGlzIHNlY3VyZQ== ` - test, err := newTransformTest(t, encryptionConfig, false, "", nil) + test, err := newTransformTest(t, encryptionConfig, false, "", nil, false) if err != nil { t.Fatalf("failed to start Kube API Server with encryptionConfig\n %s, error: %v", encryptionConfig, err) } diff --git a/test/integration/controlplane/transformation/kms_transformation_test.go b/test/integration/controlplane/transformation/kms_transformation_test.go index 01858351ea39a..d00fb4ad19cf4 100644 --- a/test/integration/controlplane/transformation/kms_transformation_test.go +++ b/test/integration/controlplane/transformation/kms_transformation_test.go @@ -145,7 +145,7 @@ resources: ` providerName := "kms-provider" pluginMock := mock.NewBase64Plugin(t, "@kms-provider.sock") - test, err := newTransformTest(t, encryptionConfig, false, "", nil) + test, err := newTransformTest(t, encryptionConfig, false, "", nil, false) if err != nil { t.Fatalf("failed to start KUBE API Server with encryptionConfig\n %s, error: %v", encryptionConfig, err) } @@ -329,7 +329,7 @@ resources: genericapiserver.SetHostnameFuncForTests("testAPIServerID") _ = mock.NewBase64Plugin(t, "@kms-provider.sock") var restarted bool - test, err := newTransformTest(t, encryptionConfig, true, "", storageConfig) + test, err := newTransformTest(t, encryptionConfig, true, "", storageConfig, false) if err != nil { t.Fatalf("failed to start KUBE API Server with encryptionConfig\n %s, error: %v", encryptionConfig, err) } @@ -550,7 +550,7 @@ resources: previousConfigDir := test.configDir test.shutdownAPIServer() restarted = true - test, err = newTransformTest(t, test.transformerConfig, true, previousConfigDir, storageConfig) + test, err = newTransformTest(t, test.transformerConfig, true, previousConfigDir, storageConfig, false) if err != nil { t.Fatalf("failed to start KUBE API Server with encryptionConfig\n %s, error: %v", encryptionConfig, err) } @@ -629,7 +629,7 @@ resources: // Need to enable this explicitly as the feature is deprecated featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.KMSv1, true) - test, err := newTransformTest(t, encryptionConfig, false, "", nil) + test, err := newTransformTest(t, encryptionConfig, false, "", nil, false) if err != nil { t.Fatalf("failed to start KUBE API Server with encryptionConfig") } @@ -755,7 +755,7 @@ resources: featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.KMSv1, true) - test, err := newTransformTest(t, encryptionConfig, false, "", nil) + test, err := newTransformTest(t, encryptionConfig, false, "", nil, false) if err != nil { t.Fatalf("failed to start KUBE API Server with encryptionConfig\n %s, error: %v", encryptionConfig, err) } @@ -902,7 +902,7 @@ resources: ` _ = mock.NewBase64Plugin(t, "@kms-provider.sock") - test, err := newTransformTest(t, encryptionConfig, true, "", nil) + test, err := newTransformTest(t, encryptionConfig, true, "", nil, false) if err != nil { t.Fatalf("failed to start KUBE API Server with encryptionConfig\n %s, error: %v", encryptionConfig, err) } @@ -1114,7 +1114,7 @@ resources: pluginMock1 := mock.NewBase64Plugin(t, "@kms-provider-1.sock") pluginMock2 := mock.NewBase64Plugin(t, "@kms-provider-2.sock") - test, err := newTransformTest(t, encryptionConfig, false, "", nil) + test, err := newTransformTest(t, encryptionConfig, false, "", nil, false) if err != nil { t.Fatalf("failed to start kube-apiserver, error: %v", err) } @@ -1177,7 +1177,7 @@ resources: pluginMock1 := mock.NewBase64Plugin(t, "@kms-provider-1.sock") pluginMock2 := mock.NewBase64Plugin(t, "@kms-provider-2.sock") - test, err := newTransformTest(t, encryptionConfig, true, "", nil) + test, err := newTransformTest(t, encryptionConfig, true, "", nil, false) if err != nil { t.Fatalf("Failed to start kube-apiserver, error: %v", err) } diff --git a/test/integration/controlplane/transformation/kmsv2_transformation_test.go b/test/integration/controlplane/transformation/kmsv2_transformation_test.go index 31d684a6640dc..55bb5348e4006 100644 --- a/test/integration/controlplane/transformation/kmsv2_transformation_test.go +++ b/test/integration/controlplane/transformation/kmsv2_transformation_test.go @@ -193,7 +193,7 @@ resources: ` _ = kmsv2mock.NewBase64Plugin(t, "@kms-provider-defaults.sock") - test, err := newTransformTest(t, encryptionConfig, false, "", nil) + test, err := newTransformTest(t, encryptionConfig, false, "", nil, false) if err != nil { t.Fatalf("failed to start KUBE API Server with encryptionConfig\n %s, error: %v", encryptionConfig, err) } @@ -279,7 +279,7 @@ resources: genericapiserver.SetHostnameFuncForTests("testAPIServerID") pluginMock := kmsv2mock.NewBase64Plugin(t, "@"+kmsName+".sock") - test, err := newTransformTest(t, encryptionConfig, false, "", nil) + test, err := newTransformTest(t, encryptionConfig, false, "", nil, false) if err != nil { t.Fatalf("failed to start KUBE API Server with encryptionConfig\n %s, error: %v", encryptionConfig, err) } @@ -432,7 +432,7 @@ resources: ` pluginMock := kmsv2mock.NewBase64Plugin(t, "@"+kmsName+".sock") - test, err := newTransformTest(t, encryptionConfig, false, "", nil) + test, err := newTransformTest(t, encryptionConfig, false, "", nil, false) if err != nil { t.Fatalf("failed to start KUBE API Server with encryptionConfig\n %s, error: %v", encryptionConfig, err) } @@ -730,7 +730,7 @@ resources: ` _ = kmsv2mock.NewBase64Plugin(t, "@"+kmsName+".sock") - test, err := newTransformTest(t, encryptionConfig, false, "", nil) + test, err := newTransformTest(t, encryptionConfig, false, "", nil, false) if err != nil { t.Fatalf("failed to start KUBE API Server with encryptionConfig\n %s, error: %v", encryptionConfig, err) } @@ -871,7 +871,7 @@ resources: pluginMock1 := kmsv2mock.NewBase64Plugin(t, "@kms-provider-1.sock") pluginMock2 := kmsv2mock.NewBase64Plugin(t, "@kms-provider-2.sock") - test, err := newTransformTest(t, encryptionConfig, false, "", nil) + test, err := newTransformTest(t, encryptionConfig, false, "", nil, false) if err != nil { t.Fatalf("Failed to start kube-apiserver, error: %v", err) } @@ -949,7 +949,7 @@ resources: _ = kmsv2mock.NewBase64Plugin(t, "@kms-provider-single-service.sock") - test, err := newTransformTest(t, encryptionConfig, false, "", nil) + test, err := newTransformTest(t, encryptionConfig, false, "", nil, false) if err != nil { t.Fatalf("failed to start KUBE API Server with encryptionConfig\n %s, error: %v", encryptionConfig, err) } @@ -1006,7 +1006,7 @@ resources: storageConfig := framework.SharedEtcd() // KMSv2 is enabled by default. Loading a encryptionConfig with KMSv2 should work - test, err := newTransformTest(t, encryptionConfig, false, "", storageConfig) + test, err := newTransformTest(t, encryptionConfig, false, "", storageConfig, false) if err != nil { t.Fatalf("failed to start KUBE API Server with encryptionConfig\n %s, error: %v", encryptionConfig, err) } @@ -1078,7 +1078,7 @@ resources: // After a restart, loading a encryptionConfig with the same KMSv2 plugin before the restart should work, decryption of data encrypted with v2 should work - test, err = newTransformTest(t, encryptionConfig, false, "", storageConfig) + test, err = newTransformTest(t, encryptionConfig, false, "", storageConfig, false) if err != nil { t.Fatalf("Failed to restart api server, error: %v", err) } @@ -1126,7 +1126,7 @@ resources: ` _ = kmsv2mock.NewBase64Plugin(b, "@kms-provider-bench.sock") - test, err := newTransformTest(b, encryptionConfig, false, "", nil) + test, err := newTransformTest(b, encryptionConfig, false, "", nil, false) if err != nil { b.Fatalf("failed to start KUBE API Server with encryptionConfig\n %s, error: %v", encryptionConfig, err) } @@ -1279,7 +1279,7 @@ resources: ` _ = kmsv2mock.NewBase64Plugin(b, "@kms-provider-bench-rest.sock") - test, err := newTransformTest(b, encryptionConfig, false, "", nil) + test, err := newTransformTest(b, encryptionConfig, false, "", nil, false) if err != nil { b.Fatalf("failed to start KUBE API Server with encryptionConfig\n %s, error: %v", encryptionConfig, err) } @@ -1378,7 +1378,7 @@ resources: storageConfig := storagebackend.NewDefaultConfig(path.Join(legacyDataEtcdPrefix, "registry"), nil) storageConfig.Transport.ServerList = []string{framework.GetEtcdURL()} - test, err := newTransformTest(t, encryptionConfig, false, "", storageConfig) + test, err := newTransformTest(t, encryptionConfig, false, "", storageConfig, false) if err != nil { t.Fatalf("failed to start KUBE API Server with encryptionConfig\n %s, error: %v", encryptionConfig, err) } diff --git a/test/integration/controlplane/transformation/secrets_transformation_test.go b/test/integration/controlplane/transformation/secrets_transformation_test.go index d554cc50f9e83..a26d66ee14c1c 100644 --- a/test/integration/controlplane/transformation/secrets_transformation_test.go +++ b/test/integration/controlplane/transformation/secrets_transformation_test.go @@ -85,7 +85,7 @@ func TestSecretsShouldBeTransformed(t *testing.T) { // TODO: add secretbox } for _, tt := range testCases { - test, err := newTransformTest(t, tt.transformerConfigContent, false, "", nil) + test, err := newTransformTest(t, tt.transformerConfigContent, false, "", nil, false) if err != nil { t.Fatalf("failed to setup test for envelop %s, error was %v", tt.transformerPrefix, err) continue @@ -119,7 +119,7 @@ func BenchmarkAESCBCEnvelopeWrite(b *testing.B) { func runBenchmark(b *testing.B, transformerConfig string) { b.StopTimer() - test, err := newTransformTest(b, transformerConfig, false, "", nil) + test, err := newTransformTest(b, transformerConfig, false, "", nil, false) if err != nil { b.Fatalf("failed to setup benchmark for config %s, error was %v", transformerConfig, err) } diff --git a/test/integration/controlplane/transformation/transformation_test.go b/test/integration/controlplane/transformation/transformation_test.go index 448c7e0554a14..4eb0912f7c5f4 100644 --- a/test/integration/controlplane/transformation/transformation_test.go +++ b/test/integration/controlplane/transformation/transformation_test.go @@ -86,9 +86,10 @@ type transformTest struct { restClient *kubernetes.Clientset ns *corev1.Namespace secret *corev1.Secret + enableRBAC bool } -func newTransformTest(tb testing.TB, transformerConfigYAML string, reload bool, configDir string, storageConfig *storagebackend.Config) (*transformTest, error) { +func newTransformTest(tb testing.TB, transformerConfigYAML string, reload bool, configDir string, storageConfig *storagebackend.Config, enableRBAC bool) (*transformTest, error) { tCtx := ktesting.Init(tb) if storageConfig == nil { storageConfig = framework.SharedEtcd() @@ -97,6 +98,7 @@ func newTransformTest(tb testing.TB, transformerConfigYAML string, reload bool, TContext: tCtx, transformerConfig: transformerConfigYAML, storageConfig: storageConfig, + enableRBAC: enableRBAC, } var err error @@ -286,14 +288,18 @@ func (e *transformTest) getRawSecretFromETCD() ([]byte, error) { } func (e *transformTest) getEncryptionOptions(reload bool) []string { + var options []string if e.transformerConfig != "" { - return []string{ + options = append(options, []string{ "--encryption-provider-config", filepath.Join(e.configDir, encryptionConfigFileName), fmt.Sprintf("--encryption-provider-config-automatic-reload=%v", reload), - "--disable-admission-plugins", "ServiceAccount"} + "--disable-admission-plugins", "ServiceAccount"}...) + } + if e.enableRBAC { + options = append(options, "--authorization-mode=RBAC") } - return nil + return options } func (e *transformTest) createEncryptionConfig() ( From 7677cf61ce767260e9a2f474d7fe04fe5eb3218d Mon Sep 17 00:00:00 2001 From: Abu Kashem Date: Tue, 8 Oct 2024 10:08:06 -0400 Subject: [PATCH 10/14] add an integration test that exercises the unsafe delete flow --- .../secrets_transformation_test.go | 206 +++++++++++++++++- 1 file changed, 205 insertions(+), 1 deletion(-) diff --git a/test/integration/controlplane/transformation/secrets_transformation_test.go b/test/integration/controlplane/transformation/secrets_transformation_test.go index a26d66ee14c1c..baf217eb4162a 100644 --- a/test/integration/controlplane/transformation/secrets_transformation_test.go +++ b/test/integration/controlplane/transformation/secrets_transformation_test.go @@ -21,12 +21,25 @@ import ( "crypto/aes" "crypto/cipher" "encoding/base64" + "errors" "fmt" + "io/ioutil" + "os" + "path/filepath" + "strings" "testing" + "time" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" apiserverv1 "k8s.io/apiserver/pkg/apis/apiserver/v1" + genericfeatures "k8s.io/apiserver/pkg/features" "k8s.io/apiserver/pkg/storage/value" aestransformer "k8s.io/apiserver/pkg/storage/value/encrypt/aes" + utilfeature "k8s.io/apiserver/pkg/util/feature" + featuregatetesting "k8s.io/component-base/featuregate/testing" + "k8s.io/utils/ptr" ) const ( @@ -66,7 +79,10 @@ resources: - resources: - secrets providers: - - identity: {} + - aesgcm: + keys: + - name: key1 + secret: dXBlcnByZGVscHJkZWxwCg== ` ) @@ -99,6 +115,194 @@ func TestSecretsShouldBeTransformed(t *testing.T) { } } +type verifier interface { + verify(t *testing.T, err error) +} + +// TestAllowUnsafeMalformedObjectDeletionFeature is an integration test that verifies: +// 1) if the feature AllowUnsafeMalformedObjectDeletion is enabled, a corrupt +// object can be deleted by enabling the delete option +// 'ignoreStoreReadErrorWithClusterBreakingPotential', it triggers the unsafe +// deletion flow that bypasses any precondition checks or finalizer constraints. +// 2) if the feature AllowUnsafeMalformedObjectDeletion is disabled, the delete +// option 'ignoreStoreReadErrorWithClusterBreakingPotential' has no +// impact (normal deletion flow is used) +func TestAllowUnsafeMalformedObjectDeletionFeature(t *testing.T) { + tests := []struct { + // whether the feature is enabled + featureEnabled bool + // whether encryption broke after the change + encryptionBrokenFn func(t *testing.T, got apierrors.APIStatus) bool + // what we expect for GET on the corrupt object, after encryption has + // broken but before the deletion + corruptObjGetPreDelete verifier + // what we expect for DELETE on the corrupt object, after encryption has + // broken, but without setting the option to ignore store read error + corrupObjDeletWithoutOption verifier + // what we expect for DELETE on the corrupt object, after encryption has + // broken, with the option to ignore store read error enabled + corrupObjDeleteWithOption verifier + // what we expect for GET on the corrupt object (post deletion) + corrupObjGetPostDelete verifier + }{ + { + featureEnabled: true, + encryptionBrokenFn: func(t *testing.T, got apierrors.APIStatus) bool { + return got.Status().Reason == metav1.StatusReasonInternalError && + strings.Contains(got.Status().Message, "StorageError: corrupt object") + }, + corruptObjGetPreDelete: wantAPIStatusError{reason: metav1.StatusReasonInternalError}, + corrupObjDeletWithoutOption: wantAPIStatusError{reason: metav1.StatusReasonInternalError}, + corrupObjDeleteWithOption: wantNoError{}, + corrupObjGetPostDelete: wantAPIStatusError{reason: metav1.StatusReasonNotFound}, + }, + { + featureEnabled: false, + encryptionBrokenFn: func(t *testing.T, got apierrors.APIStatus) bool { + return got.Status().Reason == metav1.StatusReasonInternalError + }, + corruptObjGetPreDelete: wantAPIStatusError{reason: metav1.StatusReasonInternalError}, + corrupObjDeletWithoutOption: wantAPIStatusError{reason: metav1.StatusReasonInternalError}, + corrupObjDeleteWithOption: wantAPIStatusError{reason: metav1.StatusReasonInternalError}, + corrupObjGetPostDelete: wantAPIStatusError{reason: metav1.StatusReasonInternalError}, + }, + } + for _, tc := range tests { + t.Run(fmt.Sprintf("%s/%t", string(genericfeatures.AllowUnsafeMalformedObjectDeletion), tc.featureEnabled), func(t *testing.T) { + featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AllowUnsafeMalformedObjectDeletion, tc.featureEnabled) + + test, err := newTransformTest(t, aesGCMConfigYAML, true, "", nil, false) + if err != nil { + t.Fatalf("failed to setup test for envelop %s, error was %v", aesGCMPrefix, err) + } + defer test.cleanUp() + + secretCorrupt := "foo-with-unsafe-delete" + // a) create and delete the secret, we don't expect any error + _, err = test.createSecret(secretCorrupt, testNamespace) + if err != nil { + t.Fatalf("'%s/%s' failed to create, got error: %v", err, testNamespace, secretCorrupt) + } + err = test.restClient.CoreV1().Secrets(testNamespace).Delete(context.Background(), secretCorrupt, metav1.DeleteOptions{}) + if err != nil { + t.Fatalf("'%s/%s' failed to delete, got error: %v", err, testNamespace, secretCorrupt) + } + + // b) re-create the secret + test.secret, err = test.createSecret(secretCorrupt, testNamespace) + if err != nil { + t.Fatalf("Failed to create test secret, error: %v", err) + } + + // c) update the secret with a finalizer + withFinalizer := test.secret.DeepCopy() + withFinalizer.Finalizers = append(withFinalizer.Finalizers, "tes.k8s.io/fake") + test.secret, err = test.restClient.CoreV1().Secrets(testNamespace).Update(context.Background(), withFinalizer, metav1.UpdateOptions{}) + if err != nil { + t.Fatalf("Failed to add finalizer to the secret, error: %v", err) + } + + test.runResource(test.TContext, unSealWithGCMTransformer, aesGCMPrefix, "", "v1", "secrets", test.secret.Name, test.secret.Namespace) + + // d) override the config and break decryption of the old resources, + // the secret created in step b will be undecryptable + encryptionConf := filepath.Join(test.configDir, encryptionConfigFileName) + body, _ := ioutil.ReadFile(encryptionConf) + t.Logf("file before write: %s", body) + if err := os.WriteFile(encryptionConf, []byte(identityConfigYAML), 0o644); err != nil { + t.Fatalf("failed to write encryption config that's going to make decryption fail") + } + body, _ = ioutil.ReadFile(encryptionConf) + t.Logf("file after write: %s", body) + + // e) wait for the breaking changes to take effect + testCtx, cancel := context.WithCancel(context.Background()) + defer cancel() + err = wait.PollUntilContextTimeout(testCtx, 1*time.Second, 2*time.Minute, true, func(ctx context.Context) (done bool, err error) { + _, err = test.restClient.CoreV1().Secrets(testNamespace).Get(ctx, secretCorrupt, metav1.GetOptions{}) + var got apierrors.APIStatus + if !errors.As(err, &got) { + return false, nil + } + if done := tc.encryptionBrokenFn(t, got); done { + return true, nil + } + return false, nil + }) + if err != nil { + t.Fatalf("encryption never broke: %v", err) + } + + // f) create a new secret, and then delete it, it should work + secretNormal := "bar-with-normal-delete" + _, err = test.createSecret(secretNormal, testNamespace) + if err != nil { + t.Fatalf("'%s/%s' failed to create, got error: %v", err, testNamespace, secretNormal) + } + err = test.restClient.CoreV1().Secrets(testNamespace).Delete(context.Background(), secretNormal, metav1.DeleteOptions{}) + if err != nil { + t.Fatalf("'%s/%s' failed to create, got error: %v", err, testNamespace, secretNormal) + } + + // g) let's try to get the broken secret created in step b, we expect it + // to fail, the error will vary depending on whether the feature is enabled + _, err = test.restClient.CoreV1().Secrets(testNamespace).Get(context.Background(), secretCorrupt, metav1.GetOptions{}) + tc.corruptObjGetPreDelete.verify(t, err) + + // h) let's try the normal deletion flow, we expect an error + err = test.restClient.CoreV1().Secrets(testNamespace).Delete(context.Background(), secretCorrupt, metav1.DeleteOptions{}) + tc.corrupObjDeletWithoutOption.verify(t, err) + + // i) make an attempt to delete the corrupt object by enabling the option + options := metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + } + err = test.restClient.CoreV1().Secrets(testNamespace).Delete(context.Background(), secretCorrupt, options) + tc.corrupObjDeleteWithOption.verify(t, err) + + // j) final get should return a NotFound error after the secret has been deleted + _, err = test.restClient.CoreV1().Secrets(testNamespace).Get(context.Background(), secretCorrupt, metav1.GetOptions{}) + tc.corrupObjGetPostDelete.verify(t, err) + }) + } +} + +type wantNoError struct{} + +func (want wantNoError) verify(t *testing.T, err error) { + t.Helper() + + if err != nil { + t.Errorf("unexpected error: %v", err) + } +} + +type wantAPIStatusError struct { + reason metav1.StatusReason + messageContains string +} + +func (wantError wantAPIStatusError) verify(t *testing.T, err error) { + t.Helper() + + switch { + case err != nil: + var statusGot apierrors.APIStatus + if !errors.As(err, &statusGot) { + t.Errorf("expected an API status error, but got: %v", err) + return + } + if want, got := wantError.reason, statusGot.Status().Reason; want != got { + t.Errorf("expected API status Reason: %q, but got: %q, err: %#v", want, got, statusGot) + } + if want, got := wantError.messageContains, statusGot.Status().Message; !strings.Contains(got, want) { + t.Errorf("expected API status message to contain: %q, got err: %#v", want, statusGot) + } + default: + t.Errorf("expected error: %v, but got none", err) + } +} + // Baseline (no enveloping) - use to contrast with enveloping benchmarks. func BenchmarkBase(b *testing.B) { runBenchmark(b, "") From 0b78324d9927a5654b5ede232cc6c603af2790e6 Mon Sep 17 00:00:00 2001 From: Abu Kashem Date: Mon, 7 Oct 2024 11:38:46 -0400 Subject: [PATCH 11/14] add admission for unsafe delete allow unsafe deletion of a corrupt object via delete option 'ignoreStoreReadErrorWithClusterBreakingPotential' only when the user has permission to do 'delete-ignore-read-errors' on the resource being deleted --- .../samples/generic/server/admission.go | 2 + pkg/kubeapiserver/options/plugins.go | 4 + .../admission/allowunsafedelete/admission.go | 138 ++++++++ .../allowunsafedelete/admission_test.go | 296 ++++++++++++++++++ .../apiserver/pkg/server/options/admission.go | 20 ++ .../secrets_transformation_test.go | 120 ++++++- 6 files changed, 564 insertions(+), 16 deletions(-) create mode 100644 plugin/pkg/admission/allowunsafedelete/admission.go create mode 100644 plugin/pkg/admission/allowunsafedelete/admission_test.go diff --git a/pkg/controlplane/apiserver/samples/generic/server/admission.go b/pkg/controlplane/apiserver/samples/generic/server/admission.go index 18269b945ecac..7bd668c4244bd 100644 --- a/pkg/controlplane/apiserver/samples/generic/server/admission.go +++ b/pkg/controlplane/apiserver/samples/generic/server/admission.go @@ -24,6 +24,7 @@ import ( mutatingwebhook "k8s.io/apiserver/pkg/admission/plugin/webhook/mutating" validatingwebhook "k8s.io/apiserver/pkg/admission/plugin/webhook/validating" "k8s.io/kubernetes/pkg/kubeapiserver/options" + "k8s.io/kubernetes/plugin/pkg/admission/allowunsafedelete" certapproval "k8s.io/kubernetes/plugin/pkg/admission/certificates/approval" "k8s.io/kubernetes/plugin/pkg/admission/certificates/ctbattest" certsigning "k8s.io/kubernetes/plugin/pkg/admission/certificates/signing" @@ -46,6 +47,7 @@ func DefaultOffAdmissionPlugins() sets.Set[string] { ctbattest.PluginName, // ClusterTrustBundleAttest certsubjectrestriction.PluginName, // CertificateSubjectRestriction validatingadmissionpolicy.PluginName, // ValidatingAdmissionPolicy, only active when feature gate ValidatingAdmissionPolicy is enabled + allowunsafedelete.PluginName, // AllowUnsafeMalformedObjectDeletion, only active when feature gate AllowUnsafeMalformedObjectDeletion is enabled ) return sets.New(options.AllOrderedPlugins...).Difference(defaultOnPlugins) diff --git a/pkg/kubeapiserver/options/plugins.go b/pkg/kubeapiserver/options/plugins.go index 7f0bc9ae23c2f..9d60f31c50a73 100644 --- a/pkg/kubeapiserver/options/plugins.go +++ b/pkg/kubeapiserver/options/plugins.go @@ -23,6 +23,7 @@ import ( validatingadmissionpolicy "k8s.io/apiserver/pkg/admission/plugin/policy/validating" // Admission policies "k8s.io/kubernetes/plugin/pkg/admission/admit" + "k8s.io/kubernetes/plugin/pkg/admission/allowunsafedelete" "k8s.io/kubernetes/plugin/pkg/admission/alwayspullimages" "k8s.io/kubernetes/plugin/pkg/admission/antiaffinity" certapproval "k8s.io/kubernetes/plugin/pkg/admission/certificates/approval" @@ -91,6 +92,7 @@ var AllOrderedPlugins = []string{ certsubjectrestriction.PluginName, // CertificateSubjectRestriction defaultingressclass.PluginName, // DefaultIngressClass denyserviceexternalips.PluginName, // DenyServiceExternalIPs + allowunsafedelete.PluginName, // AllowUnsafeMalformedObjectDeletion // new admission plugins should generally be inserted above here // webhook, resourcequota, and deny plugins must go at the end @@ -106,6 +108,7 @@ var AllOrderedPlugins = []string{ // The order of registration is irrelevant, see AllOrderedPlugins for execution order. func RegisterAllAdmissionPlugins(plugins *admission.Plugins) { admit.Register(plugins) // DEPRECATED as no real meaning + allowunsafedelete.Register(plugins) alwayspullimages.Register(plugins) antiaffinity.Register(plugins) defaulttolerationseconds.Register(plugins) @@ -160,6 +163,7 @@ func DefaultOffAdmissionPlugins() sets.Set[string] { defaultingressclass.PluginName, // DefaultIngressClass podsecurity.PluginName, // PodSecurity validatingadmissionpolicy.PluginName, // ValidatingAdmissionPolicy, only active when feature gate ValidatingAdmissionPolicy is enabled + allowunsafedelete.PluginName, // AllowUnsafeMalformedObjectDeletion, only active when feature gate AllowUnsafeMalformedObjectDeletion is enabled ) return sets.New(AllOrderedPlugins...).Difference(defaultOnPlugins) diff --git a/plugin/pkg/admission/allowunsafedelete/admission.go b/plugin/pkg/admission/allowunsafedelete/admission.go new file mode 100644 index 0000000000000..54f0883425854 --- /dev/null +++ b/plugin/pkg/admission/allowunsafedelete/admission.go @@ -0,0 +1,138 @@ +/* +Copyright 2024 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 allowunsafedelete + +import ( + "context" + "errors" + "fmt" + "io" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apiserver/pkg/admission" + genericadmissioninit "k8s.io/apiserver/pkg/admission/initializer" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/apiserver/pkg/endpoints/request" + genericfeatures "k8s.io/apiserver/pkg/features" + utilfeature "k8s.io/apiserver/pkg/util/feature" + + "k8s.io/klog/v2" +) + +// PluginName indicates name of admission plugin. +const PluginName = "AllowUnsafeMalformedObjectDeletion" + +// Register registers a plugin +func Register(plugins *admission.Plugins) { + plugins.Register(PluginName, func(config io.Reader) (admission.Interface, error) { + return NewAllowUnsafeDelete(), nil + }) +} + +// NewAllowUnsafeDelete creates a new admission control handler that will admit +// an unsafe delete of a corrupt object if the user has the appropriate privilege +func NewAllowUnsafeDelete() *AllowUnsafeDelete { + return &AllowUnsafeDelete{ + Handler: admission.NewHandler(admission.Delete), + } +} + +type AllowUnsafeDelete struct { + *admission.Handler + authz authorizer.Authorizer +} + +var _ admission.ValidationInterface = &AllowUnsafeDelete{} +var _ admission.InitializationValidator = &AllowUnsafeDelete{} +var _ genericadmissioninit.WantsAuthorizer = &AllowUnsafeDelete{} + +// SetAuthorizer sets the authorizer. +func (p *AllowUnsafeDelete) SetAuthorizer(authz authorizer.Authorizer) { + p.authz = authz +} + +// ValidateInitialization ensures an authorizer is set. +func (p *AllowUnsafeDelete) ValidateInitialization() error { + if p.authz == nil { + return fmt.Errorf("%s requires an authorizer", PluginName) + } + return nil +} + +// Validate ensures that the user has permission to do 'delete-ignore-read-errors' +// on the resource being deeted when ignoreStoreReadErrorWithClusterBreakingPotential +// is enabled, these are the constraints: +// a) must be a DELETE operation +// b) ignoreStoreReadErrorWithClusterBreakingPotential is set to true +// c) the request is a resource, no sub-resource or non-resource endpoint +// d) the user has permission to do 'delete-ignore-read-errors' on the resource +func (p *AllowUnsafeDelete) Validate(ctx context.Context, attr admission.Attributes, o admission.ObjectInterfaces) (err error) { + // if the feature is disabled, this plugin, although + // enabled, should not be active + if !utilfeature.DefaultFeatureGate.Enabled(genericfeatures.AllowUnsafeMalformedObjectDeletion) { + return nil + } + if attr.GetOperation() != admission.Delete || attr.GetOperationOptions() == nil { + return nil + } + + options, ok := attr.GetOperationOptions().(*metav1.DeleteOptions) + if !ok { + return fmt.Errorf("expected an option of type: %T, but got: %T", &metav1.DeleteOptions{}, attr.GetOperationOptions()) + } + if ignore := options.IgnoreStoreReadErrorWithClusterBreakingPotential; ignore == nil || !*ignore { + return nil + } + + requestInfo, found := request.RequestInfoFrom(ctx) + if !found { + return admission.NewForbidden(attr, errors.New("no RequestInfo found in the context")) + } + if !requestInfo.IsResourceRequest || len(attr.GetSubresource()) > 0 { + return admission.NewForbidden(attr, errors.New("ignoreStoreReadErrorWithClusterBreakingPotential delete option is not allowed on a subresource or non-resource request")) + } + + // if we are here, IgnoreStoreReadErrorWithClusterBreakingPotential + // is set to true in the delete options, the user must have permission + // to do 'delete-ignore-read-errors' on the given resource. + const verb = "delete-ignore-read-errors" + record := authorizer.AttributesRecord{ + User: attr.GetUserInfo(), + Verb: verb, + Namespace: attr.GetNamespace(), + Name: attr.GetName(), + APIGroup: attr.GetResource().Group, + APIVersion: attr.GetResource().Version, + Resource: attr.GetResource().Resource, + ResourceRequest: true, + } + + decision, reason, err := p.authz.Authorize(ctx, record) + if err != nil { + err = fmt.Errorf("error while checking permission for %q, %w", verb, err) + klog.V(1).ErrorS(err, "failed to authorize") + return admission.NewForbidden(attr, err) + } + if decision == authorizer.DecisionAllow { + // TODO: no distinguishable attribute in the audit entry to + // discern whether it was a normal deletion flow or unsafe, + // add an annotation to audit to make that distinction? + return nil + } + + return admission.NewForbidden(attr, fmt.Errorf("user not permitted to do %q, reason: %s", verb, reason)) +} diff --git a/plugin/pkg/admission/allowunsafedelete/admission_test.go b/plugin/pkg/admission/allowunsafedelete/admission_test.go new file mode 100644 index 0000000000000..55590e313a228 --- /dev/null +++ b/plugin/pkg/admission/allowunsafedelete/admission_test.go @@ -0,0 +1,296 @@ +/* +Copyright 2024 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 allowunsafedelete + +import ( + "context" + "fmt" + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/apiserver/pkg/endpoints/request" + genericfeatures "k8s.io/apiserver/pkg/features" + utilfeature "k8s.io/apiserver/pkg/util/feature" + featuregatetesting "k8s.io/component-base/featuregate/testing" + + "k8s.io/utils/ptr" +) + +func TestValidate(t *testing.T) { + verb := "delete-ignore-read-errors" + tests := []struct { + name string + featureEnabled bool + reqInfo *request.RequestInfo + attr admission.Attributes + authz authorizer.Authorizer + err func(admission.Attributes) error + }{ + { + name: "feature enabled, operation is not delete, admit", + featureEnabled: true, + attr: newAttributes(attributes{operation: admission.Update}), + authz: nil, // Authorize should not be invoked + }, + { + name: "feature enabled, delete, operation option is nil, admit", + featureEnabled: true, + attr: newAttributes(attributes{ + operation: admission.Delete, + operationOptions: nil, + }), + authz: nil, // Authorize should not be invoked + }, + { + name: "feature enabled, delete, operation option is not a match, forbid", + featureEnabled: true, + attr: newAttributes(attributes{ + operation: admission.Delete, + operationOptions: &metav1.PatchOptions{}, + }), + authz: nil, // Authorize should not be invoked + err: func(admission.Attributes) error { + return fmt.Errorf("expected an option of type: %T, but got: %T", &metav1.DeleteOptions{}, &metav1.PatchOptions{}) + }, + }, + { + name: "feature enabled, delete, IgnoreStoreReadErrorWithClusterBreakingPotential is nil, admit", + featureEnabled: true, + attr: newAttributes(attributes{ + operation: admission.Delete, + operationOptions: &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: nil, + }, + }), + authz: nil, // Authorize should not be invoked + }, + { + name: "feature enabled, delete, IgnoreStoreReadErrorWithClusterBreakingPotential is false, admit", + featureEnabled: true, + attr: newAttributes(attributes{ + operation: admission.Delete, + operationOptions: &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](false), + }, + }), + authz: nil, // Authorize should not be invoked + }, + { + name: "feature enabled, delete, IgnoreStoreReadErrorWithClusterBreakingPotential is true, no RequestInfo in request context, forbid", + featureEnabled: true, + reqInfo: nil, + attr: newAttributes(attributes{ + operation: admission.Delete, + operationOptions: &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + }, + }), + authz: nil, + err: func(attr admission.Attributes) error { + return admission.NewForbidden(attr, fmt.Errorf("no RequestInfo found in the context")) + }, + }, + { + name: "feature enabled, delete, IgnoreStoreReadErrorWithClusterBreakingPotential is true, subresource request, forbid", + featureEnabled: true, + reqInfo: &request.RequestInfo{IsResourceRequest: true}, + attr: newAttributes(attributes{ + operation: admission.Delete, + subresource: "foo", + operationOptions: &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + }, + }), + authz: nil, + err: func(attr admission.Attributes) error { + return admission.NewForbidden(attr, fmt.Errorf("ignoreStoreReadErrorWithClusterBreakingPotential delete option is not allowed on a subresource or non-resource request")) + }, + }, + { + name: "feature enabled, delete, IgnoreStoreReadErrorWithClusterBreakingPotential is true, subresource request, forbid", + featureEnabled: true, + reqInfo: &request.RequestInfo{IsResourceRequest: false}, + attr: newAttributes(attributes{ + operation: admission.Delete, + subresource: "", + operationOptions: &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + }, + }), + authz: nil, + err: func(attr admission.Attributes) error { + return admission.NewForbidden(attr, fmt.Errorf("ignoreStoreReadErrorWithClusterBreakingPotential delete option is not allowed on a subresource or non-resource request")) + }, + }, + { + name: "feature enabled, delete, IgnoreStoreReadErrorWithClusterBreakingPotential is true, authorizer returns error, forbid", + featureEnabled: true, + reqInfo: &request.RequestInfo{IsResourceRequest: true}, + attr: newAttributes(attributes{ + subresource: "", + operation: admission.Delete, + operationOptions: &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + }, + }), + authz: &fakeAuthorizer{err: fmt.Errorf("unexpected error")}, + err: func(attr admission.Attributes) error { + return admission.NewForbidden(attr, fmt.Errorf("error while checking permission for %q, %w", verb, fmt.Errorf("unexpected error"))) + }, + }, + { + name: "feature enabled, delete, IgnoreStoreReadErrorWithClusterBreakingPotential is true, user does not have permission, forbid", + featureEnabled: true, + reqInfo: &request.RequestInfo{IsResourceRequest: true}, + attr: newAttributes(attributes{ + operation: admission.Delete, + subresource: "", + operationOptions: &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + }, + }), + authz: &fakeAuthorizer{ + decision: authorizer.DecisionDeny, + reason: "does not have permission", + }, + err: func(attr admission.Attributes) error { + return admission.NewForbidden(attr, fmt.Errorf("user not permitted to do %q, reason: %s", verb, "does not have permission")) + }, + }, + { + name: "feature enabled, delete, IgnoreStoreReadErrorWithClusterBreakingPotential is true, authorizer gives no opinion, forbid", + featureEnabled: true, + reqInfo: &request.RequestInfo{IsResourceRequest: true}, + attr: newAttributes(attributes{ + operation: admission.Delete, + subresource: "", + operationOptions: &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + }, + }), + authz: &fakeAuthorizer{ + decision: authorizer.DecisionNoOpinion, + reason: "no opinion", + }, + err: func(attr admission.Attributes) error { + return admission.NewForbidden(attr, fmt.Errorf("user not permitted to do %q, reason: %s", verb, "no opinion")) + }, + }, + { + name: "feature enabled, delete, IgnoreStoreReadErrorWithClusterBreakingPotential is true, user has permission, admit", + featureEnabled: true, + reqInfo: &request.RequestInfo{IsResourceRequest: true}, + attr: newAttributes(attributes{ + operation: admission.Delete, + subresource: "", + operationOptions: &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + }, + userInfo: &user.DefaultInfo{Name: "foo"}, + }), + authz: &fakeAuthorizer{ + decision: authorizer.DecisionAllow, + reason: "permitted", + }, + }, + { + name: "feature disabled, always admit", + featureEnabled: false, + reqInfo: &request.RequestInfo{IsResourceRequest: true}, + attr: newAttributes(attributes{ + operation: admission.Delete, + subresource: "", + operationOptions: &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + }, + userInfo: &user.DefaultInfo{Name: "foo"}, + }), + authz: &fakeAuthorizer{ + err: fmt.Errorf("Authorize should not be invoked when feature is disabled"), + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AllowUnsafeMalformedObjectDeletion, test.featureEnabled) + + admission := NewAllowUnsafeDelete() + admission.SetAuthorizer(test.authz) + + var want error + if test.err != nil { + want = test.err(test.attr) + } + + ctx := context.Background() + if test.reqInfo != nil { + ctx = request.WithRequestInfo(ctx, test.reqInfo) + } + + got := admission.Validate(ctx, test.attr, nil) + switch { + case want != nil: + if got == nil || want.Error() != got.Error() { + t.Errorf("expected error: %v, but got: %v", want, got) + } + default: + if got != nil { + t.Errorf("expected no error, but got: %v", got) + } + } + }) + } +} + +// attributes of interest for this test +type attributes struct { + operation admission.Operation + operationOptions runtime.Object + userInfo user.Info + subresource string +} + +func newAttributes(attr attributes) admission.Attributes { + return admission.NewAttributesRecord( + nil, // this plugin should never inspect the object + nil, // old object, this plugin should never inspect it + schema.GroupVersionKind{}, // this plugin should never inspect kind + "", // namespace, leave it empty, this plugin only passes it along to the authorizer + "", // name, leave it empty, this plugin only passes it along to the authorizer + schema.GroupVersionResource{}, // resource, leave it empty, this plugin only passes it along to the authorizer + attr.subresource, + attr.operation, + attr.operationOptions, + false, // dryRun, this plugin should never inspect this attribute + attr.userInfo) +} + +type fakeAuthorizer struct { + decision authorizer.Decision + reason string + err error +} + +func (authorizer fakeAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) { + return authorizer.decision, authorizer.reason, authorizer.err +} diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/admission.go b/staging/src/k8s.io/apiserver/pkg/server/options/admission.go index 61085e94ebd17..7a66d21872a4f 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/options/admission.go +++ b/staging/src/k8s.io/apiserver/pkg/server/options/admission.go @@ -37,7 +37,9 @@ import ( apiserverapi "k8s.io/apiserver/pkg/apis/apiserver" apiserverapiv1 "k8s.io/apiserver/pkg/apis/apiserver/v1" apiserverapiv1alpha1 "k8s.io/apiserver/pkg/apis/apiserver/v1alpha1" + genericfeatures "k8s.io/apiserver/pkg/features" "k8s.io/apiserver/pkg/server" + utilfeature "k8s.io/apiserver/pkg/util/feature" cacheddiscovery "k8s.io/client-go/discovery/cached/memory" "k8s.io/client-go/dynamic" "k8s.io/client-go/informers" @@ -219,6 +221,24 @@ func (a *AdmissionOptions) Validate() []error { registeredPlugins.Difference(intersections).List())) } + // TODO: is there a better location? we need to ensure that the + // admission plugin is not disabled by the admin when the feature + // gate is enabled, otherwise we skip the check whether the user + // has permission to do unsafe deletion of corrupt object + if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.AllowUnsafeMalformedObjectDeletion) { + // the plugin and the feature have the same name + // the plugin is enabled by default, and is active only + // when the feature is enabled + name := string(genericfeatures.AllowUnsafeMalformedObjectDeletion) + // developer error, the plugin should be registered + if !registeredPlugins.Has(name) { + errs = append(errs, fmt.Errorf("the plugin %q must be registered, and enabled by default", name)) + } + if disablePlugins.Has(name) { + errs = append(errs, fmt.Errorf("the plugin %q must not be disabled when feature %q is enabled", name, name)) + } + } + return errs } diff --git a/test/integration/controlplane/transformation/secrets_transformation_test.go b/test/integration/controlplane/transformation/secrets_transformation_test.go index baf217eb4162a..4bdf1fd5ac36b 100644 --- a/test/integration/controlplane/transformation/secrets_transformation_test.go +++ b/test/integration/controlplane/transformation/secrets_transformation_test.go @@ -30,15 +30,20 @@ import ( "testing" "time" + rbacv1 "k8s.io/api/rbac/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/wait" apiserverv1 "k8s.io/apiserver/pkg/apis/apiserver/v1" genericfeatures "k8s.io/apiserver/pkg/features" "k8s.io/apiserver/pkg/storage/value" aestransformer "k8s.io/apiserver/pkg/storage/value/encrypt/aes" utilfeature "k8s.io/apiserver/pkg/util/feature" + clientset "k8s.io/client-go/kubernetes" + restclient "k8s.io/client-go/rest" featuregatetesting "k8s.io/component-base/featuregate/testing" + "k8s.io/kubernetes/test/integration/authutil" "k8s.io/utils/ptr" ) @@ -142,6 +147,10 @@ func TestAllowUnsafeMalformedObjectDeletionFeature(t *testing.T) { // what we expect for DELETE on the corrupt object, after encryption has // broken, with the option to ignore store read error enabled corrupObjDeleteWithOption verifier + // what we expect for DELETE on the corrupt object, after encryption has + // broken, with the option to ignore store read error enabled, and + // the user has the permission to do unsafe delete + corrupObjDeleteWithOptionAndPrivilege verifier // what we expect for GET on the corrupt object (post deletion) corrupObjGetPostDelete verifier }{ @@ -153,32 +162,56 @@ func TestAllowUnsafeMalformedObjectDeletionFeature(t *testing.T) { }, corruptObjGetPreDelete: wantAPIStatusError{reason: metav1.StatusReasonInternalError}, corrupObjDeletWithoutOption: wantAPIStatusError{reason: metav1.StatusReasonInternalError}, - corrupObjDeleteWithOption: wantNoError{}, - corrupObjGetPostDelete: wantAPIStatusError{reason: metav1.StatusReasonNotFound}, + corrupObjDeleteWithOption: wantAPIStatusError{ + reason: metav1.StatusReasonForbidden, + messageContains: `user not permitted to do "delete-ignore-read-errors"`, + }, + corrupObjDeleteWithOptionAndPrivilege: wantNoError{}, + corrupObjGetPostDelete: wantAPIStatusError{reason: metav1.StatusReasonNotFound}, }, { featureEnabled: false, encryptionBrokenFn: func(t *testing.T, got apierrors.APIStatus) bool { return got.Status().Reason == metav1.StatusReasonInternalError }, - corruptObjGetPreDelete: wantAPIStatusError{reason: metav1.StatusReasonInternalError}, - corrupObjDeletWithoutOption: wantAPIStatusError{reason: metav1.StatusReasonInternalError}, - corrupObjDeleteWithOption: wantAPIStatusError{reason: metav1.StatusReasonInternalError}, - corrupObjGetPostDelete: wantAPIStatusError{reason: metav1.StatusReasonInternalError}, + corruptObjGetPreDelete: wantAPIStatusError{reason: metav1.StatusReasonInternalError}, + corrupObjDeletWithoutOption: wantAPIStatusError{reason: metav1.StatusReasonInternalError}, + corrupObjDeleteWithOption: wantAPIStatusError{reason: metav1.StatusReasonInternalError}, + corrupObjDeleteWithOptionAndPrivilege: wantAPIStatusError{reason: metav1.StatusReasonInternalError}, + corrupObjGetPostDelete: wantAPIStatusError{reason: metav1.StatusReasonInternalError}, }, } for _, tc := range tests { t.Run(fmt.Sprintf("%s/%t", string(genericfeatures.AllowUnsafeMalformedObjectDeletion), tc.featureEnabled), func(t *testing.T) { featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AllowUnsafeMalformedObjectDeletion, tc.featureEnabled) - test, err := newTransformTest(t, aesGCMConfigYAML, true, "", nil, false) + test, err := newTransformTest(t, aesGCMConfigYAML, true, "", nil, tc.featureEnabled) if err != nil { t.Fatalf("failed to setup test for envelop %s, error was %v", aesGCMPrefix, err) } defer test.cleanUp() + // a) set up a distinct client for the test user with the least + // privileges, we will grant permission as we progress through the test + testUser := "croc" + testUserConfig := restclient.CopyConfig(test.kubeAPIServer.ClientConfig) + testUserConfig.Impersonate.UserName = testUser + testUserClient := clientset.NewForConfigOrDie(testUserConfig) + adminClient := test.restClient + + // b) use the admin client to grant the the test user initial permissions, + // we are not going to grant 'delete-ignore-read-errors' just yet + permitUserToDoVerbOnSecret(t, adminClient, testUser, testNamespace, []string{"create", "get", "delete", "update"}) + + // the test should not use the admin client going forward + test.restClient = testUserClient + defer func() { + // for any cleanup that requires admin privileges + test.restClient = adminClient + }() + secretCorrupt := "foo-with-unsafe-delete" - // a) create and delete the secret, we don't expect any error + // c) create and delete the secret, we don't expect any error _, err = test.createSecret(secretCorrupt, testNamespace) if err != nil { t.Fatalf("'%s/%s' failed to create, got error: %v", err, testNamespace, secretCorrupt) @@ -188,13 +221,13 @@ func TestAllowUnsafeMalformedObjectDeletionFeature(t *testing.T) { t.Fatalf("'%s/%s' failed to delete, got error: %v", err, testNamespace, secretCorrupt) } - // b) re-create the secret + // d) re-create the secret test.secret, err = test.createSecret(secretCorrupt, testNamespace) if err != nil { t.Fatalf("Failed to create test secret, error: %v", err) } - // c) update the secret with a finalizer + // e) update the secret with a finalizer withFinalizer := test.secret.DeepCopy() withFinalizer.Finalizers = append(withFinalizer.Finalizers, "tes.k8s.io/fake") test.secret, err = test.restClient.CoreV1().Secrets(testNamespace).Update(context.Background(), withFinalizer, metav1.UpdateOptions{}) @@ -204,7 +237,7 @@ func TestAllowUnsafeMalformedObjectDeletionFeature(t *testing.T) { test.runResource(test.TContext, unSealWithGCMTransformer, aesGCMPrefix, "", "v1", "secrets", test.secret.Name, test.secret.Namespace) - // d) override the config and break decryption of the old resources, + // f) override the config and break decryption of the old resources, // the secret created in step b will be undecryptable encryptionConf := filepath.Join(test.configDir, encryptionConfigFileName) body, _ := ioutil.ReadFile(encryptionConf) @@ -215,7 +248,7 @@ func TestAllowUnsafeMalformedObjectDeletionFeature(t *testing.T) { body, _ = ioutil.ReadFile(encryptionConf) t.Logf("file after write: %s", body) - // e) wait for the breaking changes to take effect + // g) wait for the breaking changes to take effect testCtx, cancel := context.WithCancel(context.Background()) defer cancel() err = wait.PollUntilContextTimeout(testCtx, 1*time.Second, 2*time.Minute, true, func(ctx context.Context) (done bool, err error) { @@ -233,7 +266,7 @@ func TestAllowUnsafeMalformedObjectDeletionFeature(t *testing.T) { t.Fatalf("encryption never broke: %v", err) } - // f) create a new secret, and then delete it, it should work + // h) create a new secret, and then delete it, it should work secretNormal := "bar-with-normal-delete" _, err = test.createSecret(secretNormal, testNamespace) if err != nil { @@ -244,22 +277,31 @@ func TestAllowUnsafeMalformedObjectDeletionFeature(t *testing.T) { t.Fatalf("'%s/%s' failed to create, got error: %v", err, testNamespace, secretNormal) } - // g) let's try to get the broken secret created in step b, we expect it + // i) let's try to get the broken secret created in step b, we expect it // to fail, the error will vary depending on whether the feature is enabled _, err = test.restClient.CoreV1().Secrets(testNamespace).Get(context.Background(), secretCorrupt, metav1.GetOptions{}) tc.corruptObjGetPreDelete.verify(t, err) - // h) let's try the normal deletion flow, we expect an error + // j) let's try the normal deletion flow, we expect an error err = test.restClient.CoreV1().Secrets(testNamespace).Delete(context.Background(), secretCorrupt, metav1.DeleteOptions{}) tc.corrupObjDeletWithoutOption.verify(t, err) - // i) make an attempt to delete the corrupt object by enabling the option + // k) make an attempt to delete the corrupt object by enabling the option, + // on the other hand, we have not granted the 'delete-ignore-read-errors' + // verb to the user yet, so we expect admission to deny the delete request options := metav1.DeleteOptions{ IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), } err = test.restClient.CoreV1().Secrets(testNamespace).Delete(context.Background(), secretCorrupt, options) tc.corrupObjDeleteWithOption.verify(t, err) + // l) grant the test user to do 'delete-ignore-read-errors' on secrets + permitUserToDoVerbOnSecret(t, adminClient, testUser, testNamespace, []string{"delete-ignore-read-errors"}) + + // m) let's try to do unsafe delete again + err = test.restClient.CoreV1().Secrets(testNamespace).Delete(context.Background(), secretCorrupt, options) + tc.corrupObjDeleteWithOptionAndPrivilege.verify(t, err) + // j) final get should return a NotFound error after the secret has been deleted _, err = test.restClient.CoreV1().Secrets(testNamespace).Get(context.Background(), secretCorrupt, metav1.GetOptions{}) tc.corrupObjGetPostDelete.verify(t, err) @@ -303,6 +345,52 @@ func (wantError wantAPIStatusError) verify(t *testing.T, err error) { } } +func permitUserToDoVerbOnSecret(t *testing.T, client *clientset.Clientset, user, namespace string, verbs []string) { + t.Helper() + + name := fmt.Sprintf("%s-can-do-%s-on-secrets-in-%s", user, strings.Join(verbs, "-"), namespace) + _, err := client.RbacV1().Roles(namespace).Create(context.TODO(), &rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Rules: []rbacv1.PolicyRule{ + { + Verbs: verbs, + APIGroups: []string{""}, + Resources: []string{"secrets"}, + }, + }, + }, metav1.CreateOptions{}) + if err != nil { + t.Fatalf("error while creating role: %s, err: %v", name, err) + } + + _, err = client.RbacV1().RoleBindings(namespace).Create(context.TODO(), &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Subjects: []rbacv1.Subject{ + { + Kind: rbacv1.UserKind, + Name: user, + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "Role", + Name: name, + }, + }, metav1.CreateOptions{}) + if err != nil { + t.Fatalf("error while creating role binding: %s, err: %v", name, err) + } + + authutil.WaitForNamedAuthorizationUpdate(t, context.TODO(), client.AuthorizationV1(), + user, namespace, verbs[0], "", schema.GroupResource{Resource: "secrets"}, true) +} + // Baseline (no enveloping) - use to contrast with enveloping benchmarks. func BenchmarkBase(b *testing.B) { runBenchmark(b, "") From 94e0fd45de6a41478f4974a68556ca84bff304d5 Mon Sep 17 00:00:00 2001 From: Abu Kashem Date: Tue, 15 Oct 2024 16:23:17 -0400 Subject: [PATCH 12/14] add integration test to verify that LIST returns corrupt object keys --- .../secrets_transformation_test.go | 161 ++++++++++++++++++ 1 file changed, 161 insertions(+) diff --git a/test/integration/controlplane/transformation/secrets_transformation_test.go b/test/integration/controlplane/transformation/secrets_transformation_test.go index 4bdf1fd5ac36b..7b9251d6724ab 100644 --- a/test/integration/controlplane/transformation/secrets_transformation_test.go +++ b/test/integration/controlplane/transformation/secrets_transformation_test.go @@ -322,6 +322,7 @@ func (want wantNoError) verify(t *testing.T, err error) { type wantAPIStatusError struct { reason metav1.StatusReason messageContains string + more func(*testing.T, apierrors.APIStatus) } func (wantError wantAPIStatusError) verify(t *testing.T, err error) { @@ -340,6 +341,9 @@ func (wantError wantAPIStatusError) verify(t *testing.T, err error) { if want, got := wantError.messageContains, statusGot.Status().Message; !strings.Contains(got, want) { t.Errorf("expected API status message to contain: %q, got err: %#v", want, statusGot) } + if wantError.more != nil { + wantError.more(t, statusGot) + } default: t.Errorf("expected error: %v, but got none", err) } @@ -391,6 +395,163 @@ func permitUserToDoVerbOnSecret(t *testing.T, client *clientset.Clientset, user, user, namespace, verbs[0], "", schema.GroupResource{Resource: "secrets"}, true) } +// TestListCorruptObjects is an integration test that verifies: +// 1) if the feature AllowUnsafeMalformedObjectDeletion is enabled, LIST operation, +// in its error response, should include information that identifies the objects +// that it failed to read from the storage +// 2) if the feature AllowUnsafeMalformedObjectDeletion is disabled, LIST should +// abort as soon as it encounters the first error, to be backward compatible +func TestListCorruptObjects(t *testing.T) { + // these are the secrets that the test will initially create, and + // are expected to become unreadable/corrupt after encryption breaks + secrets := []string{"corrupt-a", "corrupt-b", "corrupt-c"} + + tests := []struct { + featureEnabled bool + // secrets that are created before encryption breaks + secrets []string + // whether encryption broke after the config change + encryptionBrokenFn func(t *testing.T, got apierrors.APIStatus) bool + // what we expect for LIST on the corrupt objects after encryption has broken + listAfter verifier + }{ + { + secrets: secrets, + featureEnabled: true, + encryptionBrokenFn: func(t *testing.T, got apierrors.APIStatus) bool { + return got.Status().Reason == metav1.StatusReasonInternalError && + strings.Contains(got.Status().Message, "data from the storage is not transformable") + }, + listAfter: wantAPIStatusError{ + reason: metav1.StatusReasonStoreReadError, + messageContains: "failed to read one or more secrets from the storage", + more: func(t *testing.T, err apierrors.APIStatus) { + t.Helper() + + details := err.Status().Details + if details == nil { + t.Errorf("expected Details in APIStatus, but got: %#v", err) + return + } + if want, got := len(secrets), len(details.Causes); want != got { + t.Errorf("expected to have %d in APIStatus, but got: %d", want, got) + } + for _, cause := range details.Causes { + if want, got := metav1.CauseTypeUnexpectedServerResponse, cause.Type; want != got { + t.Errorf("expected to cause type to be %s, but got: %s", want, got) + } + } + for _, want := range secrets { + var found bool + for _, got := range details.Causes { + if strings.HasSuffix(got.Field, want) { + found = true + break + } + } + if !found { + t.Errorf("want key: %q in the Fields: %#v", want, details.Causes) + } + } + }, + }, + }, + { + secrets: secrets, + featureEnabled: false, + encryptionBrokenFn: func(t *testing.T, got apierrors.APIStatus) bool { + return got.Status().Reason == metav1.StatusReasonInternalError && + strings.Contains(got.Status().Message, "cipher: message authentication failed") + }, + listAfter: wantAPIStatusError{ + reason: metav1.StatusReasonInternalError, + messageContains: "unable to transform key", + }, + }, + } + for _, tc := range tests { + t.Run(fmt.Sprintf("%s/%t", string(genericfeatures.AllowUnsafeMalformedObjectDeletion), tc.featureEnabled), func(t *testing.T) { + featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AllowUnsafeMalformedObjectDeletion, tc.featureEnabled) + + test, err := newTransformTest(t, aesGCMConfigYAML, true, "", nil, tc.featureEnabled) + if err != nil { + t.Fatalf("failed to setup test for envelop %s, error was %v", aesGCMPrefix, err) + } + defer test.cleanUp() + + // a) create a number of secrets in the test namespace + for _, name := range tc.secrets { + _, err = test.createSecret(name, testNamespace) + if err != nil { + t.Fatalf("Failed to create test secret, error: %v", err) + } + } + + // b) list the secrets before we break encryption + result, err := test.restClient.CoreV1().Secrets(testNamespace).List(context.Background(), metav1.ListOptions{}) + if err != nil { + t.Fatalf("listing secrets failed unexpectedly with: %v", err) + } + if want, got := len(tc.secrets), len(result.Items); got < 3 { + t.Fatalf("expected at least %d secrets, but got: %d", want, got) + } + + // c) override the config and break decryption of the old resources, + // the secret created in step a will be undecryptable + encryptionConf := filepath.Join(test.configDir, encryptionConfigFileName) + body, _ := ioutil.ReadFile(encryptionConf) + t.Logf("file before write: %s", body) + if err := os.WriteFile(encryptionConf, []byte(identityConfigYAML), 0o644); err != nil { + t.Fatalf("failed to write encryption config that's going to make decryption fail") + } + body, _ = ioutil.ReadFile(encryptionConf) + t.Logf("file after write: %s", body) + + // d) wait for the breaking changes to take effect + testCtx, cancel := context.WithCancel(context.Background()) + defer cancel() + err = wait.PollUntilContextTimeout(testCtx, 1*time.Second, 2*time.Minute, true, func(ctx context.Context) (done bool, err error) { + _, err = test.restClient.CoreV1().Secrets(testNamespace).Get(ctx, tc.secrets[0], metav1.GetOptions{}) + var got apierrors.APIStatus + if !errors.As(err, &got) { + return false, nil + } + if done := tc.encryptionBrokenFn(t, got); done { + return true, nil + } + return false, nil + }) + if err != nil { + t.Fatalf("encryption never broke: %v", err) + } + + // TODO: ConsistentListFromCache feature returns the list of objects + // from cache even though these objects are not readable from the + // store after encryption has broken; to work around this issue, let's + // create a new secret and retrieve it from the store to get a more + // recent ResourceVersion and invoke the list with: + // ResourceVersionMatch: Exact + newSecretName := "new-a" + _, err = test.createSecret(newSecretName, testNamespace) + if err != nil { + t.Fatalf("expected no error while creating the new secret, but got: %d", err) + } + newSecret, err := test.restClient.CoreV1().Secrets(testNamespace).Get(context.Background(), newSecretName, metav1.GetOptions{}) + if err != nil { + t.Fatalf("expected no error getting the new secret, but got: %d", err) + } + + // e) list should return expected error + _, err = test.restClient.CoreV1().Secrets(testNamespace).List(context.Background(), metav1.ListOptions{ + ResourceVersion: newSecret.ResourceVersion, + ResourceVersionMatch: metav1.ResourceVersionMatchExact, + }) + tc.listAfter.verify(t, err) + + }) + } +} + // Baseline (no enveloping) - use to contrast with enveloping benchmarks. func BenchmarkBase(b *testing.B) { runBenchmark(b, "") From 4e0dbfca112941d2863c2dd401e2856f2f7f6548 Mon Sep 17 00:00:00 2001 From: Abu Kashem Date: Fri, 18 Oct 2024 11:11:36 -0400 Subject: [PATCH 13/14] use resource version as a precondition to unsafe delete --- .../generic/registry/corrupt_obj_deleter.go | 30 +++--- .../registry/corrupt_obj_deleter_test.go | 93 +++++++++++++++++++ .../k8s.io/apiserver/pkg/storage/errors.go | 16 +++- .../apiserver/pkg/storage/etcd3/store.go | 8 +- 4 files changed, 127 insertions(+), 20 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter.go b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter.go index a288615034d5c..0b667136f412c 100644 --- a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter.go +++ b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter.go @@ -18,8 +18,9 @@ package registry import ( "context" + "errors" "fmt" - "strings" + "strconv" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -103,26 +104,23 @@ func (s *corruptObjectDeleter) Delete(ctx context.Context, name string, deleteVa return nil, false, apierrors.NewInvalid(qualifiedKind, name, fieldErrList) } - // try normal deletetion anyway, it is expected to fail - obj, deleted, err := s.GracefulDeleter.Delete(ctx, name, deleteValidation, opts) - if err == nil { - return obj, deleted, err - } - // TODO: unfortunately we can't do storage.IsCorruptObject(err), - // conversion to API error drops the inner error chain - if !strings.Contains(err.Error(), "corrupt object") { - return obj, deleted, err + var ( + preconditions *storage.Preconditions + internalErr storage.InternalError + ) + // if we have the resource version of the object then we pin it to the + // preconditions, otherwise we drop preconditions entirely. + if errors.As(err, &internalErr) && internalErr.ResourceVersion != 0 { + preconditions = &storage.Preconditions{ + ResourceVersion: ptr.To[string](strconv.FormatInt(internalErr.ResourceVersion, 10)), + } } - // TODO: at this instant, some actor may have managed to recreate this - // object by doing a delete+create, or the underlying error has resolved - // and the object is readable now - klog.V(1).InfoS("Going to perform unsafe object deletion", "object", klog.KRef(genericapirequest.NamespaceValue(ctx), name)) out := s.NewFunc() storageOpts := storage.DeleteOptions{IgnoreStoreReadError: true} - // dropping preconditions, and keeping the admission - if err := s.Storage.Delete(ctx, key, out, nil, storage.ValidateObjectFunc(deleteValidation), nil, storageOpts); err != nil { + // keep the admission + if err := s.Storage.Delete(ctx, key, out, preconditions, storage.ValidateObjectFunc(deleteValidation), nil, storageOpts); err != nil { if storage.IsNotFound(err) { // the DELETE succeeded, but we don't have the object since it's // not retrievable from the storage, so we send a nil object diff --git a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter_test.go b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter_test.go index cbdb1c8db64a6..b019f1dd28960 100644 --- a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter_test.go +++ b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter_test.go @@ -19,6 +19,7 @@ package registry import ( "context" "fmt" + "strconv" "strings" "testing" @@ -232,6 +233,98 @@ func TestUnsafeDeleteWithReadableObject(t *testing.T) { } } +func TestDeleteCorruptObjectWithRevision(t *testing.T) { + podA := &example.Pod{ + ObjectMeta: metav1.ObjectMeta{Name: "foo"}, + Spec: example.PodSpec{NodeName: "machine"}, + } + + testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") + destroyFunc, registry := NewTestGenericStoreRegistry(t) + defer destroyFunc() + + // a) create the target object + _, err := registry.Create(testContext, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + // b) get the revision of the target object from the storage + obj, err := registry.Get(testContext, "foo", &metav1.GetOptions{}) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + rv, err := strconv.Atoi(obj.(*example.Pod).ResourceVersion) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + // c) wrap the storage to return corrupt object error + cs := &corruptStorage{ + Interface: registry.Storage.Storage, + err: storage.NewCorruptObjError("key", storage.NewInternalErrorWithRevision(int64(rv), fmt.Errorf("untransformable"))), + } + registry.Storage.Storage = cs + deleter := NewCorruptObjectDeleter(registry) + + // d) set the delete option to ignore store read error + _, _, err = deleter.Delete(testContext, podA.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + }) + if err != nil { + t.Errorf("Expected the corrupt object deletion flow to have worked, but got: %v", err) + } +} + +func TestDeleteCorruptObjectWithOlderRevision(t *testing.T) { + podA := &example.Pod{ + ObjectMeta: metav1.ObjectMeta{Name: "foo"}, + Spec: example.PodSpec{NodeName: "machine"}, + } + + testContext := genericapirequest.WithNamespace(genericapirequest.NewContext(), "test") + destroyFunc, registry := NewTestGenericStoreRegistry(t) + defer destroyFunc() + + // a) create the target object + _, err := registry.Create(testContext, podA, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + // b) get the revision of the target object from the storage + obj, err := registry.Get(testContext, "foo", &metav1.GetOptions{}) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + rv, err := strconv.Atoi(obj.(*example.Pod).ResourceVersion) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + // c) update the object so it gets a new revision + podA.Spec.NodeName = "another-machine" + if _, _, err := registry.Update(testContext, "foo", rest.DefaultUpdatedObjectInfo(podA), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { + t.Fatalf("Unexpected error from update: %v", err) + } + + // d) wrap the storage to return corrupt object error + cs := &corruptStorage{ + Interface: registry.Storage.Storage, + err: storage.NewCorruptObjError("key", storage.NewInternalErrorWithRevision(int64(rv), fmt.Errorf("untransformable"))), + } + registry.Storage.Storage = cs + deleter := NewCorruptObjectDeleter(registry) + + // e) set the delete option to ignore store read error + _, _, err = deleter.Delete(testContext, podA.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{ + IgnoreStoreReadErrorWithClusterBreakingPotential: ptr.To[bool](true), + }) + if want := fmt.Sprintf("Precondition failed: ResourceVersion in precondition: %d, ResourceVersion in object meta: %d", rv, rv+1); err == nil || !strings.Contains(err.Error(), want) { + t.Errorf("Expected error to contain: %q, but got: %#v", want, err) + } +} + type corruptStorage struct { storage.Interface err error diff --git a/staging/src/k8s.io/apiserver/pkg/storage/errors.go b/staging/src/k8s.io/apiserver/pkg/storage/errors.go index 9259cc7573476..aefdd917143eb 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/errors.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/errors.go @@ -205,6 +205,12 @@ func NewInvalidError(errors field.ErrorList) InvalidError { type InternalError struct { Reason string + // TODO: streamline error management for storage: + // a) remove InternalError, and user StorageError instead (use a new code ErrCodeInternal) + // b) when creating a StorageError do best effort to populate revision and key + // c) use errors.As() + ResourceVersion int64 + // retain the inner error to maintain the error tree, so as to enable us // to do proper error checking, but we also need to be backward compatible. err error @@ -223,7 +229,15 @@ func IsInternalError(err error) bool { } func NewInternalError(err error) InternalError { - return InternalError{Reason: err.Error(), err: err} + return NewInternalErrorWithRevision(0, err) +} + +func NewInternalErrorWithRevision(revision int64, err error) InternalError { + return InternalError{ + ResourceVersion: revision, + Reason: err.Error(), + err: err, + } } var tooLargeResourceVersionCauseMsg = "Too large resource version" diff --git a/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go b/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go index f398fff3700f8..3d87809204073 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go @@ -179,7 +179,7 @@ func (s *store) Get(ctx context.Context, key string, opts storage.GetOptions, ou data, _, err := s.transformer.TransformFromStorage(ctx, kv.Value, authenticatedDataString(preparedKey)) if err != nil { - return storage.NewInternalError(err) + return storage.NewInternalErrorWithRevision(kv.ModRevision, err) } err = s.decoder.Decode(data, out, kv.ModRevision) @@ -941,8 +941,10 @@ func (s *store) getState(ctx context.Context, getResp *clientv3.GetResponse, key state.meta.ResourceVersion = uint64(state.rev) if skipTransformDecode { - // be explicit that we don't have the object - state.obj = nil + state.obj = reflect.New(v.Type()).Interface().(runtime.Object) + if err := s.versioner.UpdateObject(state.obj, uint64(state.rev)); err != nil { + return nil, err + } state.stale = true // this seems a more sane value here return state, nil } From bb8a1875855c66e0ffd5a806e0e5e3de63cb33f1 Mon Sep 17 00:00:00 2001 From: "Dr. Stefan Schimanski" Date: Wed, 23 Oct 2024 11:57:33 +0200 Subject: [PATCH 14/14] Remove leaking abstraction and hide internals of corrupt obj deleter Signed-off-by: Dr. Stefan Schimanski --- .../pkg/endpoints/handlers/delete.go | 10 ++++- .../generic/registry/corrupt_obj_deleter.go | 42 +++++++++---------- .../apiserver/pkg/registry/rest/delete.go | 20 --------- 3 files changed, 28 insertions(+), 44 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go index fe51702d09ea7..0b2a144a039e9 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go @@ -43,6 +43,7 @@ import ( "k8s.io/apiserver/pkg/util/dryrun" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/component-base/tracing" + "k8s.io/utils/ptr" ) // DeleteResource returns a function that will handle a resource deletion @@ -123,7 +124,14 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope *RequestSc options.TypeMeta.SetGroupVersionKind(metav1.SchemeGroupVersion.WithKind("DeleteOptions")) if utilfeature.DefaultFeatureGate.Enabled(features.AllowUnsafeMalformedObjectDeletion) { - r = rest.WithCorruptObjDeleter(r, options) + if ptr.Deref(options.IgnoreStoreReadErrorWithClusterBreakingPotential, false) { + if p, ok := r.(rest.CorruptObjectDeleterProvider); !ok { + scope.err(fmt.Errorf("ignoreStoreReadErrorWithClusterBreakingPotential is not supported"), w, req) + return + } else { + r = p.GetCorruptObjDeleter() + } + } } span.AddEvent("About to delete object from database") diff --git a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter.go b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter.go index 0b667136f412c..08d2477d1c5bf 100644 --- a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter.go +++ b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/corrupt_obj_deleter.go @@ -19,7 +19,6 @@ package registry import ( "context" "errors" - "fmt" "strconv" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -48,26 +47,26 @@ var _ rest.GracefulDeleter = &corruptObjectDeleter{} // post deletion hook defined in 'AfterDelete' of the registry. // // WARNING: This may break the cluster if the resource being deleted has dependencies. -func NewCorruptObjectDeleter(store *Store) *corruptObjectDeleter { +func NewCorruptObjectDeleter(store *Store) rest.GracefulDeleter { return &corruptObjectDeleter{ - GracefulDeleter: store, - KeyFunc: store.KeyFunc, - NewFunc: store.NewFunc, - DefaultQualifiedResource: store.DefaultQualifiedResource, - Storage: store.Storage.Storage, + store: store, + keyFunc: store.KeyFunc, + newFunc: store.NewFunc, + defaultQualifiedResource: store.DefaultQualifiedResource, + storage: store.Storage.Storage, } } // corruptObjectDeleter implements unsafe object deletion flow type corruptObjectDeleter struct { - rest.GracefulDeleter + store *Store - KeyFunc func(ctx context.Context, name string) (string, error) - NewFunc func() runtime.Object - DefaultQualifiedResource schema.GroupResource + keyFunc func(ctx context.Context, name string) (string, error) + newFunc func() runtime.Object + defaultQualifiedResource schema.GroupResource // NOTE: not holding the DryRunnableStorage wrapper, // directly using the storage interface - Storage storage.Interface + storage storage.Interface } // Delete performs an unsafe deletion of the given resource from the storage. @@ -76,30 +75,27 @@ type corruptObjectDeleter struct { // flow, it is exclusively used when the delete option // 'IgnoreStoreReadErrorWithClusterBreakingPotential' is enabled by the user. func (s *corruptObjectDeleter) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, opts *metav1.DeleteOptions) (runtime.Object, bool, error) { - const optionName = "ignoreStoreReadErrorWithClusterBreakingPotential" if opts == nil || !ptr.Deref[bool](opts.IgnoreStoreReadErrorWithClusterBreakingPotential, false) { - // developer error, unsafe deleter should be invoked only when - // IgnoreStoreReadErrorWithClusterBreakingPotential is true - return nil, false, apierrors.NewInternalError(fmt.Errorf("expected %s to be enabled", optionName)) + return s.store.Delete(ctx, name, deleteValidation, opts) } - key, err := s.KeyFunc(ctx, name) + key, err := s.keyFunc(ctx, name) if err != nil { return nil, false, err } - obj := s.NewFunc() + obj := s.newFunc() qualifiedResource := s.qualifiedResourceFromContext(ctx) // TODO: what if Get returns the object from cache, in this case the // apiserver must restart for unsafe deletion to work - err = s.Storage.Get(ctx, key, storage.GetOptions{}, obj) + err = s.storage.Get(ctx, key, storage.GetOptions{}, obj) if err == nil || !storage.IsCorruptObject(err) { // TODO: The Invalid error should have a field for Resource. // After that field is added, we should fill the Resource and // leave the Kind field empty. See the discussion in #18526. qualifiedKind := schema.GroupKind{Group: qualifiedResource.Group, Kind: qualifiedResource.Resource} fieldErrList := field.ErrorList{ - field.Invalid(field.NewPath(optionName), true, "it is exclusively used to delete corrupt object(s), try again by removing this option"), + field.Invalid(field.NewPath("ignoreStoreReadErrorWithClusterBreakingPotential"), true, "is exclusively used to delete corrupt object(s), try again by removing this option"), } return nil, false, apierrors.NewInvalid(qualifiedKind, name, fieldErrList) } @@ -117,10 +113,10 @@ func (s *corruptObjectDeleter) Delete(ctx context.Context, name string, deleteVa } klog.V(1).InfoS("Going to perform unsafe object deletion", "object", klog.KRef(genericapirequest.NamespaceValue(ctx), name)) - out := s.NewFunc() + out := s.newFunc() storageOpts := storage.DeleteOptions{IgnoreStoreReadError: true} // keep the admission - if err := s.Storage.Delete(ctx, key, out, preconditions, storage.ValidateObjectFunc(deleteValidation), nil, storageOpts); err != nil { + if err := s.storage.Delete(ctx, key, out, preconditions, storage.ValidateObjectFunc(deleteValidation), nil, storageOpts); err != nil { if storage.IsNotFound(err) { // the DELETE succeeded, but we don't have the object since it's // not retrievable from the storage, so we send a nil object @@ -138,5 +134,5 @@ func (s *corruptObjectDeleter) qualifiedResourceFromContext(ctx context.Context) return schema.GroupResource{Group: info.APIGroup, Resource: info.Resource} } // some implementations access storage directly and thus the context has no RequestInfo - return s.DefaultQualifiedResource + return s.defaultQualifiedResource } diff --git a/staging/src/k8s.io/apiserver/pkg/registry/rest/delete.go b/staging/src/k8s.io/apiserver/pkg/registry/rest/delete.go index 8ed6477548d38..34102690e865b 100644 --- a/staging/src/k8s.io/apiserver/pkg/registry/rest/delete.go +++ b/staging/src/k8s.io/apiserver/pkg/registry/rest/delete.go @@ -200,23 +200,3 @@ func AdmissionToValidateObjectDeleteFunc(admit admission.Interface, staticAttrib return nil } } - -// WithCorruptObjDeleter wraps the given rest.GracefulDeleter that is used for normal -// deletion flow with an unsafe deleter to facilitate deletion of corrupt object -func WithCorruptObjDeleter(deleter GracefulDeleter, opts *metav1.DeleteOptions) GracefulDeleter { - if opts == nil { - return deleter - } - if ignore := opts.IgnoreStoreReadErrorWithClusterBreakingPotential; ignore == nil || !*ignore { - return deleter - } - - provider, ok := deleter.(CorruptObjectDeleterProvider) - if !ok { - return deleter - } - if unsafe := provider.GetCorruptObjDeleter(); unsafe != nil { - return unsafe - } - return deleter -}