mirror of
https://github.com/optim-enterprises-bv/kubernetes.git
synced 2025-10-30 17:58:14 +00:00
Merge pull request #128499 from stlaz/ctb_betav1
ClusterTrustBundles - move to beta
This commit is contained in:
@@ -691,6 +691,32 @@
|
||||
],
|
||||
"version": "v1"
|
||||
},
|
||||
{
|
||||
"freshness": "Current",
|
||||
"resources": [
|
||||
{
|
||||
"resource": "clustertrustbundles",
|
||||
"responseKind": {
|
||||
"group": "",
|
||||
"kind": "ClusterTrustBundle",
|
||||
"version": ""
|
||||
},
|
||||
"scope": "Cluster",
|
||||
"singularResource": "clustertrustbundle",
|
||||
"verbs": [
|
||||
"create",
|
||||
"delete",
|
||||
"deletecollection",
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"update",
|
||||
"watch"
|
||||
]
|
||||
}
|
||||
],
|
||||
"version": "v1beta1"
|
||||
},
|
||||
{
|
||||
"freshness": "Current",
|
||||
"resources": [
|
||||
|
||||
@@ -107,6 +107,10 @@
|
||||
"groupVersion": "certificates.k8s.io/v1",
|
||||
"version": "v1"
|
||||
},
|
||||
{
|
||||
"groupVersion": "certificates.k8s.io/v1beta1",
|
||||
"version": "v1beta1"
|
||||
},
|
||||
{
|
||||
"groupVersion": "certificates.k8s.io/v1alpha1",
|
||||
"version": "v1alpha1"
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
"groupVersion": "certificates.k8s.io/v1",
|
||||
"version": "v1"
|
||||
},
|
||||
{
|
||||
"groupVersion": "certificates.k8s.io/v1beta1",
|
||||
"version": "v1beta1"
|
||||
},
|
||||
{
|
||||
"groupVersion": "certificates.k8s.io/v1alpha1",
|
||||
"version": "v1alpha1"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"name": "clustertrustbundles",
|
||||
"namespaced": false,
|
||||
"singularName": "clustertrustbundle",
|
||||
"storageVersionHash": "XGGGW2kGm+w=",
|
||||
"storageVersionHash": "v5yhuVertL4=",
|
||||
"verbs": [
|
||||
"create",
|
||||
"delete",
|
||||
|
||||
24
api/discovery/apis__certificates.k8s.io__v1beta1.json
Normal file
24
api/discovery/apis__certificates.k8s.io__v1beta1.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"groupVersion": "certificates.k8s.io/v1beta1",
|
||||
"kind": "APIResourceList",
|
||||
"resources": [
|
||||
{
|
||||
"kind": "ClusterTrustBundle",
|
||||
"name": "clustertrustbundles",
|
||||
"namespaced": false,
|
||||
"singularName": "clustertrustbundle",
|
||||
"storageVersionHash": "v5yhuVertL4=",
|
||||
"verbs": [
|
||||
"create",
|
||||
"delete",
|
||||
"deletecollection",
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"update",
|
||||
"watch"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
773
api/openapi-spec/swagger.json
generated
773
api/openapi-spec/swagger.json
generated
@@ -5202,6 +5202,90 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"io.k8s.api.certificates.v1beta1.ClusterTrustBundle": {
|
||||
"description": "ClusterTrustBundle is a cluster-scoped container for X.509 trust anchors (root certificates).\n\nClusterTrustBundle objects are considered to be readable by any authenticated user in the cluster, because they can be mounted by pods using the `clusterTrustBundle` projection. All service accounts have read access to ClusterTrustBundles by default. Users who only have namespace-level access to a cluster can read ClusterTrustBundles by impersonating a serviceaccount that they have access to.\n\nIt can be optionally associated with a particular assigner, in which case it contains one valid set of trust anchors for that signer. Signers may have multiple associated ClusterTrustBundles; each is an independent set of trust anchors for that signer. Admission control is used to enforce that only users with permissions on the signer can create or modify the corresponding bundle.",
|
||||
"properties": {
|
||||
"apiVersion": {
|
||||
"description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
"type": "string"
|
||||
},
|
||||
"kind": {
|
||||
"description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta",
|
||||
"description": "metadata contains the object metadata."
|
||||
},
|
||||
"spec": {
|
||||
"$ref": "#/definitions/io.k8s.api.certificates.v1beta1.ClusterTrustBundleSpec",
|
||||
"description": "spec contains the signer (if any) and trust anchors."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"spec"
|
||||
],
|
||||
"type": "object",
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "certificates.k8s.io",
|
||||
"kind": "ClusterTrustBundle",
|
||||
"version": "v1beta1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.api.certificates.v1beta1.ClusterTrustBundleList": {
|
||||
"description": "ClusterTrustBundleList is a collection of ClusterTrustBundle objects",
|
||||
"properties": {
|
||||
"apiVersion": {
|
||||
"description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
"type": "string"
|
||||
},
|
||||
"items": {
|
||||
"description": "items is a collection of ClusterTrustBundle objects",
|
||||
"items": {
|
||||
"$ref": "#/definitions/io.k8s.api.certificates.v1beta1.ClusterTrustBundle"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"kind": {
|
||||
"description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta",
|
||||
"description": "metadata contains the list metadata."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"type": "object",
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "certificates.k8s.io",
|
||||
"kind": "ClusterTrustBundleList",
|
||||
"version": "v1beta1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.api.certificates.v1beta1.ClusterTrustBundleSpec": {
|
||||
"description": "ClusterTrustBundleSpec contains the signer and trust anchors.",
|
||||
"properties": {
|
||||
"signerName": {
|
||||
"description": "signerName indicates the associated signer, if any.\n\nIn order to create or update a ClusterTrustBundle that sets signerName, you must have the following cluster-scoped permission: group=certificates.k8s.io resource=signers resourceName=<the signer name> verb=attest.\n\nIf signerName is not empty, then the ClusterTrustBundle object must be named with the signer name as a prefix (translating slashes to colons). For example, for the signer name `example.com/foo`, valid ClusterTrustBundle object names include `example.com:foo:abc` and `example.com:foo:v1`.\n\nIf signerName is empty, then the ClusterTrustBundle object's name must not have such a prefix.\n\nList/watch requests for ClusterTrustBundles can filter on this field using a `spec.signerName=NAME` field selector.",
|
||||
"type": "string"
|
||||
},
|
||||
"trustBundle": {
|
||||
"description": "trustBundle contains the individual X.509 trust anchors for this bundle, as PEM bundle of PEM-wrapped, DER-formatted X.509 certificates.\n\nThe data must consist only of PEM certificate blocks that parse as valid X.509 certificates. Each certificate must include a basic constraints extension with the CA bit set. The API server will reject objects that contain duplicate certificates, or that use PEM block headers.\n\nUsers of ClusterTrustBundles, including Kubelet, are free to reorder and deduplicate certificate blocks in this file according to their own logic, as well as to drop PEM block headers and inter-block data.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"trustBundle"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"io.k8s.api.coordination.v1.Lease": {
|
||||
"description": "Lease defines a lease concept.",
|
||||
"properties": {
|
||||
@@ -56199,6 +56283,695 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"/apis/certificates.k8s.io/v1beta1/": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf",
|
||||
"application/cbor"
|
||||
],
|
||||
"description": "get available resources",
|
||||
"operationId": "getCertificatesV1beta1APIResources",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf",
|
||||
"application/cbor"
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.APIResourceList"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized"
|
||||
}
|
||||
},
|
||||
"schemes": [
|
||||
"https"
|
||||
],
|
||||
"tags": [
|
||||
"certificates_v1beta1"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/apis/certificates.k8s.io/v1beta1/clustertrustbundles": {
|
||||
"delete": {
|
||||
"consumes": [
|
||||
"*/*"
|
||||
],
|
||||
"description": "delete collection of ClusterTrustBundle",
|
||||
"operationId": "deleteCertificatesV1beta1CollectionClusterTrustBundle",
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/parameters/body-2Y1dVQaQ"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/continue-QfD61s0i"
|
||||
},
|
||||
{
|
||||
"description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed",
|
||||
"in": "query",
|
||||
"name": "dryRun",
|
||||
"type": "string",
|
||||
"uniqueItems": true
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/fieldSelector-xIcQKXFG"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/gracePeriodSeconds--K5HaBOS"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-QbNkfIqj"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/labelSelector-5Zw57w4C"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/limit-1NfNmdNH"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/orphanDependents-uRB25kX5"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/propagationPolicy-6jk3prlO"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/resourceVersion-5WAnf1kx"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/resourceVersionMatch-t8XhRHeC"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/sendInitialEvents-rLXlEK_k"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/timeoutSeconds-yvYezaOC"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf",
|
||||
"application/cbor"
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized"
|
||||
}
|
||||
},
|
||||
"schemes": [
|
||||
"https"
|
||||
],
|
||||
"tags": [
|
||||
"certificates_v1beta1"
|
||||
],
|
||||
"x-kubernetes-action": "deletecollection",
|
||||
"x-kubernetes-group-version-kind": {
|
||||
"group": "certificates.k8s.io",
|
||||
"kind": "ClusterTrustBundle",
|
||||
"version": "v1beta1"
|
||||
}
|
||||
},
|
||||
"get": {
|
||||
"consumes": [
|
||||
"*/*"
|
||||
],
|
||||
"description": "list or watch objects of kind ClusterTrustBundle",
|
||||
"operationId": "listCertificatesV1beta1ClusterTrustBundle",
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/continue-QfD61s0i"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/fieldSelector-xIcQKXFG"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/labelSelector-5Zw57w4C"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/limit-1NfNmdNH"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/resourceVersion-5WAnf1kx"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/resourceVersionMatch-t8XhRHeC"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/sendInitialEvents-rLXlEK_k"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/timeoutSeconds-yvYezaOC"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/watch-XNNPZGbK"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf",
|
||||
"application/cbor",
|
||||
"application/json;stream=watch",
|
||||
"application/vnd.kubernetes.protobuf;stream=watch",
|
||||
"application/cbor-seq"
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/io.k8s.api.certificates.v1beta1.ClusterTrustBundleList"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized"
|
||||
}
|
||||
},
|
||||
"schemes": [
|
||||
"https"
|
||||
],
|
||||
"tags": [
|
||||
"certificates_v1beta1"
|
||||
],
|
||||
"x-kubernetes-action": "list",
|
||||
"x-kubernetes-group-version-kind": {
|
||||
"group": "certificates.k8s.io",
|
||||
"kind": "ClusterTrustBundle",
|
||||
"version": "v1beta1"
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/parameters/pretty-tJGM1-ng"
|
||||
}
|
||||
],
|
||||
"post": {
|
||||
"consumes": [
|
||||
"*/*"
|
||||
],
|
||||
"description": "create a ClusterTrustBundle",
|
||||
"operationId": "createCertificatesV1beta1ClusterTrustBundle",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "body",
|
||||
"name": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/io.k8s.api.certificates.v1beta1.ClusterTrustBundle"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed",
|
||||
"in": "query",
|
||||
"name": "dryRun",
|
||||
"type": "string",
|
||||
"uniqueItems": true
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/fieldManager-Qy4HdaTW"
|
||||
},
|
||||
{
|
||||
"description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.",
|
||||
"in": "query",
|
||||
"name": "fieldValidation",
|
||||
"type": "string",
|
||||
"uniqueItems": true
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf",
|
||||
"application/cbor"
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/io.k8s.api.certificates.v1beta1.ClusterTrustBundle"
|
||||
}
|
||||
},
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/io.k8s.api.certificates.v1beta1.ClusterTrustBundle"
|
||||
}
|
||||
},
|
||||
"202": {
|
||||
"description": "Accepted",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/io.k8s.api.certificates.v1beta1.ClusterTrustBundle"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized"
|
||||
}
|
||||
},
|
||||
"schemes": [
|
||||
"https"
|
||||
],
|
||||
"tags": [
|
||||
"certificates_v1beta1"
|
||||
],
|
||||
"x-kubernetes-action": "post",
|
||||
"x-kubernetes-group-version-kind": {
|
||||
"group": "certificates.k8s.io",
|
||||
"kind": "ClusterTrustBundle",
|
||||
"version": "v1beta1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"/apis/certificates.k8s.io/v1beta1/clustertrustbundles/{name}": {
|
||||
"delete": {
|
||||
"consumes": [
|
||||
"*/*"
|
||||
],
|
||||
"description": "delete a ClusterTrustBundle",
|
||||
"operationId": "deleteCertificatesV1beta1ClusterTrustBundle",
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/parameters/body-2Y1dVQaQ"
|
||||
},
|
||||
{
|
||||
"description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed",
|
||||
"in": "query",
|
||||
"name": "dryRun",
|
||||
"type": "string",
|
||||
"uniqueItems": true
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/gracePeriodSeconds--K5HaBOS"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/ignoreStoreReadErrorWithClusterBreakingPotential-QbNkfIqj"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/orphanDependents-uRB25kX5"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/propagationPolicy-6jk3prlO"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf",
|
||||
"application/cbor"
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status"
|
||||
}
|
||||
},
|
||||
"202": {
|
||||
"description": "Accepted",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Status"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized"
|
||||
}
|
||||
},
|
||||
"schemes": [
|
||||
"https"
|
||||
],
|
||||
"tags": [
|
||||
"certificates_v1beta1"
|
||||
],
|
||||
"x-kubernetes-action": "delete",
|
||||
"x-kubernetes-group-version-kind": {
|
||||
"group": "certificates.k8s.io",
|
||||
"kind": "ClusterTrustBundle",
|
||||
"version": "v1beta1"
|
||||
}
|
||||
},
|
||||
"get": {
|
||||
"consumes": [
|
||||
"*/*"
|
||||
],
|
||||
"description": "read the specified ClusterTrustBundle",
|
||||
"operationId": "readCertificatesV1beta1ClusterTrustBundle",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf",
|
||||
"application/cbor"
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/io.k8s.api.certificates.v1beta1.ClusterTrustBundle"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized"
|
||||
}
|
||||
},
|
||||
"schemes": [
|
||||
"https"
|
||||
],
|
||||
"tags": [
|
||||
"certificates_v1beta1"
|
||||
],
|
||||
"x-kubernetes-action": "get",
|
||||
"x-kubernetes-group-version-kind": {
|
||||
"group": "certificates.k8s.io",
|
||||
"kind": "ClusterTrustBundle",
|
||||
"version": "v1beta1"
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"description": "name of the ClusterTrustBundle",
|
||||
"in": "path",
|
||||
"name": "name",
|
||||
"required": true,
|
||||
"type": "string",
|
||||
"uniqueItems": true
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/pretty-tJGM1-ng"
|
||||
}
|
||||
],
|
||||
"patch": {
|
||||
"consumes": [
|
||||
"application/json-patch+json",
|
||||
"application/merge-patch+json",
|
||||
"application/strategic-merge-patch+json",
|
||||
"application/apply-patch+yaml",
|
||||
"application/apply-patch+cbor"
|
||||
],
|
||||
"description": "partially update the specified ClusterTrustBundle",
|
||||
"operationId": "patchCertificatesV1beta1ClusterTrustBundle",
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/parameters/body-78PwaGsr"
|
||||
},
|
||||
{
|
||||
"description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed",
|
||||
"in": "query",
|
||||
"name": "dryRun",
|
||||
"type": "string",
|
||||
"uniqueItems": true
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/fieldManager-7c6nTn1T"
|
||||
},
|
||||
{
|
||||
"description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.",
|
||||
"in": "query",
|
||||
"name": "fieldValidation",
|
||||
"type": "string",
|
||||
"uniqueItems": true
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/force-tOGGb0Yi"
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf",
|
||||
"application/cbor"
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/io.k8s.api.certificates.v1beta1.ClusterTrustBundle"
|
||||
}
|
||||
},
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/io.k8s.api.certificates.v1beta1.ClusterTrustBundle"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized"
|
||||
}
|
||||
},
|
||||
"schemes": [
|
||||
"https"
|
||||
],
|
||||
"tags": [
|
||||
"certificates_v1beta1"
|
||||
],
|
||||
"x-kubernetes-action": "patch",
|
||||
"x-kubernetes-group-version-kind": {
|
||||
"group": "certificates.k8s.io",
|
||||
"kind": "ClusterTrustBundle",
|
||||
"version": "v1beta1"
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"consumes": [
|
||||
"*/*"
|
||||
],
|
||||
"description": "replace the specified ClusterTrustBundle",
|
||||
"operationId": "replaceCertificatesV1beta1ClusterTrustBundle",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "body",
|
||||
"name": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/io.k8s.api.certificates.v1beta1.ClusterTrustBundle"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed",
|
||||
"in": "query",
|
||||
"name": "dryRun",
|
||||
"type": "string",
|
||||
"uniqueItems": true
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/fieldManager-Qy4HdaTW"
|
||||
},
|
||||
{
|
||||
"description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.",
|
||||
"in": "query",
|
||||
"name": "fieldValidation",
|
||||
"type": "string",
|
||||
"uniqueItems": true
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf",
|
||||
"application/cbor"
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/io.k8s.api.certificates.v1beta1.ClusterTrustBundle"
|
||||
}
|
||||
},
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/io.k8s.api.certificates.v1beta1.ClusterTrustBundle"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized"
|
||||
}
|
||||
},
|
||||
"schemes": [
|
||||
"https"
|
||||
],
|
||||
"tags": [
|
||||
"certificates_v1beta1"
|
||||
],
|
||||
"x-kubernetes-action": "put",
|
||||
"x-kubernetes-group-version-kind": {
|
||||
"group": "certificates.k8s.io",
|
||||
"kind": "ClusterTrustBundle",
|
||||
"version": "v1beta1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"/apis/certificates.k8s.io/v1beta1/watch/clustertrustbundles": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
"*/*"
|
||||
],
|
||||
"description": "watch individual changes to a list of ClusterTrustBundle. deprecated: use the 'watch' parameter with a list operation instead.",
|
||||
"operationId": "watchCertificatesV1beta1ClusterTrustBundleList",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf",
|
||||
"application/cbor",
|
||||
"application/json;stream=watch",
|
||||
"application/vnd.kubernetes.protobuf;stream=watch",
|
||||
"application/cbor-seq"
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized"
|
||||
}
|
||||
},
|
||||
"schemes": [
|
||||
"https"
|
||||
],
|
||||
"tags": [
|
||||
"certificates_v1beta1"
|
||||
],
|
||||
"x-kubernetes-action": "watchlist",
|
||||
"x-kubernetes-group-version-kind": {
|
||||
"group": "certificates.k8s.io",
|
||||
"kind": "ClusterTrustBundle",
|
||||
"version": "v1beta1"
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/continue-QfD61s0i"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/fieldSelector-xIcQKXFG"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/labelSelector-5Zw57w4C"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/limit-1NfNmdNH"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/pretty-tJGM1-ng"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/resourceVersion-5WAnf1kx"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/resourceVersionMatch-t8XhRHeC"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/sendInitialEvents-rLXlEK_k"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/timeoutSeconds-yvYezaOC"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/watch-XNNPZGbK"
|
||||
}
|
||||
]
|
||||
},
|
||||
"/apis/certificates.k8s.io/v1beta1/watch/clustertrustbundles/{name}": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
"*/*"
|
||||
],
|
||||
"description": "watch changes to an object of kind ClusterTrustBundle. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.",
|
||||
"operationId": "watchCertificatesV1beta1ClusterTrustBundle",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/yaml",
|
||||
"application/vnd.kubernetes.protobuf",
|
||||
"application/cbor",
|
||||
"application/json;stream=watch",
|
||||
"application/vnd.kubernetes.protobuf;stream=watch",
|
||||
"application/cbor-seq"
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.WatchEvent"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized"
|
||||
}
|
||||
},
|
||||
"schemes": [
|
||||
"https"
|
||||
],
|
||||
"tags": [
|
||||
"certificates_v1beta1"
|
||||
],
|
||||
"x-kubernetes-action": "watch",
|
||||
"x-kubernetes-group-version-kind": {
|
||||
"group": "certificates.k8s.io",
|
||||
"kind": "ClusterTrustBundle",
|
||||
"version": "v1beta1"
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/parameters/allowWatchBookmarks-HC2hJt-J"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/continue-QfD61s0i"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/fieldSelector-xIcQKXFG"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/labelSelector-5Zw57w4C"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/limit-1NfNmdNH"
|
||||
},
|
||||
{
|
||||
"description": "name of the ClusterTrustBundle",
|
||||
"in": "path",
|
||||
"name": "name",
|
||||
"required": true,
|
||||
"type": "string",
|
||||
"uniqueItems": true
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/pretty-tJGM1-ng"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/resourceVersion-5WAnf1kx"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/resourceVersionMatch-t8XhRHeC"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/sendInitialEvents-rLXlEK_k"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/timeoutSeconds-yvYezaOC"
|
||||
},
|
||||
{
|
||||
"$ref": "#/parameters/watch-XNNPZGbK"
|
||||
}
|
||||
]
|
||||
},
|
||||
"/apis/coordination.k8s.io/": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
|
||||
2558
api/openapi-spec/v3/apis__certificates.k8s.io__v1beta1_openapi.json
generated
Normal file
2558
api/openapi-spec/v3/apis__certificates.k8s.io__v1beta1_openapi.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,9 @@ import (
|
||||
"fmt"
|
||||
|
||||
certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1"
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/server/dynamiccertificates"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
@@ -233,6 +236,8 @@ func newKubeAPIServerSignerClusterTrustBundledPublisherDescriptor() *ControllerD
|
||||
}
|
||||
}
|
||||
|
||||
type controllerConstructor func(string, dynamiccertificates.CAContentProvider, kubernetes.Interface) (ctbpublisher.PublisherRunner, error)
|
||||
|
||||
func newKubeAPIServerSignerClusterTrustBundledPublisherController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||
rootCA, err := getKubeAPIServerCAFileContents(controllerContext)
|
||||
if err != nil {
|
||||
@@ -243,36 +248,53 @@ func newKubeAPIServerSignerClusterTrustBundledPublisherController(ctx context.Co
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
apiserverSignerClient := controllerContext.ClientBuilder.ClientOrDie("kube-apiserver-serving-clustertrustbundle-publisher")
|
||||
ctbAvailable, err := clusterTrustBundlesAvailable(apiserverSignerClient)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("discovery failed for ClusterTrustBundle: %w", err)
|
||||
}
|
||||
|
||||
if !ctbAvailable {
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
servingSigners, err := dynamiccertificates.NewStaticCAContent("kube-apiserver-serving", rootCA)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("failed to create a static CA content provider for the kube-apiserver-serving signer: %w", err)
|
||||
}
|
||||
|
||||
ctbPublisher, err := ctbpublisher.NewClusterTrustBundlePublisher(
|
||||
"kubernetes.io/kube-apiserver-serving",
|
||||
servingSigners,
|
||||
apiserverSignerClient,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("error creating kube-apiserver-serving signer certificates publisher: %w", err)
|
||||
schemaControllerMapping := map[schema.GroupVersion]controllerConstructor{
|
||||
certificatesv1alpha1.SchemeGroupVersion: ctbpublisher.NewAlphaClusterTrustBundlePublisher,
|
||||
certificatesv1beta1.SchemeGroupVersion: ctbpublisher.NewBetaClusterTrustBundlePublisher,
|
||||
}
|
||||
|
||||
go ctbPublisher.Run(ctx)
|
||||
apiserverSignerClient := controllerContext.ClientBuilder.ClientOrDie("kube-apiserver-serving-clustertrustbundle-publisher")
|
||||
var runner ctbpublisher.PublisherRunner
|
||||
for _, gv := range []schema.GroupVersion{certificatesv1beta1.SchemeGroupVersion, certificatesv1alpha1.SchemeGroupVersion} {
|
||||
ctbAvailable, err := clusterTrustBundlesAvailable(apiserverSignerClient, gv)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("discovery failed for ClusterTrustBundle: %w", err)
|
||||
}
|
||||
|
||||
if !ctbAvailable {
|
||||
continue
|
||||
}
|
||||
|
||||
runner, err = schemaControllerMapping[gv](
|
||||
"kubernetes.io/kube-apiserver-serving",
|
||||
servingSigners,
|
||||
apiserverSignerClient,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("error creating kube-apiserver-serving signer certificates publisher: %w", err)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if runner == nil {
|
||||
klog.Info("no known scheme version was found for clustertrustbundles, cannot start kube-apiserver-serving-clustertrustbundle-publisher-controller")
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
go runner.Run(ctx)
|
||||
return nil, true, nil
|
||||
}
|
||||
|
||||
func clusterTrustBundlesAvailable(client kubernetes.Interface) (bool, error) {
|
||||
resList, err := client.Discovery().ServerResourcesForGroupVersion(certificatesv1alpha1.SchemeGroupVersion.String())
|
||||
func clusterTrustBundlesAvailable(client kubernetes.Interface, schemaVersion schema.GroupVersion) (bool, error) {
|
||||
resList, err := client.Discovery().ServerResourcesForGroupVersion(schemaVersion.String())
|
||||
if errors.IsNotFound(err) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if resList != nil {
|
||||
// even in case of an error above there might be a partial list for APIs that
|
||||
|
||||
@@ -24,7 +24,22 @@ import (
|
||||
|
||||
func addConversionFuncs(scheme *runtime.Scheme) error {
|
||||
// Add field conversion funcs.
|
||||
return scheme.AddFieldLabelConversionFunc(SchemeGroupVersion.WithKind("CertificateSigningRequest"),
|
||||
err := scheme.AddFieldLabelConversionFunc(SchemeGroupVersion.WithKind("CertificateSigningRequest"),
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "metadata.name",
|
||||
"spec.signerName":
|
||||
return label, value, nil
|
||||
default:
|
||||
return "", "", fmt.Errorf("field label not supported: %s", label)
|
||||
}
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return scheme.AddFieldLabelConversionFunc(SchemeGroupVersion.WithKind("ClusterTrustBundle"),
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "metadata.name",
|
||||
|
||||
100
pkg/apis/certificates/v1beta1/zz_generated.conversion.go
generated
100
pkg/apis/certificates/v1beta1/zz_generated.conversion.go
generated
@@ -90,6 +90,36 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*certificatesv1beta1.ClusterTrustBundle)(nil), (*certificates.ClusterTrustBundle)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta1_ClusterTrustBundle_To_certificates_ClusterTrustBundle(a.(*certificatesv1beta1.ClusterTrustBundle), b.(*certificates.ClusterTrustBundle), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*certificates.ClusterTrustBundle)(nil), (*certificatesv1beta1.ClusterTrustBundle)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_certificates_ClusterTrustBundle_To_v1beta1_ClusterTrustBundle(a.(*certificates.ClusterTrustBundle), b.(*certificatesv1beta1.ClusterTrustBundle), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*certificatesv1beta1.ClusterTrustBundleList)(nil), (*certificates.ClusterTrustBundleList)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta1_ClusterTrustBundleList_To_certificates_ClusterTrustBundleList(a.(*certificatesv1beta1.ClusterTrustBundleList), b.(*certificates.ClusterTrustBundleList), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*certificates.ClusterTrustBundleList)(nil), (*certificatesv1beta1.ClusterTrustBundleList)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_certificates_ClusterTrustBundleList_To_v1beta1_ClusterTrustBundleList(a.(*certificates.ClusterTrustBundleList), b.(*certificatesv1beta1.ClusterTrustBundleList), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*certificatesv1beta1.ClusterTrustBundleSpec)(nil), (*certificates.ClusterTrustBundleSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta1_ClusterTrustBundleSpec_To_certificates_ClusterTrustBundleSpec(a.(*certificatesv1beta1.ClusterTrustBundleSpec), b.(*certificates.ClusterTrustBundleSpec), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*certificates.ClusterTrustBundleSpec)(nil), (*certificatesv1beta1.ClusterTrustBundleSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_certificates_ClusterTrustBundleSpec_To_v1beta1_ClusterTrustBundleSpec(a.(*certificates.ClusterTrustBundleSpec), b.(*certificatesv1beta1.ClusterTrustBundleSpec), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -256,3 +286,73 @@ func autoConvert_certificates_CertificateSigningRequestStatus_To_v1beta1_Certifi
|
||||
func Convert_certificates_CertificateSigningRequestStatus_To_v1beta1_CertificateSigningRequestStatus(in *certificates.CertificateSigningRequestStatus, out *certificatesv1beta1.CertificateSigningRequestStatus, s conversion.Scope) error {
|
||||
return autoConvert_certificates_CertificateSigningRequestStatus_To_v1beta1_CertificateSigningRequestStatus(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_ClusterTrustBundle_To_certificates_ClusterTrustBundle(in *certificatesv1beta1.ClusterTrustBundle, out *certificates.ClusterTrustBundle, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_v1beta1_ClusterTrustBundleSpec_To_certificates_ClusterTrustBundleSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1beta1_ClusterTrustBundle_To_certificates_ClusterTrustBundle is an autogenerated conversion function.
|
||||
func Convert_v1beta1_ClusterTrustBundle_To_certificates_ClusterTrustBundle(in *certificatesv1beta1.ClusterTrustBundle, out *certificates.ClusterTrustBundle, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_ClusterTrustBundle_To_certificates_ClusterTrustBundle(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_certificates_ClusterTrustBundle_To_v1beta1_ClusterTrustBundle(in *certificates.ClusterTrustBundle, out *certificatesv1beta1.ClusterTrustBundle, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_certificates_ClusterTrustBundleSpec_To_v1beta1_ClusterTrustBundleSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_certificates_ClusterTrustBundle_To_v1beta1_ClusterTrustBundle is an autogenerated conversion function.
|
||||
func Convert_certificates_ClusterTrustBundle_To_v1beta1_ClusterTrustBundle(in *certificates.ClusterTrustBundle, out *certificatesv1beta1.ClusterTrustBundle, s conversion.Scope) error {
|
||||
return autoConvert_certificates_ClusterTrustBundle_To_v1beta1_ClusterTrustBundle(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_ClusterTrustBundleList_To_certificates_ClusterTrustBundleList(in *certificatesv1beta1.ClusterTrustBundleList, out *certificates.ClusterTrustBundleList, s conversion.Scope) error {
|
||||
out.ListMeta = in.ListMeta
|
||||
out.Items = *(*[]certificates.ClusterTrustBundle)(unsafe.Pointer(&in.Items))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1beta1_ClusterTrustBundleList_To_certificates_ClusterTrustBundleList is an autogenerated conversion function.
|
||||
func Convert_v1beta1_ClusterTrustBundleList_To_certificates_ClusterTrustBundleList(in *certificatesv1beta1.ClusterTrustBundleList, out *certificates.ClusterTrustBundleList, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_ClusterTrustBundleList_To_certificates_ClusterTrustBundleList(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_certificates_ClusterTrustBundleList_To_v1beta1_ClusterTrustBundleList(in *certificates.ClusterTrustBundleList, out *certificatesv1beta1.ClusterTrustBundleList, s conversion.Scope) error {
|
||||
out.ListMeta = in.ListMeta
|
||||
out.Items = *(*[]certificatesv1beta1.ClusterTrustBundle)(unsafe.Pointer(&in.Items))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_certificates_ClusterTrustBundleList_To_v1beta1_ClusterTrustBundleList is an autogenerated conversion function.
|
||||
func Convert_certificates_ClusterTrustBundleList_To_v1beta1_ClusterTrustBundleList(in *certificates.ClusterTrustBundleList, out *certificatesv1beta1.ClusterTrustBundleList, s conversion.Scope) error {
|
||||
return autoConvert_certificates_ClusterTrustBundleList_To_v1beta1_ClusterTrustBundleList(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_ClusterTrustBundleSpec_To_certificates_ClusterTrustBundleSpec(in *certificatesv1beta1.ClusterTrustBundleSpec, out *certificates.ClusterTrustBundleSpec, s conversion.Scope) error {
|
||||
out.SignerName = in.SignerName
|
||||
out.TrustBundle = in.TrustBundle
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1beta1_ClusterTrustBundleSpec_To_certificates_ClusterTrustBundleSpec is an autogenerated conversion function.
|
||||
func Convert_v1beta1_ClusterTrustBundleSpec_To_certificates_ClusterTrustBundleSpec(in *certificatesv1beta1.ClusterTrustBundleSpec, out *certificates.ClusterTrustBundleSpec, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_ClusterTrustBundleSpec_To_certificates_ClusterTrustBundleSpec(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_certificates_ClusterTrustBundleSpec_To_v1beta1_ClusterTrustBundleSpec(in *certificates.ClusterTrustBundleSpec, out *certificatesv1beta1.ClusterTrustBundleSpec, s conversion.Scope) error {
|
||||
out.SignerName = in.SignerName
|
||||
out.TrustBundle = in.TrustBundle
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_certificates_ClusterTrustBundleSpec_To_v1beta1_ClusterTrustBundleSpec is an autogenerated conversion function.
|
||||
func Convert_certificates_ClusterTrustBundleSpec_To_v1beta1_ClusterTrustBundleSpec(in *certificates.ClusterTrustBundleSpec, out *certificatesv1beta1.ClusterTrustBundleSpec, s conversion.Scope) error {
|
||||
return autoConvert_certificates_ClusterTrustBundleSpec_To_v1beta1_ClusterTrustBundleSpec(in, out, s)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1"
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/component-base/metrics/legacyregistry"
|
||||
"k8s.io/component-base/metrics/testutil"
|
||||
@@ -50,7 +50,7 @@ clustertrustbundle_publisher_sync_total{code="200"} 1
|
||||
},
|
||||
{
|
||||
desc: "kube api error",
|
||||
err: apierrors.NewNotFound(certificatesv1alpha1.Resource("clustertrustbundle"), "test.test:testSigner:something"),
|
||||
err: apierrors.NewNotFound(certificatesv1beta1.Resource("clustertrustbundle"), "test.test:testSigner:something"),
|
||||
metrics: []string{
|
||||
"clustertrustbundle_publisher_sync_total",
|
||||
},
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"time"
|
||||
|
||||
certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1"
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
@@ -31,9 +32,11 @@ import (
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apiserver/pkg/server/dynamiccertificates"
|
||||
certinformers "k8s.io/client-go/informers/certificates/v1alpha1"
|
||||
certalpha1informers "k8s.io/client-go/informers/certificates/v1alpha1"
|
||||
certbeta1informers "k8s.io/client-go/informers/certificates/v1beta1"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
certlisters "k8s.io/client-go/listers/certificates/v1alpha1"
|
||||
certalphav1listers "k8s.io/client-go/listers/certificates/v1alpha1"
|
||||
certbetav1listers "k8s.io/client-go/listers/certificates/v1beta1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/klog/v2"
|
||||
@@ -43,41 +46,196 @@ func init() {
|
||||
registerMetrics()
|
||||
}
|
||||
|
||||
type ClusterTrustBundlePublisher struct {
|
||||
type PublisherRunner interface {
|
||||
Run(context.Context)
|
||||
}
|
||||
|
||||
type ClusterTrustBundlePublisher[T clusterTrustBundle] struct {
|
||||
signerName string
|
||||
ca dynamiccertificates.CAContentProvider
|
||||
|
||||
client clientset.Interface
|
||||
client clusterTrustBundlesClient[T]
|
||||
|
||||
ctbInformer cache.SharedIndexInformer
|
||||
ctbLister certlisters.ClusterTrustBundleLister
|
||||
ctbLister clusterTrustBundlesLister[T]
|
||||
ctbListerSynced cache.InformerSynced
|
||||
|
||||
handlers clusterTrustBundleHandlers[T]
|
||||
|
||||
queue workqueue.TypedRateLimitingInterface[string]
|
||||
}
|
||||
|
||||
// clusterTrustBundle is a type constraint grouping all APIs versions of ClusterTrustBundles
|
||||
type clusterTrustBundle interface {
|
||||
certificatesv1alpha1.ClusterTrustBundle | certificatesv1beta1.ClusterTrustBundle
|
||||
}
|
||||
|
||||
// clusterTrustBundlesClient is an API-version independent client for the ClusterTrustBundles API
|
||||
type clusterTrustBundlesClient[T clusterTrustBundle] interface {
|
||||
Create(context.Context, *T, metav1.CreateOptions) (*T, error)
|
||||
Update(context.Context, *T, metav1.UpdateOptions) (*T, error)
|
||||
Delete(context.Context, string, metav1.DeleteOptions) error
|
||||
}
|
||||
|
||||
// clusterTrustBundlesLister is an API-version independent lister for the ClusterTrustBundles API
|
||||
type clusterTrustBundlesLister[T clusterTrustBundle] interface {
|
||||
Get(string) (*T, error)
|
||||
List(labels.Selector) ([]*T, error)
|
||||
}
|
||||
|
||||
type clusterTrustBundleHandlers[T clusterTrustBundle] interface {
|
||||
createClusterTrustBundle(bundleName, signerName, trustBundle string) *T
|
||||
updateWithTrustBundle(ctbObject *T, newBundle string) *T
|
||||
containsTrustBundle(ctbObject *T, bundle string) bool
|
||||
getName(ctbObject *T) string
|
||||
}
|
||||
|
||||
var _ clusterTrustBundleHandlers[certificatesv1beta1.ClusterTrustBundle] = &betaHandlers{}
|
||||
var _ clusterTrustBundleHandlers[certificatesv1alpha1.ClusterTrustBundle] = &alphaHandlers{}
|
||||
|
||||
// betaHandlers groups the `clusterTrustBundleHandlers` for the v1beta1 API of
|
||||
// clusterTrustBundles
|
||||
type betaHandlers struct{}
|
||||
|
||||
func (w *betaHandlers) createClusterTrustBundle(bundleName, signerName, trustBundle string) *certificatesv1beta1.ClusterTrustBundle {
|
||||
return &certificatesv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: bundleName,
|
||||
},
|
||||
Spec: certificatesv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: signerName,
|
||||
TrustBundle: trustBundle,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (w *betaHandlers) updateWithTrustBundle(ctbObject *certificatesv1beta1.ClusterTrustBundle, newBundle string) *certificatesv1beta1.ClusterTrustBundle {
|
||||
newObj := ctbObject.DeepCopy()
|
||||
newObj.Spec.TrustBundle = newBundle
|
||||
return newObj
|
||||
}
|
||||
|
||||
func (w *betaHandlers) containsTrustBundle(ctbObject *certificatesv1beta1.ClusterTrustBundle, bundle string) bool {
|
||||
return ctbObject.Spec.TrustBundle == bundle
|
||||
}
|
||||
|
||||
func (w *betaHandlers) getName(ctbObject *certificatesv1beta1.ClusterTrustBundle) string {
|
||||
return ctbObject.Name
|
||||
}
|
||||
|
||||
// alphaHandlers groups the `clusterTrustBundleHandlers` for the v1alpha1 API of
|
||||
// clusterTrustBundles
|
||||
type alphaHandlers struct{}
|
||||
|
||||
func (w *alphaHandlers) createClusterTrustBundle(bundleName, signerName, trustBundle string) *certificatesv1alpha1.ClusterTrustBundle {
|
||||
return &certificatesv1alpha1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: bundleName,
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
SignerName: signerName,
|
||||
TrustBundle: trustBundle,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (w *alphaHandlers) updateWithTrustBundle(ctbObject *certificatesv1alpha1.ClusterTrustBundle, newBundle string) *certificatesv1alpha1.ClusterTrustBundle {
|
||||
newObj := ctbObject.DeepCopy()
|
||||
newObj.Spec.TrustBundle = newBundle
|
||||
return newObj
|
||||
}
|
||||
|
||||
func (w *alphaHandlers) containsTrustBundle(ctbObject *certificatesv1alpha1.ClusterTrustBundle, bundle string) bool {
|
||||
return ctbObject.Spec.TrustBundle == bundle
|
||||
}
|
||||
|
||||
func (w *alphaHandlers) getName(ctbObject *certificatesv1alpha1.ClusterTrustBundle) string {
|
||||
return ctbObject.Name
|
||||
}
|
||||
|
||||
type caContentListener func()
|
||||
|
||||
func (f caContentListener) Enqueue() {
|
||||
f()
|
||||
}
|
||||
|
||||
// NewClusterTrustBundlePublisher creates and maintains a cluster trust bundle object
|
||||
// for a signer named `signerName`. The cluster trust bundle object contains the
|
||||
// CA from the `caProvider` in its .spec.TrustBundle.
|
||||
func NewClusterTrustBundlePublisher(
|
||||
// NewBetaClusterTrustBundlePublisher sets up a ClusterTrustBundlePublisher for the
|
||||
// v1beta1 API
|
||||
func NewBetaClusterTrustBundlePublisher(
|
||||
signerName string,
|
||||
caProvider dynamiccertificates.CAContentProvider,
|
||||
kubeClient clientset.Interface,
|
||||
) (*ClusterTrustBundlePublisher, error) {
|
||||
) (
|
||||
PublisherRunner,
|
||||
error,
|
||||
) {
|
||||
|
||||
ctbInformer := certbeta1informers.NewFilteredClusterTrustBundleInformer(kubeClient, 0, cache.Indexers{},
|
||||
func(options *metav1.ListOptions) {
|
||||
options.FieldSelector = fields.OneTermEqualSelector("spec.signerName", signerName).String()
|
||||
})
|
||||
|
||||
return newClusterTrustBundlePublisher(
|
||||
signerName,
|
||||
caProvider,
|
||||
kubeClient.CertificatesV1beta1().ClusterTrustBundles(),
|
||||
ctbInformer,
|
||||
certbetav1listers.NewClusterTrustBundleLister(ctbInformer.GetIndexer()),
|
||||
&betaHandlers{},
|
||||
)
|
||||
}
|
||||
|
||||
// NewAlphaClusterTrustBundlePublisher sets up a ClusterTrustBundlePublisher for the
|
||||
// v1alpha1 API
|
||||
func NewAlphaClusterTrustBundlePublisher(
|
||||
signerName string,
|
||||
caProvider dynamiccertificates.CAContentProvider,
|
||||
kubeClient clientset.Interface,
|
||||
) (
|
||||
PublisherRunner,
|
||||
error,
|
||||
) {
|
||||
|
||||
ctbInformer := certalpha1informers.NewFilteredClusterTrustBundleInformer(kubeClient, 0, cache.Indexers{},
|
||||
func(options *metav1.ListOptions) {
|
||||
options.FieldSelector = fields.OneTermEqualSelector("spec.signerName", signerName).String()
|
||||
})
|
||||
|
||||
return newClusterTrustBundlePublisher(
|
||||
signerName,
|
||||
caProvider,
|
||||
kubeClient.CertificatesV1alpha1().ClusterTrustBundles(),
|
||||
ctbInformer,
|
||||
certalphav1listers.NewClusterTrustBundleLister(ctbInformer.GetIndexer()),
|
||||
&alphaHandlers{},
|
||||
)
|
||||
}
|
||||
|
||||
// NewClusterTrustBundlePublisher creates and maintains a cluster trust bundle object
|
||||
// for a signer named `signerName`. The cluster trust bundle object contains the
|
||||
// CA from the `caProvider` in its .spec.TrustBundle.
|
||||
func newClusterTrustBundlePublisher[T clusterTrustBundle](
|
||||
signerName string,
|
||||
caProvider dynamiccertificates.CAContentProvider,
|
||||
bundleClient clusterTrustBundlesClient[T],
|
||||
ctbInformer cache.SharedIndexInformer,
|
||||
ctbLister clusterTrustBundlesLister[T],
|
||||
handlers clusterTrustBundleHandlers[T],
|
||||
) (PublisherRunner, error) {
|
||||
if len(signerName) == 0 {
|
||||
return nil, fmt.Errorf("signerName cannot be empty")
|
||||
}
|
||||
|
||||
p := &ClusterTrustBundlePublisher{
|
||||
p := &ClusterTrustBundlePublisher[T]{
|
||||
signerName: signerName,
|
||||
ca: caProvider,
|
||||
client: kubeClient,
|
||||
client: bundleClient,
|
||||
|
||||
ctbInformer: ctbInformer,
|
||||
ctbLister: ctbLister,
|
||||
ctbListerSynced: ctbInformer.HasSynced,
|
||||
|
||||
handlers: handlers,
|
||||
|
||||
queue: workqueue.NewTypedRateLimitingQueueWithConfig(
|
||||
workqueue.DefaultTypedControllerRateLimiter[string](),
|
||||
@@ -86,9 +244,6 @@ func NewClusterTrustBundlePublisher(
|
||||
},
|
||||
),
|
||||
}
|
||||
p.ctbInformer = setupSignerNameFilteredCTBInformer(p.client, p.signerName)
|
||||
p.ctbLister = certlisters.NewClusterTrustBundleLister(p.ctbInformer.GetIndexer())
|
||||
p.ctbListerSynced = p.ctbInformer.HasSynced
|
||||
|
||||
_, err := p.ctbInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
@@ -109,13 +264,13 @@ func NewClusterTrustBundlePublisher(
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (p *ClusterTrustBundlePublisher) caContentChangedListener() dynamiccertificates.Listener {
|
||||
func (p *ClusterTrustBundlePublisher[T]) caContentChangedListener() dynamiccertificates.Listener {
|
||||
return caContentListener(func() {
|
||||
p.queue.Add("")
|
||||
})
|
||||
}
|
||||
|
||||
func (p *ClusterTrustBundlePublisher) Run(ctx context.Context) {
|
||||
func (p *ClusterTrustBundlePublisher[T]) Run(ctx context.Context) {
|
||||
defer utilruntime.HandleCrash()
|
||||
defer p.queue.ShutDown()
|
||||
|
||||
@@ -136,7 +291,7 @@ func (p *ClusterTrustBundlePublisher) Run(ctx context.Context) {
|
||||
<-ctx.Done()
|
||||
}
|
||||
|
||||
func (p *ClusterTrustBundlePublisher) runWorker() func(context.Context) {
|
||||
func (p *ClusterTrustBundlePublisher[T]) runWorker() func(context.Context) {
|
||||
return func(ctx context.Context) {
|
||||
for p.processNextWorkItem(ctx) {
|
||||
}
|
||||
@@ -145,7 +300,7 @@ func (p *ClusterTrustBundlePublisher) runWorker() func(context.Context) {
|
||||
|
||||
// processNextWorkItem deals with one key off the queue. It returns false when
|
||||
// it's time to quit.
|
||||
func (p *ClusterTrustBundlePublisher) processNextWorkItem(ctx context.Context) bool {
|
||||
func (p *ClusterTrustBundlePublisher[T]) processNextWorkItem(ctx context.Context) bool {
|
||||
key, quit := p.queue.Get()
|
||||
if quit {
|
||||
return false
|
||||
@@ -162,7 +317,7 @@ func (p *ClusterTrustBundlePublisher) processNextWorkItem(ctx context.Context) b
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *ClusterTrustBundlePublisher) syncClusterTrustBundle(ctx context.Context) (err error) {
|
||||
func (p *ClusterTrustBundlePublisher[T]) syncClusterTrustBundle(ctx context.Context) (err error) {
|
||||
startTime := time.Now()
|
||||
defer func() {
|
||||
recordMetrics(startTime, err)
|
||||
@@ -174,19 +329,10 @@ func (p *ClusterTrustBundlePublisher) syncClusterTrustBundle(ctx context.Context
|
||||
|
||||
bundle, err := p.ctbLister.Get(bundleName)
|
||||
if apierrors.IsNotFound(err) {
|
||||
_, err = p.client.CertificatesV1alpha1().ClusterTrustBundles().Create(ctx, &certificatesv1alpha1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: bundleName,
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
SignerName: p.signerName,
|
||||
TrustBundle: caBundle,
|
||||
},
|
||||
}, metav1.CreateOptions{})
|
||||
} else if err == nil && bundle.Spec.TrustBundle != caBundle {
|
||||
bundle = bundle.DeepCopy()
|
||||
bundle.Spec.TrustBundle = caBundle
|
||||
_, err = p.client.CertificatesV1alpha1().ClusterTrustBundles().Update(ctx, bundle, metav1.UpdateOptions{})
|
||||
_, err = p.client.Create(ctx, p.handlers.createClusterTrustBundle(bundleName, p.signerName, caBundle), metav1.CreateOptions{})
|
||||
} else if err == nil && !p.handlers.containsTrustBundle(bundle, caBundle) {
|
||||
updatedBundle := p.handlers.updateWithTrustBundle(bundle, caBundle)
|
||||
_, err = p.client.Update(ctx, updatedBundle, metav1.UpdateOptions{})
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -201,12 +347,13 @@ func (p *ClusterTrustBundlePublisher) syncClusterTrustBundle(ctx context.Context
|
||||
// keep the deletion error to be returned in the end in order to retrigger the reconciliation loop
|
||||
var deletionError error
|
||||
for _, bundleObject := range signerTrustBundles {
|
||||
if bundleObject.Name == bundleName {
|
||||
if p.handlers.getName(bundleObject) == bundleName {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := p.client.CertificatesV1alpha1().ClusterTrustBundles().Delete(ctx, bundleObject.Name, metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) {
|
||||
klog.FromContext(ctx).Error(err, "failed to remove a cluster trust bundle", "bundleName", bundleObject.Name)
|
||||
deleteName := p.handlers.getName(bundleObject)
|
||||
if err := p.client.Delete(ctx, deleteName, metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) {
|
||||
klog.FromContext(ctx).Error(err, "failed to remove a cluster trust bundle", "bundleName", deleteName)
|
||||
deletionError = err
|
||||
}
|
||||
}
|
||||
@@ -214,13 +361,6 @@ func (p *ClusterTrustBundlePublisher) syncClusterTrustBundle(ctx context.Context
|
||||
return deletionError
|
||||
}
|
||||
|
||||
func setupSignerNameFilteredCTBInformer(client clientset.Interface, signerName string) cache.SharedIndexInformer {
|
||||
return certinformers.NewFilteredClusterTrustBundleInformer(client, 0, cache.Indexers{},
|
||||
func(options *metav1.ListOptions) {
|
||||
options.FieldSelector = fields.OneTermEqualSelector("spec.signerName", signerName).String()
|
||||
})
|
||||
}
|
||||
|
||||
func constructBundleName(signerName string, bundleBytes []byte) string {
|
||||
namePrefix := strings.ReplaceAll(signerName, "/", ":") + ":"
|
||||
bundleHash := sha256.Sum256(bundleBytes)
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
cryptorand "crypto/rand"
|
||||
"testing"
|
||||
|
||||
certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1"
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/server/dynamiccertificates"
|
||||
@@ -44,7 +44,7 @@ func TestCTBPublisherSync(t *testing.T) {
|
||||
|
||||
createAction := expectAction[clienttesting.CreateAction](t, filteredActions[0], "create")
|
||||
|
||||
ctb, ok := createAction.GetObject().(*certificatesv1alpha1.ClusterTrustBundle)
|
||||
ctb, ok := createAction.GetObject().(*certificatesv1beta1.ClusterTrustBundle)
|
||||
if !ok {
|
||||
t.Fatalf("expected ClusterTrustBundle create, got %v", createAction.GetObject())
|
||||
}
|
||||
@@ -63,7 +63,7 @@ func TestCTBPublisherSync(t *testing.T) {
|
||||
|
||||
updateAction := expectAction[clienttesting.UpdateAction](t, filteredActions[0], "update")
|
||||
|
||||
ctb, ok := updateAction.GetObject().(*certificatesv1alpha1.ClusterTrustBundle)
|
||||
ctb, ok := updateAction.GetObject().(*certificatesv1beta1.ClusterTrustBundle)
|
||||
if !ok {
|
||||
t.Fatalf("expected ClusterTrustBundle update, got %v", updateAction.GetObject())
|
||||
}
|
||||
@@ -109,19 +109,19 @@ func TestCTBPublisherSync(t *testing.T) {
|
||||
{
|
||||
name: "no CTBs for the current signer exist",
|
||||
existingCTBs: []runtime.Object{
|
||||
&certificatesv1alpha1.ClusterTrustBundle{
|
||||
&certificatesv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "nosigner",
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certificatesv1beta1.ClusterTrustBundleSpec{
|
||||
TrustBundle: "somedatahere",
|
||||
},
|
||||
},
|
||||
&certificatesv1alpha1.ClusterTrustBundle{
|
||||
&certificatesv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "signer:one",
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certificatesv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: "signer",
|
||||
TrustBundle: "signerdata",
|
||||
},
|
||||
@@ -132,11 +132,11 @@ func TestCTBPublisherSync(t *testing.T) {
|
||||
{
|
||||
name: "CTB for the signer exists with different content",
|
||||
existingCTBs: []runtime.Object{
|
||||
&certificatesv1alpha1.ClusterTrustBundle{
|
||||
&certificatesv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: testBundleName,
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certificatesv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: testSignerName,
|
||||
TrustBundle: "olddata",
|
||||
},
|
||||
@@ -147,20 +147,20 @@ func TestCTBPublisherSync(t *testing.T) {
|
||||
{
|
||||
name: "multiple CTBs for the signer",
|
||||
existingCTBs: []runtime.Object{
|
||||
&certificatesv1alpha1.ClusterTrustBundle{
|
||||
&certificatesv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: testBundleName,
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certificatesv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: testSignerName,
|
||||
TrustBundle: string(testCAProvider.CurrentCABundleContent()),
|
||||
},
|
||||
},
|
||||
&certificatesv1alpha1.ClusterTrustBundle{
|
||||
&certificatesv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test.test/testSigner:name2",
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certificatesv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: testSignerName,
|
||||
TrustBundle: string(testCAProvider.CurrentCABundleContent()),
|
||||
},
|
||||
@@ -171,20 +171,20 @@ func TestCTBPublisherSync(t *testing.T) {
|
||||
{
|
||||
name: "multiple CTBs for the signer - the one with the proper name needs changing",
|
||||
existingCTBs: []runtime.Object{
|
||||
&certificatesv1alpha1.ClusterTrustBundle{
|
||||
&certificatesv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: testBundleName,
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certificatesv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: testSignerName,
|
||||
TrustBundle: "olddata",
|
||||
},
|
||||
},
|
||||
&certificatesv1alpha1.ClusterTrustBundle{
|
||||
&certificatesv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test.test/testSigner:name2",
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certificatesv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: testSignerName,
|
||||
TrustBundle: string(testCAProvider.CurrentCABundleContent()),
|
||||
},
|
||||
@@ -202,11 +202,11 @@ func TestCTBPublisherSync(t *testing.T) {
|
||||
{
|
||||
name: "another CTB with a different name exists for the signer",
|
||||
existingCTBs: []runtime.Object{
|
||||
&certificatesv1alpha1.ClusterTrustBundle{
|
||||
&certificatesv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test.test/testSigner:preexisting",
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certificatesv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: testSignerName,
|
||||
TrustBundle: string(testCAProvider.CurrentCABundleContent()),
|
||||
},
|
||||
@@ -224,28 +224,28 @@ func TestCTBPublisherSync(t *testing.T) {
|
||||
{
|
||||
name: "CTB at the correct state - noop",
|
||||
existingCTBs: []runtime.Object{
|
||||
&certificatesv1alpha1.ClusterTrustBundle{
|
||||
&certificatesv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "nosigner",
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certificatesv1beta1.ClusterTrustBundleSpec{
|
||||
TrustBundle: "somedatahere",
|
||||
},
|
||||
},
|
||||
&certificatesv1alpha1.ClusterTrustBundle{
|
||||
&certificatesv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "signer:one",
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certificatesv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: "signer",
|
||||
TrustBundle: "signerdata",
|
||||
},
|
||||
},
|
||||
&certificatesv1alpha1.ClusterTrustBundle{
|
||||
&certificatesv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: testBundleName,
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certificatesv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: testSignerName,
|
||||
TrustBundle: string(testCAProvider.CurrentCABundleContent()),
|
||||
},
|
||||
@@ -264,17 +264,22 @@ func TestCTBPublisherSync(t *testing.T) {
|
||||
|
||||
fakeClient := fakeKubeClientSetWithCTBList(t, testSignerName, tt.existingCTBs...)
|
||||
|
||||
p, err := NewClusterTrustBundlePublisher(testSignerName, testCAProvider, fakeClient)
|
||||
p, err := NewBetaClusterTrustBundlePublisher(testSignerName, testCAProvider, fakeClient)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to set up a new cluster trust bundle publisher: %v", err)
|
||||
}
|
||||
|
||||
go p.ctbInformer.Run(testCtx.Done())
|
||||
if !cache.WaitForCacheSync(testCtx.Done(), p.ctbInformer.HasSynced) {
|
||||
controller, ok := p.(*ClusterTrustBundlePublisher[certificatesv1beta1.ClusterTrustBundle])
|
||||
if !ok {
|
||||
t.Fatalf("failed to assert the controller for the beta API")
|
||||
}
|
||||
|
||||
go controller.ctbInformer.Run(testCtx.Done())
|
||||
if !cache.WaitForCacheSync(testCtx.Done(), controller.ctbInformer.HasSynced) {
|
||||
t.Fatal("timed out waiting for informer to sync")
|
||||
}
|
||||
|
||||
if err := p.syncClusterTrustBundle(testCtx); (err != nil) != tt.wantErr {
|
||||
if err := controller.syncClusterTrustBundle(testCtx); (err != nil) != tt.wantErr {
|
||||
t.Errorf("syncClusterTrustBundle() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
|
||||
@@ -297,9 +302,9 @@ func fakeKubeClientSetWithCTBList(t *testing.T, signerName string, ctbs ...runti
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
retList := &certificatesv1alpha1.ClusterTrustBundleList{}
|
||||
retList := &certificatesv1beta1.ClusterTrustBundleList{}
|
||||
for _, ctb := range ctbs {
|
||||
ctbObj, ok := ctb.(*certificatesv1alpha1.ClusterTrustBundle)
|
||||
ctbObj, ok := ctb.(*certificatesv1beta1.ClusterTrustBundle)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -277,6 +277,7 @@ func DefaultGenericAPIServicePriorities() map[schema.GroupVersion]APIServicePrio
|
||||
{Group: "authentication.k8s.io", Version: "v1alpha1"}: {Group: 17700, Version: 1},
|
||||
{Group: "authorization.k8s.io", Version: "v1"}: {Group: 17600, Version: 15},
|
||||
{Group: "certificates.k8s.io", Version: "v1"}: {Group: 17300, Version: 15},
|
||||
{Group: "certificates.k8s.io", Version: "v1beta1"}: {Group: 17300, Version: 9},
|
||||
{Group: "certificates.k8s.io", Version: "v1alpha1"}: {Group: 17300, Version: 1},
|
||||
{Group: "rbac.authorization.k8s.io", Version: "v1"}: {Group: 17000, Version: 15},
|
||||
{Group: "apiextensions.k8s.io", Version: "v1"}: {Group: 16700, Version: 15},
|
||||
|
||||
@@ -37,6 +37,7 @@ import (
|
||||
batchapiv1 "k8s.io/api/batch/v1"
|
||||
certificatesapiv1 "k8s.io/api/certificates/v1"
|
||||
certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1"
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
coordinationapiv1 "k8s.io/api/coordination/v1"
|
||||
coordinationv1alpha2 "k8s.io/api/coordination/v1alpha2"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
@@ -457,6 +458,7 @@ var (
|
||||
betaAPIGroupVersionsDisabledByDefault = []schema.GroupVersion{
|
||||
admissionregistrationv1beta1.SchemeGroupVersion,
|
||||
authenticationv1beta1.SchemeGroupVersion,
|
||||
certificatesv1beta1.SchemeGroupVersion,
|
||||
storageapiv1beta1.SchemeGroupVersion,
|
||||
flowcontrolv1beta1.SchemeGroupVersion,
|
||||
flowcontrolv1beta2.SchemeGroupVersion,
|
||||
|
||||
@@ -74,10 +74,12 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
|
||||
|
||||
ClusterTrustBundle: {
|
||||
{Version: version.MustParse("1.27"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
ClusterTrustBundleProjection: {
|
||||
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Beta},
|
||||
},
|
||||
|
||||
ContainerCheckpoint: {
|
||||
|
||||
127
pkg/generated/openapi/zz_generated.openapi.go
generated
127
pkg/generated/openapi/zz_generated.openapi.go
generated
@@ -382,6 +382,9 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
|
||||
"k8s.io/api/certificates/v1beta1.CertificateSigningRequestList": schema_k8sio_api_certificates_v1beta1_CertificateSigningRequestList(ref),
|
||||
"k8s.io/api/certificates/v1beta1.CertificateSigningRequestSpec": schema_k8sio_api_certificates_v1beta1_CertificateSigningRequestSpec(ref),
|
||||
"k8s.io/api/certificates/v1beta1.CertificateSigningRequestStatus": schema_k8sio_api_certificates_v1beta1_CertificateSigningRequestStatus(ref),
|
||||
"k8s.io/api/certificates/v1beta1.ClusterTrustBundle": schema_k8sio_api_certificates_v1beta1_ClusterTrustBundle(ref),
|
||||
"k8s.io/api/certificates/v1beta1.ClusterTrustBundleList": schema_k8sio_api_certificates_v1beta1_ClusterTrustBundleList(ref),
|
||||
"k8s.io/api/certificates/v1beta1.ClusterTrustBundleSpec": schema_k8sio_api_certificates_v1beta1_ClusterTrustBundleSpec(ref),
|
||||
"k8s.io/api/coordination/v1.Lease": schema_k8sio_api_coordination_v1_Lease(ref),
|
||||
"k8s.io/api/coordination/v1.LeaseList": schema_k8sio_api_coordination_v1_LeaseList(ref),
|
||||
"k8s.io/api/coordination/v1.LeaseSpec": schema_k8sio_api_coordination_v1_LeaseSpec(ref),
|
||||
@@ -19239,6 +19242,130 @@ func schema_k8sio_api_certificates_v1beta1_CertificateSigningRequestStatus(ref c
|
||||
}
|
||||
}
|
||||
|
||||
func schema_k8sio_api_certificates_v1beta1_ClusterTrustBundle(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "ClusterTrustBundle is a cluster-scoped container for X.509 trust anchors (root certificates).\n\nClusterTrustBundle objects are considered to be readable by any authenticated user in the cluster, because they can be mounted by pods using the `clusterTrustBundle` projection. All service accounts have read access to ClusterTrustBundles by default. Users who only have namespace-level access to a cluster can read ClusterTrustBundles by impersonating a serviceaccount that they have access to.\n\nIt can be optionally associated with a particular assigner, in which case it contains one valid set of trust anchors for that signer. Signers may have multiple associated ClusterTrustBundles; each is an independent set of trust anchors for that signer. Admission control is used to enforce that only users with permissions on the signer can create or modify the corresponding bundle.",
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"kind": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
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{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"apiVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"metadata": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "metadata contains the object metadata.",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
|
||||
},
|
||||
},
|
||||
"spec": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "spec contains the signer (if any) and trust anchors.",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/api/certificates/v1beta1.ClusterTrustBundleSpec"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"spec"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"k8s.io/api/certificates/v1beta1.ClusterTrustBundleSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_k8sio_api_certificates_v1beta1_ClusterTrustBundleList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "ClusterTrustBundleList is a collection of ClusterTrustBundle objects",
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"kind": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
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{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"apiVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"metadata": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "metadata contains the list metadata.",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"),
|
||||
},
|
||||
},
|
||||
"items": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "items is a collection of ClusterTrustBundle objects",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/api/certificates/v1beta1.ClusterTrustBundle"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"items"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"k8s.io/api/certificates/v1beta1.ClusterTrustBundle", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_k8sio_api_certificates_v1beta1_ClusterTrustBundleSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "ClusterTrustBundleSpec contains the signer and trust anchors.",
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"signerName": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "signerName indicates the associated signer, if any.\n\nIn order to create or update a ClusterTrustBundle that sets signerName, you must have the following cluster-scoped permission: group=certificates.k8s.io resource=signers resourceName=<the signer name> verb=attest.\n\nIf signerName is not empty, then the ClusterTrustBundle object must be named with the signer name as a prefix (translating slashes to colons). For example, for the signer name `example.com/foo`, valid ClusterTrustBundle object names include `example.com:foo:abc` and `example.com:foo:v1`.\n\nIf signerName is empty, then the ClusterTrustBundle object's name must not have such a prefix.\n\nList/watch requests for ClusterTrustBundles can filter on this field using a `spec.signerName=NAME` field selector.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"trustBundle": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "trustBundle contains the individual X.509 trust anchors for this bundle, as PEM bundle of PEM-wrapped, DER-formatted X.509 certificates.\n\nThe data must consist only of PEM certificate blocks that parse as valid X.509 certificates. Each certificate must include a basic constraints extension with the CA bit set. The API server will reject objects that contain duplicate certificates, or that use PEM block headers.\n\nUsers of ClusterTrustBundles, including Kubelet, are free to reorder and deduplicate certificate blocks in this file according to their own logic, as well as to drop PEM block headers and inter-block data.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"trustBundle"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_k8sio_api_coordination_v1_Lease(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
|
||||
@@ -86,7 +86,7 @@ func NewStorageFactoryConfigEffectiveVersion(effectiveVersion basecompatibility.
|
||||
networking.Resource("servicecidrs").WithVersion("v1beta1"),
|
||||
admissionregistration.Resource("mutatingadmissionpolicies").WithVersion("v1alpha1"),
|
||||
admissionregistration.Resource("mutatingadmissionpolicybindings").WithVersion("v1alpha1"),
|
||||
certificates.Resource("clustertrustbundles").WithVersion("v1alpha1"),
|
||||
certificates.Resource("clustertrustbundles").WithVersion("v1beta1"),
|
||||
storage.Resource("volumeattributesclasses").WithVersion("v1beta1"),
|
||||
storagemigration.Resource("storagemigrations").WithVersion("v1alpha1"),
|
||||
}
|
||||
|
||||
@@ -23,15 +23,20 @@ import (
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1"
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
lrucache "k8s.io/apimachinery/pkg/util/cache"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
certinformersv1alpha1 "k8s.io/client-go/informers/certificates/v1alpha1"
|
||||
certlistersv1alpha1 "k8s.io/client-go/listers/certificates/v1alpha1"
|
||||
"k8s.io/client-go/informers"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
@@ -40,6 +45,51 @@ const (
|
||||
maxLabelSelectorLength = 100 * 1024
|
||||
)
|
||||
|
||||
// clusterTrustBundle is a type constraint for version-independent ClusterTrustBundle API
|
||||
type clusterTrustBundle interface {
|
||||
certificatesv1alpha1.ClusterTrustBundle | certificatesv1beta1.ClusterTrustBundle
|
||||
}
|
||||
|
||||
// clusterTrustBundlesLister is an API-verion independent ClusterTrustBundles lister
|
||||
type clusterTrustBundlesLister[T clusterTrustBundle] interface {
|
||||
Get(string) (*T, error)
|
||||
List(labels.Selector) ([]*T, error)
|
||||
}
|
||||
|
||||
type clusterTrustBundleHandlers[T clusterTrustBundle] interface {
|
||||
GetName(*T) string
|
||||
GetSignerName(*T) string
|
||||
GetTrustBundle(*T) string
|
||||
}
|
||||
|
||||
type alphaClusterTrustBundleHandlers struct{}
|
||||
|
||||
type betaClusterTrustBundleHandlers struct{}
|
||||
|
||||
func (b *alphaClusterTrustBundleHandlers) GetName(ctb *certificatesv1alpha1.ClusterTrustBundle) string {
|
||||
return ctb.Name
|
||||
}
|
||||
|
||||
func (b *alphaClusterTrustBundleHandlers) GetSignerName(ctb *certificatesv1alpha1.ClusterTrustBundle) string {
|
||||
return ctb.Spec.SignerName
|
||||
}
|
||||
|
||||
func (b *alphaClusterTrustBundleHandlers) GetTrustBundle(ctb *certificatesv1alpha1.ClusterTrustBundle) string {
|
||||
return ctb.Spec.TrustBundle
|
||||
}
|
||||
|
||||
func (b betaClusterTrustBundleHandlers) GetName(ctb *certificatesv1beta1.ClusterTrustBundle) string {
|
||||
return ctb.Name
|
||||
}
|
||||
|
||||
func (b *betaClusterTrustBundleHandlers) GetSignerName(ctb *certificatesv1beta1.ClusterTrustBundle) string {
|
||||
return ctb.Spec.SignerName
|
||||
}
|
||||
|
||||
func (b *betaClusterTrustBundleHandlers) GetTrustBundle(ctb *certificatesv1beta1.ClusterTrustBundle) string {
|
||||
return ctb.Spec.TrustBundle
|
||||
}
|
||||
|
||||
// Manager abstracts over the ability to get trust anchors.
|
||||
type Manager interface {
|
||||
GetTrustAnchorsByName(name string, allowMissing bool) ([]byte, error)
|
||||
@@ -48,23 +98,44 @@ type Manager interface {
|
||||
|
||||
// InformerManager is the "real" manager. It uses informers to track
|
||||
// ClusterTrustBundle objects.
|
||||
type InformerManager struct {
|
||||
type InformerManager[T clusterTrustBundle] struct {
|
||||
ctbInformer cache.SharedIndexInformer
|
||||
ctbLister certlistersv1alpha1.ClusterTrustBundleLister
|
||||
ctbLister clusterTrustBundlesLister[T]
|
||||
|
||||
ctbHandlers clusterTrustBundleHandlers[T]
|
||||
|
||||
normalizationCache *lrucache.LRUExpireCache
|
||||
cacheTTL time.Duration
|
||||
}
|
||||
|
||||
var _ Manager = (*InformerManager)(nil)
|
||||
var _ Manager = (*InformerManager[certificatesv1beta1.ClusterTrustBundle])(nil)
|
||||
|
||||
// NewInformerManager returns an initialized InformerManager.
|
||||
func NewInformerManager(ctx context.Context, bundles certinformersv1alpha1.ClusterTrustBundleInformer, cacheSize int, cacheTTL time.Duration) (*InformerManager, error) {
|
||||
func NewAlphaInformerManager(
|
||||
ctx context.Context, informerFactory informers.SharedInformerFactory, cacheSize int, cacheTTL time.Duration,
|
||||
) (Manager, error) {
|
||||
bundlesInformer := informerFactory.Certificates().V1alpha1().ClusterTrustBundles()
|
||||
return newInformerManager(
|
||||
ctx, &alphaClusterTrustBundleHandlers{}, bundlesInformer.Informer(), bundlesInformer.Lister(), cacheSize, cacheTTL,
|
||||
)
|
||||
}
|
||||
|
||||
func NewBetaInformerManager(
|
||||
ctx context.Context, informerFactory informers.SharedInformerFactory, cacheSize int, cacheTTL time.Duration,
|
||||
) (Manager, error) {
|
||||
bundlesInformer := informerFactory.Certificates().V1beta1().ClusterTrustBundles()
|
||||
return newInformerManager(
|
||||
ctx, &betaClusterTrustBundleHandlers{}, bundlesInformer.Informer(), bundlesInformer.Lister(), cacheSize, cacheTTL,
|
||||
)
|
||||
}
|
||||
|
||||
// newInformerManager returns an initialized InformerManager.
|
||||
func newInformerManager[T clusterTrustBundle](ctx context.Context, handlers clusterTrustBundleHandlers[T], informer cache.SharedIndexInformer, lister clusterTrustBundlesLister[T], cacheSize int, cacheTTL time.Duration) (Manager, error) {
|
||||
// We need to call Informer() before calling start on the shared informer
|
||||
// factory, or the informer won't be registered to be started.
|
||||
m := &InformerManager{
|
||||
ctbInformer: bundles.Informer(),
|
||||
ctbLister: bundles.Lister(),
|
||||
m := &InformerManager[T]{
|
||||
ctbInformer: informer,
|
||||
ctbLister: lister,
|
||||
ctbHandlers: handlers,
|
||||
normalizationCache: lrucache.NewLRUExpireCache(cacheSize),
|
||||
cacheTTL: cacheTTL,
|
||||
}
|
||||
@@ -74,34 +145,34 @@ func NewInformerManager(ctx context.Context, bundles certinformersv1alpha1.Clust
|
||||
// apply to them.
|
||||
_, err := m.ctbInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj any) {
|
||||
ctb, ok := obj.(*certificatesv1alpha1.ClusterTrustBundle)
|
||||
ctb, ok := obj.(*T)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
logger.Info("Dropping all cache entries for signer", "signerName", ctb.Spec.SignerName)
|
||||
logger.Info("Dropping all cache entries for signer", "signerName", m.ctbHandlers.GetSignerName(ctb))
|
||||
m.dropCacheFor(ctb)
|
||||
},
|
||||
UpdateFunc: func(old, new any) {
|
||||
ctb, ok := new.(*certificatesv1alpha1.ClusterTrustBundle)
|
||||
ctb, ok := new.(*T)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
logger.Info("Dropping cache for ClusterTrustBundle", "signerName", ctb.Spec.SignerName)
|
||||
m.dropCacheFor(new.(*certificatesv1alpha1.ClusterTrustBundle))
|
||||
logger.Info("Dropping cache for ClusterTrustBundle", "signerName", m.ctbHandlers.GetSignerName(ctb))
|
||||
m.dropCacheFor(new.(*T))
|
||||
},
|
||||
DeleteFunc: func(obj any) {
|
||||
ctb, ok := obj.(*certificatesv1alpha1.ClusterTrustBundle)
|
||||
ctb, ok := obj.(*T)
|
||||
if !ok {
|
||||
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
ctb, ok = tombstone.Obj.(*certificatesv1alpha1.ClusterTrustBundle)
|
||||
ctb, ok = tombstone.Obj.(*T)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
}
|
||||
logger.Info("Dropping cache for ClusterTrustBundle", "signerName", ctb.Spec.SignerName)
|
||||
logger.Info("Dropping cache for ClusterTrustBundle", "signerName", m.ctbHandlers.GetSignerName(ctb))
|
||||
m.dropCacheFor(ctb)
|
||||
},
|
||||
})
|
||||
@@ -112,21 +183,21 @@ func NewInformerManager(ctx context.Context, bundles certinformersv1alpha1.Clust
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (m *InformerManager) dropCacheFor(ctb *certificatesv1alpha1.ClusterTrustBundle) {
|
||||
if ctb.Spec.SignerName != "" {
|
||||
func (m *InformerManager[T]) dropCacheFor(ctb *T) {
|
||||
if ctbSignerName := m.ctbHandlers.GetSignerName(ctb); ctbSignerName != "" {
|
||||
m.normalizationCache.RemoveAll(func(key any) bool {
|
||||
return key.(cacheKeyType).signerName == ctb.Spec.SignerName
|
||||
return key.(cacheKeyType).signerName == ctbSignerName
|
||||
})
|
||||
} else {
|
||||
m.normalizationCache.RemoveAll(func(key any) bool {
|
||||
return key.(cacheKeyType).ctbName == ctb.ObjectMeta.Name
|
||||
return key.(cacheKeyType).ctbName == m.ctbHandlers.GetName(ctb)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// GetTrustAnchorsByName returns normalized and deduplicated trust anchors from
|
||||
// a single named ClusterTrustBundle.
|
||||
func (m *InformerManager) GetTrustAnchorsByName(name string, allowMissing bool) ([]byte, error) {
|
||||
func (m *InformerManager[T]) GetTrustAnchorsByName(name string, allowMissing bool) ([]byte, error) {
|
||||
if !m.ctbInformer.HasSynced() {
|
||||
return nil, fmt.Errorf("ClusterTrustBundle informer has not yet synced")
|
||||
}
|
||||
@@ -145,7 +216,7 @@ func (m *InformerManager) GetTrustAnchorsByName(name string, allowMissing bool)
|
||||
return nil, fmt.Errorf("while getting ClusterTrustBundle: %w", err)
|
||||
}
|
||||
|
||||
pemTrustAnchors, err := m.normalizeTrustAnchors([]*certificatesv1alpha1.ClusterTrustBundle{ctb})
|
||||
pemTrustAnchors, err := m.normalizeTrustAnchors([]*T{ctb})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("while normalizing trust anchors: %w", err)
|
||||
}
|
||||
@@ -157,7 +228,7 @@ func (m *InformerManager) GetTrustAnchorsByName(name string, allowMissing bool)
|
||||
|
||||
// GetTrustAnchorsBySigner returns normalized and deduplicated trust anchors
|
||||
// from a set of selected ClusterTrustBundles.
|
||||
func (m *InformerManager) GetTrustAnchorsBySigner(signerName string, labelSelector *metav1.LabelSelector, allowMissing bool) ([]byte, error) {
|
||||
func (m *InformerManager[T]) GetTrustAnchorsBySigner(signerName string, labelSelector *metav1.LabelSelector, allowMissing bool) ([]byte, error) {
|
||||
if !m.ctbInformer.HasSynced() {
|
||||
return nil, fmt.Errorf("ClusterTrustBundle informer has not yet synced")
|
||||
}
|
||||
@@ -184,9 +255,9 @@ func (m *InformerManager) GetTrustAnchorsBySigner(signerName string, labelSelect
|
||||
return nil, fmt.Errorf("while listing ClusterTrustBundles matching label selector %v: %w", labelSelector, err)
|
||||
}
|
||||
|
||||
ctbList := []*certificatesv1alpha1.ClusterTrustBundle{}
|
||||
ctbList := []*T{}
|
||||
for _, ctb := range rawCTBList {
|
||||
if ctb.Spec.SignerName == signerName {
|
||||
if m.ctbHandlers.GetSignerName(ctb) == signerName {
|
||||
ctbList = append(ctbList, ctb)
|
||||
}
|
||||
}
|
||||
@@ -208,11 +279,11 @@ func (m *InformerManager) GetTrustAnchorsBySigner(signerName string, labelSelect
|
||||
return pemTrustAnchors, nil
|
||||
}
|
||||
|
||||
func (m *InformerManager) normalizeTrustAnchors(ctbList []*certificatesv1alpha1.ClusterTrustBundle) ([]byte, error) {
|
||||
func (m *InformerManager[T]) normalizeTrustAnchors(ctbList []*T) ([]byte, error) {
|
||||
// Deduplicate trust anchors from all ClusterTrustBundles.
|
||||
trustAnchorSet := sets.Set[string]{}
|
||||
for _, ctb := range ctbList {
|
||||
rest := []byte(ctb.Spec.TrustBundle)
|
||||
rest := []byte(m.ctbHandlers.GetTrustBundle(ctb))
|
||||
var b *pem.Block
|
||||
for {
|
||||
b, rest = pem.Decode(rest)
|
||||
@@ -261,3 +332,133 @@ func (m *NoopManager) GetTrustAnchorsByName(name string, allowMissing bool) ([]b
|
||||
func (m *NoopManager) GetTrustAnchorsBySigner(signerName string, labelSelector *metav1.LabelSelector, allowMissing bool) ([]byte, error) {
|
||||
return nil, fmt.Errorf("ClusterTrustBundle projection is not supported in static kubelet mode")
|
||||
}
|
||||
|
||||
// LazyInformerManager decides whether to use the noop or the actual manager on a call to
|
||||
// the manager's methods.
|
||||
// We cannot determine this upon startup because some may rely on the kubelet to be fully
|
||||
// running in order to setup their kube-apiserver.
|
||||
type LazyInformerManager struct {
|
||||
manager Manager
|
||||
managerLock sync.RWMutex
|
||||
client clientset.Interface
|
||||
cacheSize int
|
||||
contextWithLogger context.Context
|
||||
logger logr.Logger
|
||||
}
|
||||
|
||||
func NewLazyInformerManager(ctx context.Context, kubeClient clientset.Interface, cacheSize int) Manager {
|
||||
return &LazyInformerManager{
|
||||
client: kubeClient,
|
||||
cacheSize: cacheSize,
|
||||
contextWithLogger: ctx,
|
||||
logger: klog.FromContext(ctx),
|
||||
managerLock: sync.RWMutex{},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *LazyInformerManager) GetTrustAnchorsByName(name string, allowMissing bool) ([]byte, error) {
|
||||
if err := m.ensureManagerSet(); err != nil {
|
||||
return nil, fmt.Errorf("failed to ensure informer manager for ClusterTrustBundles: %w", err)
|
||||
}
|
||||
return m.manager.GetTrustAnchorsByName(name, allowMissing)
|
||||
}
|
||||
|
||||
func (m *LazyInformerManager) GetTrustAnchorsBySigner(signerName string, labelSelector *metav1.LabelSelector, allowMissing bool) ([]byte, error) {
|
||||
if err := m.ensureManagerSet(); err != nil {
|
||||
return nil, fmt.Errorf("failed to ensure informer manager for ClusterTrustBundles: %w", err)
|
||||
}
|
||||
return m.manager.GetTrustAnchorsBySigner(signerName, labelSelector, allowMissing)
|
||||
}
|
||||
|
||||
func (m *LazyInformerManager) isManagerSet() bool {
|
||||
m.managerLock.RLock()
|
||||
defer m.managerLock.RUnlock()
|
||||
return m.manager != nil
|
||||
}
|
||||
|
||||
type managerConstructor func(ctx context.Context, informerFactory informers.SharedInformerFactory, cacheSize int, cacheTTL time.Duration) (Manager, error)
|
||||
|
||||
func (m *LazyInformerManager) ensureManagerSet() error {
|
||||
if m.isManagerSet() {
|
||||
return nil
|
||||
}
|
||||
|
||||
m.managerLock.Lock()
|
||||
defer m.managerLock.Unlock()
|
||||
// we need to check again in case the manager was set between locking
|
||||
if m.manager != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
managerSchema := map[schema.GroupVersion]managerConstructor{
|
||||
certificatesv1alpha1.SchemeGroupVersion: NewAlphaInformerManager,
|
||||
certificatesv1beta1.SchemeGroupVersion: NewBetaInformerManager,
|
||||
}
|
||||
|
||||
kubeInformers := informers.NewSharedInformerFactoryWithOptions(m.client, 0)
|
||||
|
||||
var clusterTrustBundleManager Manager
|
||||
var foundGV string
|
||||
for _, gv := range []schema.GroupVersion{certificatesv1beta1.SchemeGroupVersion, certificatesv1alpha1.SchemeGroupVersion} {
|
||||
ctbAPIAvailable, err := clusterTrustBundlesAvailable(m.client, gv)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to determine which informer manager to choose: %w", err)
|
||||
}
|
||||
|
||||
if !ctbAPIAvailable {
|
||||
continue
|
||||
}
|
||||
|
||||
clusterTrustBundleManager, err = managerSchema[gv](m.contextWithLogger, kubeInformers, m.cacheSize, 5*time.Minute)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error starting informer-based ClusterTrustBundle manager: %w", err)
|
||||
}
|
||||
foundGV = gv.String()
|
||||
break
|
||||
}
|
||||
|
||||
if clusterTrustBundleManager == nil {
|
||||
m.manager = &NoopManager{}
|
||||
m.logger.Info("No version of the ClusterTrustBundle API was found, the ClusterTrustBundle informer won't be started")
|
||||
return nil
|
||||
}
|
||||
|
||||
m.manager = clusterTrustBundleManager
|
||||
kubeInformers.Start(m.contextWithLogger.Done())
|
||||
m.logger.Info("Started ClusterTrustBundle informer", "apiGroup", foundGV)
|
||||
|
||||
// a cache fetch will likely follow right after, wait for the freshly started
|
||||
// informers to sync
|
||||
synced := true
|
||||
timeoutContext, cancel := context.WithTimeout(m.contextWithLogger, 10*time.Second)
|
||||
defer cancel()
|
||||
m.logger.Info("Waiting for ClusterTrustBundle informer to sync")
|
||||
for _, ok := range kubeInformers.WaitForCacheSync(timeoutContext.Done()) {
|
||||
synced = synced && ok
|
||||
}
|
||||
if synced {
|
||||
m.logger.Info("ClusterTrustBundle informer synced")
|
||||
} else {
|
||||
m.logger.Info("ClusterTrustBundle informer not synced, continuing to attempt in background")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func clusterTrustBundlesAvailable(client clientset.Interface, gv schema.GroupVersion) (bool, error) {
|
||||
resList, err := client.Discovery().ServerResourcesForGroupVersion(gv.String())
|
||||
if k8serrors.IsNotFound(err) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if resList != nil {
|
||||
// even in case of an error above there might be a partial list for APIs that
|
||||
// were already successfully discovered
|
||||
for _, r := range resList.APIResources {
|
||||
if r.Name == "clustertrustbundles" {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
@@ -28,13 +28,23 @@ import (
|
||||
"math/big"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1"
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
"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/client-go/discovery"
|
||||
fakediscovery "k8s.io/client-go/discovery/fake"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/kubernetes/test/utils/ktesting"
|
||||
@@ -46,8 +56,7 @@ func TestBeforeSynced(t *testing.T) {
|
||||
|
||||
informerFactory := informers.NewSharedInformerFactoryWithOptions(kc, 0)
|
||||
|
||||
ctbInformer := informerFactory.Certificates().V1alpha1().ClusterTrustBundles()
|
||||
ctbManager, _ := NewInformerManager(tCtx, ctbInformer, 256, 5*time.Minute)
|
||||
ctbManager, _ := NewBetaInformerManager(tCtx, informerFactory, 256, 5*time.Minute)
|
||||
|
||||
_, err := ctbManager.GetTrustAnchorsByName("foo", false)
|
||||
if err == nil {
|
||||
@@ -55,38 +64,74 @@ func TestBeforeSynced(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
type testClient[T clusterTrustBundle] interface {
|
||||
Create(context.Context, *T, metav1.CreateOptions) (*T, error)
|
||||
Delete(context.Context, string, metav1.DeleteOptions) error
|
||||
}
|
||||
|
||||
// testingFunctionBundle is a API-version agnostic bundle of functions for handling CTBs in tests.
|
||||
type testingFunctionBundle[T clusterTrustBundle] struct {
|
||||
ctbConstructor func(name, signerName string, labels map[string]string, bundle string) *T
|
||||
ctbToObj func(*T) runtime.Object
|
||||
ctbTrustBundle func(*T) string
|
||||
|
||||
informerManagerConstructor func(ctx context.Context, informerFactory informers.SharedInformerFactory, cacheSize int, cacheTTL time.Duration) (Manager, error)
|
||||
informerGetter func(informers.SharedInformerFactory) cache.SharedIndexInformer
|
||||
clientGetter func(kubernetes.Interface) testClient[T]
|
||||
}
|
||||
|
||||
var alphaFunctionsBundle = testingFunctionBundle[certificatesv1alpha1.ClusterTrustBundle]{
|
||||
ctbConstructor: mustMakeAlphaCTB,
|
||||
ctbToObj: func(ctb *certificatesv1alpha1.ClusterTrustBundle) runtime.Object { return ctb },
|
||||
ctbTrustBundle: (&alphaClusterTrustBundleHandlers{}).GetTrustBundle,
|
||||
|
||||
informerManagerConstructor: NewAlphaInformerManager,
|
||||
informerGetter: func(informerFactory informers.SharedInformerFactory) cache.SharedIndexInformer {
|
||||
return informerFactory.Certificates().V1alpha1().ClusterTrustBundles().Informer()
|
||||
},
|
||||
clientGetter: func(c kubernetes.Interface) testClient[certificatesv1alpha1.ClusterTrustBundle] {
|
||||
return c.CertificatesV1alpha1().ClusterTrustBundles()
|
||||
},
|
||||
}
|
||||
|
||||
var betaFunctionsBundle = testingFunctionBundle[certificatesv1beta1.ClusterTrustBundle]{
|
||||
ctbConstructor: mustMakeBetaCTB,
|
||||
ctbToObj: func(ctb *certificatesv1beta1.ClusterTrustBundle) runtime.Object { return ctb },
|
||||
ctbTrustBundle: (&betaClusterTrustBundleHandlers{}).GetTrustBundle,
|
||||
|
||||
informerManagerConstructor: NewBetaInformerManager,
|
||||
informerGetter: func(informerFactory informers.SharedInformerFactory) cache.SharedIndexInformer {
|
||||
return informerFactory.Certificates().V1beta1().ClusterTrustBundles().Informer()
|
||||
},
|
||||
clientGetter: func(c kubernetes.Interface) testClient[certificatesv1beta1.ClusterTrustBundle] {
|
||||
return c.CertificatesV1beta1().ClusterTrustBundles()
|
||||
},
|
||||
}
|
||||
|
||||
func TestGetTrustAnchorsByName(t *testing.T) {
|
||||
t.Run("v1alpha1", func(t *testing.T) { testGetTrustAnchorsByName(t, alphaFunctionsBundle) })
|
||||
t.Run("v1beta1", func(t *testing.T) { testGetTrustAnchorsByName(t, betaFunctionsBundle) })
|
||||
}
|
||||
|
||||
func testGetTrustAnchorsByName[T clusterTrustBundle](t *testing.T, b testingFunctionBundle[T]) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
tCtx := ktesting.Init(t)
|
||||
defer cancel()
|
||||
|
||||
ctb1 := &certificatesv1alpha1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "ctb1",
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
TrustBundle: mustMakeRoot(t, "root1"),
|
||||
},
|
||||
}
|
||||
ctb1Bundle := mustMakeRoot(t, "root1")
|
||||
ctb1 := b.ctbConstructor("ctb1", "", nil, ctb1Bundle)
|
||||
ctb2Bundle := mustMakeRoot(t, "root2")
|
||||
ctb2 := b.ctbConstructor("ctb2", "", nil, ctb2Bundle)
|
||||
|
||||
ctb2 := &certificatesv1alpha1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "ctb2",
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
TrustBundle: mustMakeRoot(t, "root2"),
|
||||
},
|
||||
}
|
||||
|
||||
kc := fake.NewSimpleClientset(ctb1, ctb2)
|
||||
kc := fake.NewSimpleClientset(b.ctbToObj(ctb1), b.ctbToObj(ctb2))
|
||||
|
||||
informerFactory := informers.NewSharedInformerFactoryWithOptions(kc, 0)
|
||||
|
||||
ctbInformer := informerFactory.Certificates().V1alpha1().ClusterTrustBundles()
|
||||
ctbManager, _ := NewInformerManager(tCtx, ctbInformer, 256, 5*time.Minute)
|
||||
ctbManager, _ := b.informerManagerConstructor(tCtx, informerFactory, 256, 5*time.Minute)
|
||||
|
||||
informerFactory.Start(ctx.Done())
|
||||
if !cache.WaitForCacheSync(ctx.Done(), ctbInformer.Informer().HasSynced) {
|
||||
ctbInformer := b.informerGetter(informerFactory)
|
||||
if !cache.WaitForCacheSync(ctx.Done(), ctbInformer.HasSynced) {
|
||||
t.Fatalf("Timed out waiting for informer to sync")
|
||||
}
|
||||
|
||||
@@ -95,7 +140,7 @@ func TestGetTrustAnchorsByName(t *testing.T) {
|
||||
t.Fatalf("Error while calling GetTrustAnchorsByName: %v", err)
|
||||
}
|
||||
|
||||
if diff := diffBundles(gotBundle, []byte(ctb1.Spec.TrustBundle)); diff != "" {
|
||||
if diff := diffBundles(gotBundle, []byte(b.ctbTrustBundle(ctb1))); diff != "" {
|
||||
t.Fatalf("Got bad bundle; diff (-got +want)\n%s", diff)
|
||||
}
|
||||
|
||||
@@ -104,7 +149,7 @@ func TestGetTrustAnchorsByName(t *testing.T) {
|
||||
t.Fatalf("Error while calling GetTrustAnchorsByName: %v", err)
|
||||
}
|
||||
|
||||
if diff := diffBundles(gotBundle, []byte(ctb2.Spec.TrustBundle)); diff != "" {
|
||||
if diff := diffBundles(gotBundle, []byte(b.ctbTrustBundle(ctb2))); diff != "" {
|
||||
t.Fatalf("Got bad bundle; diff (-got +want)\n%s", diff)
|
||||
}
|
||||
|
||||
@@ -120,37 +165,30 @@ func TestGetTrustAnchorsByName(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetTrustAnchorsByNameCaching(t *testing.T) {
|
||||
t.Run("v1alpha1", func(t *testing.T) { testGetTrustAnchorsByNameCaching(t, alphaFunctionsBundle) })
|
||||
t.Run("v1beta1", func(t *testing.T) { testGetTrustAnchorsByNameCaching(t, betaFunctionsBundle) })
|
||||
}
|
||||
|
||||
func testGetTrustAnchorsByNameCaching[T clusterTrustBundle](t *testing.T, b testingFunctionBundle[T]) {
|
||||
tCtx := ktesting.Init(t)
|
||||
ctx, cancel := context.WithTimeout(tCtx, 20*time.Second)
|
||||
defer cancel()
|
||||
|
||||
ctb1 := &certificatesv1alpha1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
TrustBundle: mustMakeRoot(t, "root1"),
|
||||
},
|
||||
}
|
||||
ctb1Bundle := mustMakeRoot(t, "root1")
|
||||
ctb1 := b.ctbConstructor("foo", "", nil, ctb1Bundle)
|
||||
|
||||
ctb2 := &certificatesv1alpha1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
TrustBundle: mustMakeRoot(t, "root2"),
|
||||
},
|
||||
}
|
||||
ctb2Bundle := mustMakeRoot(t, "root2")
|
||||
ctb2 := b.ctbConstructor("foo", "", nil, ctb2Bundle)
|
||||
|
||||
kc := fake.NewSimpleClientset(ctb1)
|
||||
kc := fake.NewSimpleClientset(b.ctbToObj(ctb1))
|
||||
|
||||
informerFactory := informers.NewSharedInformerFactoryWithOptions(kc, 0)
|
||||
|
||||
ctbInformer := informerFactory.Certificates().V1alpha1().ClusterTrustBundles()
|
||||
ctbManager, _ := NewInformerManager(tCtx, ctbInformer, 256, 5*time.Minute)
|
||||
ctbManager, _ := b.informerManagerConstructor(tCtx, informerFactory, 256, 5*time.Minute)
|
||||
|
||||
informerFactory.Start(ctx.Done())
|
||||
if !cache.WaitForCacheSync(ctx.Done(), ctbInformer.Informer().HasSynced) {
|
||||
ctbInformer := b.informerGetter(informerFactory)
|
||||
if !cache.WaitForCacheSync(ctx.Done(), ctbInformer.HasSynced) {
|
||||
t.Fatalf("Timed out waiting for informer to sync")
|
||||
}
|
||||
|
||||
@@ -160,7 +198,7 @@ func TestGetTrustAnchorsByNameCaching(t *testing.T) {
|
||||
t.Fatalf("Got error while calling GetTrustAnchorsBySigner: %v", err)
|
||||
}
|
||||
|
||||
wantBundle := ctb1.Spec.TrustBundle
|
||||
wantBundle := b.ctbTrustBundle(ctb1)
|
||||
|
||||
if diff := diffBundles(gotBundle, []byte(wantBundle)); diff != "" {
|
||||
t.Fatalf("Bad bundle; diff (-got +want)\n%s", diff)
|
||||
@@ -173,17 +211,19 @@ func TestGetTrustAnchorsByNameCaching(t *testing.T) {
|
||||
t.Fatalf("Got error while calling GetTrustAnchorsBySigner: %v", err)
|
||||
}
|
||||
|
||||
wantBundle := ctb1.Spec.TrustBundle
|
||||
wantBundle := b.ctbTrustBundle(ctb1)
|
||||
|
||||
if diff := diffBundles(gotBundle, []byte(wantBundle)); diff != "" {
|
||||
t.Fatalf("Bad bundle; diff (-got +want)\n%s", diff)
|
||||
}
|
||||
})
|
||||
|
||||
if err := kc.CertificatesV1alpha1().ClusterTrustBundles().Delete(ctx, ctb1.ObjectMeta.Name, metav1.DeleteOptions{}); err != nil {
|
||||
client := b.clientGetter(kc)
|
||||
|
||||
if err := client.Delete(ctx, "foo", metav1.DeleteOptions{}); err != nil {
|
||||
t.Fatalf("Error while deleting the old CTB: %v", err)
|
||||
}
|
||||
if _, err := kc.CertificatesV1alpha1().ClusterTrustBundles().Create(ctx, ctb2, metav1.CreateOptions{}); err != nil {
|
||||
if _, err := client.Create(ctx, ctb2, metav1.CreateOptions{}); err != nil {
|
||||
t.Fatalf("Error while adding new CTB: %v", err)
|
||||
}
|
||||
|
||||
@@ -198,8 +238,7 @@ func TestGetTrustAnchorsByNameCaching(t *testing.T) {
|
||||
t.Fatalf("Got error while calling GetTrustAnchorsBySigner: %v", err)
|
||||
}
|
||||
|
||||
wantBundle := ctb2.Spec.TrustBundle
|
||||
|
||||
wantBundle := b.ctbTrustBundle(ctb2)
|
||||
if diff := diffBundles(gotBundle, []byte(wantBundle)); diff != "" {
|
||||
t.Fatalf("Bad bundle; diff (-got +want)\n%s", diff)
|
||||
}
|
||||
@@ -207,25 +246,30 @@ func TestGetTrustAnchorsByNameCaching(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetTrustAnchorsBySignerName(t *testing.T) {
|
||||
t.Run("v1alpha1", func(t *testing.T) { testGetTrustAnchorsBySignerName(t, alphaFunctionsBundle) })
|
||||
t.Run("v1beta1", func(t *testing.T) { testGetTrustAnchorsBySignerName(t, betaFunctionsBundle) })
|
||||
}
|
||||
|
||||
func testGetTrustAnchorsBySignerName[T clusterTrustBundle](t *testing.T, b testingFunctionBundle[T]) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
tCtx := ktesting.Init(t)
|
||||
defer cancel()
|
||||
|
||||
ctb1 := mustMakeCTB("signer-a-label-a-1", "foo.bar/a", map[string]string{"label": "a"}, mustMakeRoot(t, "0"))
|
||||
ctb2 := mustMakeCTB("signer-a-label-a-2", "foo.bar/a", map[string]string{"label": "a"}, mustMakeRoot(t, "1"))
|
||||
ctb2dup := mustMakeCTB("signer-a-label-2-dup", "foo.bar/a", map[string]string{"label": "a"}, ctb2.Spec.TrustBundle)
|
||||
ctb3 := mustMakeCTB("signer-a-label-b-1", "foo.bar/a", map[string]string{"label": "b"}, mustMakeRoot(t, "2"))
|
||||
ctb4 := mustMakeCTB("signer-b-label-a-1", "foo.bar/b", map[string]string{"label": "a"}, mustMakeRoot(t, "3"))
|
||||
ctb1 := b.ctbConstructor("signer-a-label-a-1", "foo.bar/a", map[string]string{"label": "a"}, mustMakeRoot(t, "0"))
|
||||
ctb2 := b.ctbConstructor("signer-a-label-a-2", "foo.bar/a", map[string]string{"label": "a"}, mustMakeRoot(t, "1"))
|
||||
ctb2dup := b.ctbConstructor("signer-a-label-2-dup", "foo.bar/a", map[string]string{"label": "a"}, b.ctbTrustBundle(ctb2))
|
||||
ctb3 := b.ctbConstructor("signer-a-label-b-1", "foo.bar/a", map[string]string{"label": "b"}, mustMakeRoot(t, "2"))
|
||||
ctb4 := b.ctbConstructor("signer-b-label-a-1", "foo.bar/b", map[string]string{"label": "a"}, mustMakeRoot(t, "3"))
|
||||
|
||||
kc := fake.NewSimpleClientset(ctb1, ctb2, ctb2dup, ctb3, ctb4)
|
||||
kc := fake.NewSimpleClientset(b.ctbToObj(ctb1), b.ctbToObj(ctb2), b.ctbToObj(ctb2dup), b.ctbToObj(ctb3), b.ctbToObj(ctb4))
|
||||
|
||||
informerFactory := informers.NewSharedInformerFactoryWithOptions(kc, 0)
|
||||
|
||||
ctbInformer := informerFactory.Certificates().V1alpha1().ClusterTrustBundles()
|
||||
ctbManager, _ := NewInformerManager(tCtx, ctbInformer, 256, 5*time.Minute)
|
||||
ctbManager, _ := b.informerManagerConstructor(tCtx, informerFactory, 256, 5*time.Minute)
|
||||
|
||||
informerFactory.Start(ctx.Done())
|
||||
if !cache.WaitForCacheSync(ctx.Done(), ctbInformer.Informer().HasSynced) {
|
||||
ctbInformer := b.informerGetter(informerFactory)
|
||||
if !cache.WaitForCacheSync(ctx.Done(), ctbInformer.HasSynced) {
|
||||
t.Fatalf("Timed out waiting for informer to sync")
|
||||
}
|
||||
|
||||
@@ -251,7 +295,7 @@ func TestGetTrustAnchorsBySignerName(t *testing.T) {
|
||||
t.Fatalf("Got error while calling GetTrustAnchorsBySigner: %v", err)
|
||||
}
|
||||
|
||||
wantBundle := ctb1.Spec.TrustBundle + ctb2.Spec.TrustBundle
|
||||
wantBundle := b.ctbTrustBundle(ctb1) + b.ctbTrustBundle(ctb2)
|
||||
|
||||
if diff := diffBundles(gotBundle, []byte(wantBundle)); diff != "" {
|
||||
t.Fatalf("Bad bundle; diff (-got +want)\n%s", diff)
|
||||
@@ -277,7 +321,7 @@ func TestGetTrustAnchorsBySignerName(t *testing.T) {
|
||||
t.Fatalf("Got error while calling GetTrustAnchorsBySigner: %v", err)
|
||||
}
|
||||
|
||||
if diff := diffBundles(gotBundle, []byte(ctb4.Spec.TrustBundle)); diff != "" {
|
||||
if diff := diffBundles(gotBundle, []byte(b.ctbTrustBundle(ctb4))); diff != "" {
|
||||
t.Fatalf("Bad bundle; diff (-got +want)\n%s", diff)
|
||||
}
|
||||
})
|
||||
@@ -288,7 +332,7 @@ func TestGetTrustAnchorsBySignerName(t *testing.T) {
|
||||
t.Fatalf("Got error while calling GetTrustAnchorsBySigner: %v", err)
|
||||
}
|
||||
|
||||
if diff := diffBundles(gotBundle, []byte(ctb3.Spec.TrustBundle)); diff != "" {
|
||||
if diff := diffBundles(gotBundle, []byte(b.ctbTrustBundle(ctb3))); diff != "" {
|
||||
t.Fatalf("Bad bundle; diff (-got +want)\n%s", diff)
|
||||
}
|
||||
})
|
||||
@@ -299,7 +343,7 @@ func TestGetTrustAnchorsBySignerName(t *testing.T) {
|
||||
t.Fatalf("Got error while calling GetTrustAnchorsBySigner: %v", err)
|
||||
}
|
||||
|
||||
if diff := diffBundles(gotBundle, []byte(ctb4.Spec.TrustBundle)); diff != "" {
|
||||
if diff := diffBundles(gotBundle, []byte(b.ctbTrustBundle(ctb4))); diff != "" {
|
||||
t.Fatalf("Bad bundle; diff (-got +want)\n%s", diff)
|
||||
}
|
||||
})
|
||||
@@ -324,22 +368,27 @@ func TestGetTrustAnchorsBySignerName(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetTrustAnchorsBySignerNameCaching(t *testing.T) {
|
||||
t.Run("v1alpha1", func(t *testing.T) { testGetTrustAnchorsBySignerNameCaching(t, alphaFunctionsBundle) })
|
||||
t.Run("v1beta1", func(t *testing.T) { testGetTrustAnchorsBySignerNameCaching(t, betaFunctionsBundle) })
|
||||
}
|
||||
|
||||
func testGetTrustAnchorsBySignerNameCaching[T clusterTrustBundle](t *testing.T, b testingFunctionBundle[T]) {
|
||||
tCtx := ktesting.Init(t)
|
||||
ctx, cancel := context.WithTimeout(tCtx, 20*time.Second)
|
||||
defer cancel()
|
||||
|
||||
ctb1 := mustMakeCTB("signer-a-label-a-1", "foo.bar/a", map[string]string{"label": "a"}, mustMakeRoot(t, "0"))
|
||||
ctb2 := mustMakeCTB("signer-a-label-a-2", "foo.bar/a", map[string]string{"label": "a"}, mustMakeRoot(t, "1"))
|
||||
ctb1 := b.ctbConstructor("signer-a-label-a-1", "foo.bar/a", map[string]string{"label": "a"}, mustMakeRoot(t, "0"))
|
||||
ctb2 := b.ctbConstructor("signer-a-label-a-2", "foo.bar/a", map[string]string{"label": "a"}, mustMakeRoot(t, "1"))
|
||||
|
||||
kc := fake.NewSimpleClientset(ctb1)
|
||||
kc := fake.NewSimpleClientset(b.ctbToObj(ctb1))
|
||||
|
||||
informerFactory := informers.NewSharedInformerFactoryWithOptions(kc, 0)
|
||||
|
||||
ctbInformer := informerFactory.Certificates().V1alpha1().ClusterTrustBundles()
|
||||
ctbManager, _ := NewInformerManager(tCtx, ctbInformer, 256, 5*time.Minute)
|
||||
ctbManager, _ := b.informerManagerConstructor(tCtx, informerFactory, 256, 5*time.Minute)
|
||||
|
||||
informerFactory.Start(ctx.Done())
|
||||
if !cache.WaitForCacheSync(ctx.Done(), ctbInformer.Informer().HasSynced) {
|
||||
ctbInformer := b.informerGetter(informerFactory)
|
||||
if !cache.WaitForCacheSync(ctx.Done(), ctbInformer.HasSynced) {
|
||||
t.Fatalf("Timed out waiting for informer to sync")
|
||||
}
|
||||
|
||||
@@ -349,7 +398,7 @@ func TestGetTrustAnchorsBySignerNameCaching(t *testing.T) {
|
||||
t.Fatalf("Got error while calling GetTrustAnchorsBySigner: %v", err)
|
||||
}
|
||||
|
||||
wantBundle := ctb1.Spec.TrustBundle
|
||||
wantBundle := b.ctbTrustBundle(ctb1)
|
||||
|
||||
if diff := diffBundles(gotBundle, []byte(wantBundle)); diff != "" {
|
||||
t.Fatalf("Bad bundle; diff (-got +want)\n%s", diff)
|
||||
@@ -362,17 +411,18 @@ func TestGetTrustAnchorsBySignerNameCaching(t *testing.T) {
|
||||
t.Fatalf("Got error while calling GetTrustAnchorsBySigner: %v", err)
|
||||
}
|
||||
|
||||
wantBundle := ctb1.Spec.TrustBundle
|
||||
wantBundle := b.ctbTrustBundle(ctb1)
|
||||
|
||||
if diff := diffBundles(gotBundle, []byte(wantBundle)); diff != "" {
|
||||
t.Fatalf("Bad bundle; diff (-got +want)\n%s", diff)
|
||||
}
|
||||
})
|
||||
|
||||
if err := kc.CertificatesV1alpha1().ClusterTrustBundles().Delete(ctx, ctb1.ObjectMeta.Name, metav1.DeleteOptions{}); err != nil {
|
||||
client := b.clientGetter(kc)
|
||||
if err := client.Delete(ctx, "signer-a-label-a-1", metav1.DeleteOptions{}); err != nil {
|
||||
t.Fatalf("Error while deleting the old CTB: %v", err)
|
||||
}
|
||||
if _, err := kc.CertificatesV1alpha1().ClusterTrustBundles().Create(ctx, ctb2, metav1.CreateOptions{}); err != nil {
|
||||
if _, err := client.Create(ctx, ctb2, metav1.CreateOptions{}); err != nil {
|
||||
t.Fatalf("Error while adding new CTB: %v", err)
|
||||
}
|
||||
|
||||
@@ -387,7 +437,7 @@ func TestGetTrustAnchorsBySignerNameCaching(t *testing.T) {
|
||||
t.Fatalf("Got error while calling GetTrustAnchorsBySigner: %v", err)
|
||||
}
|
||||
|
||||
wantBundle := ctb2.Spec.TrustBundle
|
||||
wantBundle := b.ctbTrustBundle(ctb2)
|
||||
|
||||
if diff := diffBundles(gotBundle, []byte(wantBundle)); diff != "" {
|
||||
t.Fatalf("Bad bundle; diff (-got +want)\n%s", diff)
|
||||
@@ -422,7 +472,20 @@ func mustMakeRoot(t *testing.T, cn string) string {
|
||||
}))
|
||||
}
|
||||
|
||||
func mustMakeCTB(name, signerName string, labels map[string]string, bundle string) *certificatesv1alpha1.ClusterTrustBundle {
|
||||
func mustMakeBetaCTB(name, signerName string, labels map[string]string, bundle string) *certificatesv1beta1.ClusterTrustBundle {
|
||||
return &certificatesv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Labels: labels,
|
||||
},
|
||||
Spec: certificatesv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: signerName,
|
||||
TrustBundle: bundle,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func mustMakeAlphaCTB(name, signerName string, labels map[string]string, bundle string) *certificatesv1alpha1.ClusterTrustBundle {
|
||||
return &certificatesv1alpha1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
@@ -478,3 +541,133 @@ func diffBundles(a, b []byte) string {
|
||||
|
||||
return cmp.Diff(aBlocks, bBlocks)
|
||||
}
|
||||
|
||||
func TestLazyInformerManager_ensureManagerSet(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
injectError error
|
||||
ctbsAvailableGVs []string
|
||||
wantManager string
|
||||
wantError bool
|
||||
}{
|
||||
{
|
||||
name: "API unavailable",
|
||||
injectError: errors.NewNotFound(schema.GroupResource{Group: "certificates.k8s.io/v1beta1"}, ""),
|
||||
wantManager: "noop",
|
||||
},
|
||||
{
|
||||
name: "err in discovery",
|
||||
injectError: fmt.Errorf("unexpected discovery error"),
|
||||
wantError: true,
|
||||
wantManager: "nil",
|
||||
},
|
||||
{
|
||||
name: "API available in v1alpha1",
|
||||
ctbsAvailableGVs: []string{"v1alpha1"},
|
||||
wantManager: "v1alpha1",
|
||||
},
|
||||
{
|
||||
name: "API available in an unhandled version",
|
||||
ctbsAvailableGVs: []string{"v1beta2"},
|
||||
wantManager: "noop",
|
||||
},
|
||||
{
|
||||
name: "API available in v1beta1",
|
||||
ctbsAvailableGVs: []string{"v1beta1"},
|
||||
wantManager: "v1beta1",
|
||||
},
|
||||
{
|
||||
name: "API available in v1 - currently unhandled",
|
||||
ctbsAvailableGVs: []string{"v1"},
|
||||
wantManager: "noop",
|
||||
},
|
||||
{
|
||||
name: "err in discovery but beta API shard discovered",
|
||||
injectError: fmt.Errorf("unexpected discovery error"),
|
||||
ctbsAvailableGVs: []string{"v1beta1"},
|
||||
wantManager: "v1beta1",
|
||||
},
|
||||
{
|
||||
name: "API available in alpha and beta - prefer beta",
|
||||
ctbsAvailableGVs: []string{"v1alpha1", "v1beta1"},
|
||||
wantManager: "v1beta1",
|
||||
},
|
||||
{
|
||||
name: "API available in multiple handled and unhandled versions - prefer the most-GA handled version",
|
||||
ctbsAvailableGVs: []string{"v1alpha1", "v1", "v2", "v1beta1", "v1alpha2"},
|
||||
wantManager: "v1beta1",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
logger, loggerCtx := ktesting.NewTestContext(t)
|
||||
|
||||
fakeDisc := fakeDiscovery{
|
||||
err: tt.injectError,
|
||||
gvResources: make(map[string]*metav1.APIResourceList),
|
||||
}
|
||||
|
||||
for _, gv := range tt.ctbsAvailableGVs {
|
||||
fakeDisc.gvResources["certificates.k8s.io/"+gv] = &metav1.APIResourceList{
|
||||
APIResources: []metav1.APIResource{
|
||||
{Name: "certificatesigningrequests"},
|
||||
{Name: "clustertrustbundles"},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
m := &LazyInformerManager{
|
||||
managerLock: sync.RWMutex{},
|
||||
client: NewFakeClientset(fakeDisc),
|
||||
cacheSize: 128,
|
||||
contextWithLogger: loggerCtx,
|
||||
logger: logger,
|
||||
}
|
||||
if err := m.ensureManagerSet(); tt.wantError != (err != nil) {
|
||||
t.Errorf("expected error: %t, got %v", tt.wantError, err)
|
||||
}
|
||||
|
||||
switch manager := m.manager.(type) {
|
||||
case *InformerManager[certificatesv1alpha1.ClusterTrustBundle]:
|
||||
require.Equal(t, tt.wantManager, "v1alpha1")
|
||||
case *InformerManager[certificatesv1beta1.ClusterTrustBundle]:
|
||||
require.Equal(t, tt.wantManager, "v1beta1")
|
||||
case *NoopManager:
|
||||
require.Equal(t, tt.wantManager, "noop")
|
||||
case nil:
|
||||
require.Equal(t, tt.wantManager, "nil")
|
||||
default:
|
||||
t.Fatalf("unknown manager type: %T", manager)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// fakeDiscovery inherits DiscoveryInterface(via FakeDiscovery) with some methods serving testing data.
|
||||
type fakeDiscovery struct {
|
||||
fakediscovery.FakeDiscovery
|
||||
gvResources map[string]*metav1.APIResourceList
|
||||
err error
|
||||
}
|
||||
|
||||
func (d fakeDiscovery) ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error) {
|
||||
return d.gvResources[groupVersion], d.err
|
||||
}
|
||||
|
||||
type fakeDiscoveryClientSet struct {
|
||||
*fake.Clientset
|
||||
DiscoveryObj *fakeDiscovery
|
||||
}
|
||||
|
||||
func (c *fakeDiscoveryClientSet) Discovery() discovery.DiscoveryInterface {
|
||||
return c.DiscoveryObj
|
||||
}
|
||||
|
||||
// Create a fake Clientset with its Discovery method overridden.
|
||||
func NewFakeClientset(fakeDiscovery fakeDiscovery) *fakeDiscoveryClientSet {
|
||||
cs := &fakeDiscoveryClientSet{
|
||||
Clientset: fake.NewClientset(),
|
||||
DiscoveryObj: &fakeDiscovery,
|
||||
}
|
||||
return cs
|
||||
}
|
||||
|
||||
@@ -878,19 +878,12 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
||||
|
||||
tokenManager := token.NewManager(kubeDeps.KubeClient)
|
||||
|
||||
var clusterTrustBundleManager clustertrustbundle.Manager
|
||||
var clusterTrustBundleManager clustertrustbundle.Manager = &clustertrustbundle.NoopManager{}
|
||||
if kubeDeps.KubeClient != nil && utilfeature.DefaultFeatureGate.Enabled(features.ClusterTrustBundleProjection) {
|
||||
kubeInformers := informers.NewSharedInformerFactoryWithOptions(kubeDeps.KubeClient, 0)
|
||||
clusterTrustBundleManager, err = clustertrustbundle.NewInformerManager(ctx, kubeInformers.Certificates().V1alpha1().ClusterTrustBundles(), 2*int(kubeCfg.MaxPods), 5*time.Minute)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("while starting informer-based ClusterTrustBundle manager: %w", err)
|
||||
}
|
||||
kubeInformers.Start(wait.NeverStop)
|
||||
klog.InfoS("Started ClusterTrustBundle informer")
|
||||
clusterTrustBundleManager = clustertrustbundle.NewLazyInformerManager(ctx, kubeDeps.KubeClient, 2*int(kubeCfg.MaxPods))
|
||||
klog.InfoS("ClusterTrustBundle informer will be started eventually once a trust bundle is requested")
|
||||
} else {
|
||||
// In static kubelet mode, use a no-op manager.
|
||||
clusterTrustBundleManager = &clustertrustbundle.NoopManager{}
|
||||
klog.InfoS("Not starting ClusterTrustBundle informer because we are in static kubelet mode")
|
||||
klog.InfoS("Not starting ClusterTrustBundle informer because we are in static kubelet mode or the ClusterTrustBundleProjection featuregate is disabled")
|
||||
}
|
||||
|
||||
// NewInitializedVolumePluginMgr initializes some storageErrors on the Kubelet runtimeState (in csi_plugin.go init)
|
||||
|
||||
@@ -30,8 +30,7 @@ import (
|
||||
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
||||
autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1"
|
||||
batchv1beta1 "k8s.io/api/batch/v1beta1" // should this change, too? there are still certv1beta1.CSR printers, but not their v1 versions
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
coordinationv1 "k8s.io/api/coordination/v1"
|
||||
coordinationv1alpha2 "k8s.io/api/coordination/v1alpha2"
|
||||
@@ -420,7 +419,7 @@ func AddHandlers(h printers.PrintHandler) {
|
||||
|
||||
clusterTrustBundleColumnDefinitions := []metav1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
||||
{Name: "SignerName", Type: "string", Description: certificatesv1alpha1.ClusterTrustBundleSpec{}.SwaggerDoc()["signerName"]},
|
||||
{Name: "SignerName", Type: "string", Description: certificatesv1beta1.ClusterTrustBundleSpec{}.SwaggerDoc()["signerName"]},
|
||||
}
|
||||
h.TableHandler(clusterTrustBundleColumnDefinitions, printClusterTrustBundle)
|
||||
h.TableHandler(clusterTrustBundleColumnDefinitions, printClusterTrustBundleList)
|
||||
|
||||
@@ -19,6 +19,7 @@ package rest
|
||||
import (
|
||||
certificatesapiv1 "k8s.io/api/certificates/v1"
|
||||
certificatesapiv1alpha1 "k8s.io/api/certificates/v1alpha1"
|
||||
certificatesapiv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
"k8s.io/apiserver/pkg/registry/generic"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
@@ -45,6 +46,12 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag
|
||||
apiGroupInfo.VersionedResourcesStorageMap[certificatesapiv1.SchemeGroupVersion.Version] = storageMap
|
||||
}
|
||||
|
||||
if storageMap, err := p.v1beta1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
|
||||
return genericapiserver.APIGroupInfo{}, err
|
||||
} else if len(storageMap) > 0 {
|
||||
apiGroupInfo.VersionedResourcesStorageMap[certificatesapiv1beta1.SchemeGroupVersion.Version] = storageMap
|
||||
}
|
||||
|
||||
if storageMap, err := p.v1alpha1Storage(apiResourceConfigSource, restOptionsGetter); err != nil {
|
||||
return genericapiserver.APIGroupInfo{}, err
|
||||
} else if len(storageMap) > 0 {
|
||||
@@ -70,6 +77,24 @@ func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.API
|
||||
return storage, nil
|
||||
}
|
||||
|
||||
func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) {
|
||||
storage := map[string]rest.Storage{}
|
||||
|
||||
if resource := "clustertrustbundles"; apiResourceConfigSource.ResourceEnabled(certificatesapiv1beta1.SchemeGroupVersion.WithResource(resource)) {
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.ClusterTrustBundle) {
|
||||
bundleStorage, err := clustertrustbundlestore.NewREST(restOptionsGetter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
storage[resource] = bundleStorage
|
||||
} else {
|
||||
klog.Warning("ClusterTrustBundle storage is disabled because the ClusterTrustBundle feature gate is disabled")
|
||||
}
|
||||
}
|
||||
|
||||
return storage, nil
|
||||
}
|
||||
|
||||
func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (map[string]rest.Storage, error) {
|
||||
storage := map[string]rest.Storage{}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import (
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
authenticationv1 "k8s.io/api/authentication/v1"
|
||||
certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1"
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -912,11 +912,11 @@ func TestCollectDataWithClusterTrustBundle(t *testing.T) {
|
||||
DefaultMode: utilptr.Int32(0644),
|
||||
},
|
||||
bundles: []runtime.Object{
|
||||
&certificatesv1alpha1.ClusterTrustBundle{
|
||||
&certificatesv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certificatesv1beta1.ClusterTrustBundleSpec{
|
||||
TrustBundle: string(goodCert1),
|
||||
},
|
||||
},
|
||||
@@ -947,14 +947,14 @@ func TestCollectDataWithClusterTrustBundle(t *testing.T) {
|
||||
DefaultMode: utilptr.Int32(0644),
|
||||
},
|
||||
bundles: []runtime.Object{
|
||||
&certificatesv1alpha1.ClusterTrustBundle{
|
||||
&certificatesv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo:example:bar",
|
||||
Labels: map[string]string{
|
||||
"key": "value",
|
||||
},
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certificatesv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: "foo.example/bar",
|
||||
TrustBundle: string(goodCert1),
|
||||
},
|
||||
@@ -981,11 +981,11 @@ func TestCollectDataWithClusterTrustBundle(t *testing.T) {
|
||||
DefaultMode: utilptr.Int32(0600),
|
||||
},
|
||||
bundles: []runtime.Object{
|
||||
&certificatesv1alpha1.ClusterTrustBundle{
|
||||
&certificatesv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certificatesv1beta1.ClusterTrustBundleSpec{
|
||||
TrustBundle: string(goodCert1),
|
||||
},
|
||||
},
|
||||
|
||||
@@ -427,7 +427,7 @@ func (f *fakeKubeletVolumeHost) GetHostUtil() hostutil.HostUtils {
|
||||
}
|
||||
|
||||
func (f *fakeKubeletVolumeHost) GetTrustAnchorsByName(name string, allowMissing bool) ([]byte, error) {
|
||||
ctb, err := f.kubeClient.CertificatesV1alpha1().ClusterTrustBundles().Get(context.Background(), name, metav1.GetOptions{})
|
||||
ctb, err := f.kubeClient.CertificatesV1beta1().ClusterTrustBundles().Get(context.Background(), name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("while getting ClusterTrustBundle %s: %w", name, err)
|
||||
}
|
||||
@@ -437,7 +437,7 @@ func (f *fakeKubeletVolumeHost) GetTrustAnchorsByName(name string, allowMissing
|
||||
|
||||
// Note: we do none of the deduplication and sorting that the real deal should do.
|
||||
func (f *fakeKubeletVolumeHost) GetTrustAnchorsBySigner(signerName string, labelSelector *metav1.LabelSelector, allowMissing bool) ([]byte, error) {
|
||||
ctbList, err := f.kubeClient.CertificatesV1alpha1().ClusterTrustBundles().List(context.Background(), metav1.ListOptions{})
|
||||
ctbList, err := f.kubeClient.CertificatesV1beta1().ClusterTrustBundles().List(context.Background(), metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("while listing all ClusterTrustBundles: %w", err)
|
||||
}
|
||||
|
||||
@@ -186,10 +186,94 @@ func (m *CertificateSigningRequestStatus) XXX_DiscardUnknown() {
|
||||
|
||||
var xxx_messageInfo_CertificateSigningRequestStatus proto.InternalMessageInfo
|
||||
|
||||
func (m *ClusterTrustBundle) Reset() { *m = ClusterTrustBundle{} }
|
||||
func (*ClusterTrustBundle) ProtoMessage() {}
|
||||
func (*ClusterTrustBundle) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6529c11a462c48a5, []int{5}
|
||||
}
|
||||
func (m *ClusterTrustBundle) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *ClusterTrustBundle) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
func (m *ClusterTrustBundle) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ClusterTrustBundle.Merge(m, src)
|
||||
}
|
||||
func (m *ClusterTrustBundle) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *ClusterTrustBundle) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ClusterTrustBundle.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ClusterTrustBundle proto.InternalMessageInfo
|
||||
|
||||
func (m *ClusterTrustBundleList) Reset() { *m = ClusterTrustBundleList{} }
|
||||
func (*ClusterTrustBundleList) ProtoMessage() {}
|
||||
func (*ClusterTrustBundleList) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6529c11a462c48a5, []int{6}
|
||||
}
|
||||
func (m *ClusterTrustBundleList) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *ClusterTrustBundleList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
func (m *ClusterTrustBundleList) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ClusterTrustBundleList.Merge(m, src)
|
||||
}
|
||||
func (m *ClusterTrustBundleList) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *ClusterTrustBundleList) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ClusterTrustBundleList.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ClusterTrustBundleList proto.InternalMessageInfo
|
||||
|
||||
func (m *ClusterTrustBundleSpec) Reset() { *m = ClusterTrustBundleSpec{} }
|
||||
func (*ClusterTrustBundleSpec) ProtoMessage() {}
|
||||
func (*ClusterTrustBundleSpec) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6529c11a462c48a5, []int{7}
|
||||
}
|
||||
func (m *ClusterTrustBundleSpec) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *ClusterTrustBundleSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
func (m *ClusterTrustBundleSpec) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ClusterTrustBundleSpec.Merge(m, src)
|
||||
}
|
||||
func (m *ClusterTrustBundleSpec) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *ClusterTrustBundleSpec) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ClusterTrustBundleSpec.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ClusterTrustBundleSpec proto.InternalMessageInfo
|
||||
|
||||
func (m *ExtraValue) Reset() { *m = ExtraValue{} }
|
||||
func (*ExtraValue) ProtoMessage() {}
|
||||
func (*ExtraValue) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6529c11a462c48a5, []int{5}
|
||||
return fileDescriptor_6529c11a462c48a5, []int{8}
|
||||
}
|
||||
func (m *ExtraValue) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
@@ -221,6 +305,9 @@ func init() {
|
||||
proto.RegisterType((*CertificateSigningRequestSpec)(nil), "k8s.io.api.certificates.v1beta1.CertificateSigningRequestSpec")
|
||||
proto.RegisterMapType((map[string]ExtraValue)(nil), "k8s.io.api.certificates.v1beta1.CertificateSigningRequestSpec.ExtraEntry")
|
||||
proto.RegisterType((*CertificateSigningRequestStatus)(nil), "k8s.io.api.certificates.v1beta1.CertificateSigningRequestStatus")
|
||||
proto.RegisterType((*ClusterTrustBundle)(nil), "k8s.io.api.certificates.v1beta1.ClusterTrustBundle")
|
||||
proto.RegisterType((*ClusterTrustBundleList)(nil), "k8s.io.api.certificates.v1beta1.ClusterTrustBundleList")
|
||||
proto.RegisterType((*ClusterTrustBundleSpec)(nil), "k8s.io.api.certificates.v1beta1.ClusterTrustBundleSpec")
|
||||
proto.RegisterType((*ExtraValue)(nil), "k8s.io.api.certificates.v1beta1.ExtraValue")
|
||||
}
|
||||
|
||||
@@ -229,64 +316,69 @@ func init() {
|
||||
}
|
||||
|
||||
var fileDescriptor_6529c11a462c48a5 = []byte{
|
||||
// 901 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x4d, 0x6f, 0x1b, 0x45,
|
||||
0x18, 0xf6, 0xc6, 0x1f, 0xb1, 0xc7, 0x21, 0x6d, 0x47, 0x50, 0x2d, 0x96, 0xea, 0xb5, 0x56, 0x80,
|
||||
0xc2, 0xd7, 0x2c, 0xa9, 0x2a, 0x88, 0x72, 0x40, 0xb0, 0x21, 0x42, 0x11, 0x29, 0x48, 0x93, 0x84,
|
||||
0x03, 0x42, 0xa2, 0x93, 0xf5, 0xdb, 0xcd, 0x34, 0xdd, 0x0f, 0x76, 0x66, 0x4d, 0x7d, 0xeb, 0x4f,
|
||||
0xe0, 0xc8, 0x91, 0xff, 0xc0, 0x9f, 0x08, 0x07, 0xa4, 0x1e, 0x7b, 0x40, 0x16, 0x71, 0xff, 0x45,
|
||||
0x4e, 0x68, 0x66, 0xc7, 0x6b, 0xc7, 0x4e, 0x70, 0x69, 0x6f, 0x3b, 0xcf, 0xbc, 0xcf, 0xf3, 0xbc,
|
||||
0xf3, 0xce, 0xfb, 0x8e, 0x8d, 0xbc, 0xd3, 0x2d, 0x41, 0x78, 0xe2, 0xb1, 0x94, 0x7b, 0x01, 0x64,
|
||||
0x92, 0x3f, 0xe4, 0x01, 0x93, 0x20, 0xbc, 0xc1, 0xe6, 0x31, 0x48, 0xb6, 0xe9, 0x85, 0x10, 0x43,
|
||||
0xc6, 0x24, 0xf4, 0x49, 0x9a, 0x25, 0x32, 0xc1, 0x4e, 0x41, 0x20, 0x2c, 0xe5, 0x64, 0x96, 0x40,
|
||||
0x0c, 0xa1, 0xf3, 0x71, 0xc8, 0xe5, 0x49, 0x7e, 0x4c, 0x82, 0x24, 0xf2, 0xc2, 0x24, 0x4c, 0x3c,
|
||||
0xcd, 0x3b, 0xce, 0x1f, 0xea, 0x95, 0x5e, 0xe8, 0xaf, 0x42, 0xaf, 0xe3, 0xce, 0x26, 0x90, 0x64,
|
||||
0xe0, 0x0d, 0x16, 0x3c, 0x3b, 0xf7, 0xa6, 0x31, 0x11, 0x0b, 0x4e, 0x78, 0x0c, 0xd9, 0xd0, 0x4b,
|
||||
0x4f, 0x43, 0x05, 0x08, 0x2f, 0x02, 0xc9, 0xae, 0x62, 0x79, 0xd7, 0xb1, 0xb2, 0x3c, 0x96, 0x3c,
|
||||
0x82, 0x05, 0xc2, 0xa7, 0xcb, 0x08, 0x22, 0x38, 0x81, 0x88, 0xcd, 0xf3, 0xdc, 0x3f, 0x57, 0xd0,
|
||||
0xdb, 0x3b, 0xd3, 0x52, 0x1c, 0xf0, 0x30, 0xe6, 0x71, 0x48, 0xe1, 0xe7, 0x1c, 0x84, 0xc4, 0x0f,
|
||||
0x50, 0x53, 0x65, 0xd8, 0x67, 0x92, 0xd9, 0x56, 0xcf, 0xda, 0x68, 0xdf, 0xfd, 0x84, 0x4c, 0x6b,
|
||||
0x58, 0x1a, 0x91, 0xf4, 0x34, 0x54, 0x80, 0x20, 0x2a, 0x9a, 0x0c, 0x36, 0xc9, 0x77, 0xc7, 0x8f,
|
||||
0x20, 0x90, 0xf7, 0x41, 0x32, 0x1f, 0x9f, 0x8d, 0x9c, 0xca, 0x78, 0xe4, 0xa0, 0x29, 0x46, 0x4b,
|
||||
0x55, 0xfc, 0x00, 0xd5, 0x44, 0x0a, 0x81, 0xbd, 0xa2, 0xd5, 0x3f, 0x27, 0x4b, 0x6e, 0x88, 0x5c,
|
||||
0x9b, 0xeb, 0x41, 0x0a, 0x81, 0xbf, 0x66, 0xbc, 0x6a, 0x6a, 0x45, 0xb5, 0x32, 0x3e, 0x41, 0x0d,
|
||||
0x21, 0x99, 0xcc, 0x85, 0x5d, 0xd5, 0x1e, 0x5f, 0xbc, 0x86, 0x87, 0xd6, 0xf1, 0xd7, 0x8d, 0x4b,
|
||||
0xa3, 0x58, 0x53, 0xa3, 0xef, 0xbe, 0xa8, 0x22, 0xf7, 0x5a, 0xee, 0x4e, 0x12, 0xf7, 0xb9, 0xe4,
|
||||
0x49, 0x8c, 0xb7, 0x50, 0x4d, 0x0e, 0x53, 0xd0, 0x05, 0x6d, 0xf9, 0xef, 0x4c, 0x52, 0x3e, 0x1c,
|
||||
0xa6, 0x70, 0x31, 0x72, 0xde, 0x9c, 0x8f, 0x57, 0x38, 0xd5, 0x0c, 0xbc, 0x5f, 0x1e, 0xa5, 0xa1,
|
||||
0xb9, 0xf7, 0x2e, 0x27, 0x72, 0x31, 0x72, 0xae, 0xe8, 0x48, 0x52, 0x2a, 0x5d, 0x4e, 0x17, 0xbf,
|
||||
0x87, 0x1a, 0x19, 0x30, 0x91, 0xc4, 0xba, 0xf8, 0xad, 0xe9, 0xb1, 0xa8, 0x46, 0xa9, 0xd9, 0xc5,
|
||||
0xef, 0xa3, 0xd5, 0x08, 0x84, 0x60, 0x21, 0xe8, 0x0a, 0xb6, 0xfc, 0x1b, 0x26, 0x70, 0xf5, 0x7e,
|
||||
0x01, 0xd3, 0xc9, 0x3e, 0x7e, 0x84, 0xd6, 0x1f, 0x33, 0x21, 0x8f, 0xd2, 0x3e, 0x93, 0x70, 0xc8,
|
||||
0x23, 0xb0, 0x6b, 0xba, 0xe6, 0x1f, 0xbc, 0x5c, 0xd7, 0x28, 0x86, 0x7f, 0xdb, 0xa8, 0xaf, 0xef,
|
||||
0x5f, 0x52, 0xa2, 0x73, 0xca, 0x78, 0x80, 0xb0, 0x42, 0x0e, 0x33, 0x16, 0x8b, 0xa2, 0x50, 0xca,
|
||||
0xaf, 0xfe, 0xbf, 0xfd, 0x3a, 0xc6, 0x0f, 0xef, 0x2f, 0xa8, 0xd1, 0x2b, 0x1c, 0xdc, 0x91, 0x85,
|
||||
0xee, 0x5c, 0x7b, 0xcb, 0xfb, 0x5c, 0x48, 0xfc, 0xe3, 0xc2, 0xd4, 0x90, 0x97, 0xcb, 0x47, 0xb1,
|
||||
0xf5, 0xcc, 0xdc, 0x34, 0x39, 0x35, 0x27, 0xc8, 0xcc, 0xc4, 0xfc, 0x84, 0xea, 0x5c, 0x42, 0x24,
|
||||
0xec, 0x95, 0x5e, 0x75, 0xa3, 0x7d, 0x77, 0xfb, 0xd5, 0xdb, 0xd9, 0x7f, 0xc3, 0xd8, 0xd4, 0xf7,
|
||||
0x94, 0x20, 0x2d, 0x74, 0xdd, 0x3f, 0x6a, 0xff, 0x71, 0x40, 0x35, 0x58, 0xf8, 0x5d, 0xb4, 0x9a,
|
||||
0x15, 0x4b, 0x7d, 0xbe, 0x35, 0xbf, 0xad, 0xba, 0xc1, 0x44, 0xd0, 0xc9, 0x1e, 0x26, 0x08, 0x09,
|
||||
0x1e, 0xc6, 0x90, 0x7d, 0xcb, 0x22, 0xb0, 0x57, 0x8b, 0x26, 0x53, 0x2f, 0xc1, 0x41, 0x89, 0xd2,
|
||||
0x99, 0x08, 0xbc, 0x83, 0x6e, 0xc1, 0x93, 0x94, 0x67, 0x4c, 0x37, 0x2b, 0x04, 0x49, 0xdc, 0x17,
|
||||
0x76, 0xb3, 0x67, 0x6d, 0xd4, 0xfd, 0xb7, 0xc6, 0x23, 0xe7, 0xd6, 0xee, 0xfc, 0x26, 0x5d, 0x8c,
|
||||
0xc7, 0x04, 0x35, 0x72, 0xd5, 0x8b, 0xc2, 0xae, 0xf7, 0xaa, 0x1b, 0x2d, 0xff, 0xb6, 0xea, 0xe8,
|
||||
0x23, 0x8d, 0x5c, 0x8c, 0x9c, 0xe6, 0x37, 0x30, 0xd4, 0x0b, 0x6a, 0xa2, 0xf0, 0x47, 0xa8, 0x99,
|
||||
0x0b, 0xc8, 0x62, 0x95, 0x62, 0x31, 0x07, 0x65, 0xf1, 0x8f, 0x0c, 0x4e, 0xcb, 0x08, 0x7c, 0x07,
|
||||
0x55, 0x73, 0xde, 0x37, 0x73, 0xd0, 0x36, 0x81, 0xd5, 0xa3, 0xbd, 0xaf, 0xa8, 0xc2, 0xb1, 0x8b,
|
||||
0x1a, 0x61, 0x96, 0xe4, 0xa9, 0xb0, 0x6b, 0xda, 0x1c, 0x29, 0xf3, 0xaf, 0x35, 0x42, 0xcd, 0x0e,
|
||||
0x8e, 0x51, 0x1d, 0x9e, 0xc8, 0x8c, 0xd9, 0x0d, 0x7d, 0x7f, 0x7b, 0xaf, 0xf7, 0xe4, 0x91, 0x5d,
|
||||
0xa5, 0xb5, 0x1b, 0xcb, 0x6c, 0x38, 0xbd, 0x4e, 0x8d, 0xd1, 0xc2, 0xa6, 0x03, 0x08, 0x4d, 0x63,
|
||||
0xf0, 0x4d, 0x54, 0x3d, 0x85, 0x61, 0xf1, 0xf6, 0x50, 0xf5, 0x89, 0xbf, 0x44, 0xf5, 0x01, 0x7b,
|
||||
0x9c, 0x83, 0x79, 0x82, 0x3f, 0x5c, 0x9a, 0x8f, 0x56, 0xfb, 0x5e, 0x51, 0x68, 0xc1, 0xdc, 0x5e,
|
||||
0xd9, 0xb2, 0xdc, 0xbf, 0x2c, 0xe4, 0x2c, 0x79, 0x38, 0xf1, 0x2f, 0x08, 0x05, 0x93, 0xc7, 0x48,
|
||||
0xd8, 0x96, 0x3e, 0xff, 0xce, 0xab, 0x9f, 0xbf, 0x7c, 0xd8, 0xa6, 0xbf, 0x31, 0x25, 0x24, 0xe8,
|
||||
0x8c, 0x15, 0xde, 0x44, 0xed, 0x19, 0x69, 0x7d, 0xd2, 0x35, 0xff, 0xc6, 0x78, 0xe4, 0xb4, 0x67,
|
||||
0xc4, 0xe9, 0x6c, 0x8c, 0xfb, 0x99, 0x29, 0x9b, 0x3e, 0x28, 0x76, 0x26, 0x43, 0x67, 0xe9, 0x7b,
|
||||
0x6d, 0xcd, 0x0f, 0xcd, 0x76, 0xf3, 0xb7, 0xdf, 0x9d, 0xca, 0xd3, 0xbf, 0x7b, 0x15, 0x7f, 0xf7,
|
||||
0xec, 0xbc, 0x5b, 0x79, 0x76, 0xde, 0xad, 0x3c, 0x3f, 0xef, 0x56, 0x9e, 0x8e, 0xbb, 0xd6, 0xd9,
|
||||
0xb8, 0x6b, 0x3d, 0x1b, 0x77, 0xad, 0xe7, 0xe3, 0xae, 0xf5, 0xcf, 0xb8, 0x6b, 0xfd, 0xfa, 0xa2,
|
||||
0x5b, 0xf9, 0xc1, 0x59, 0xf2, 0xdf, 0xe5, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x35, 0x2f, 0x11,
|
||||
0xe8, 0xdd, 0x08, 0x00, 0x00,
|
||||
// 991 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x4f, 0x6f, 0xe3, 0x44,
|
||||
0x14, 0x8f, 0x9b, 0x3f, 0x4d, 0x26, 0xa5, 0xbb, 0x3b, 0x40, 0x65, 0x22, 0x6d, 0x1c, 0x59, 0x80,
|
||||
0xca, 0x3f, 0x9b, 0x96, 0x85, 0xad, 0x7a, 0x40, 0xe0, 0x50, 0xa1, 0x8a, 0x2e, 0x48, 0xd3, 0x16,
|
||||
0x01, 0x42, 0x62, 0xa7, 0xce, 0x5b, 0xd7, 0xdb, 0xc6, 0x36, 0x9e, 0x71, 0xd8, 0xdc, 0x56, 0xe2,
|
||||
0x0b, 0x70, 0xe4, 0xc8, 0x77, 0xe0, 0x4b, 0x94, 0x03, 0x52, 0xb9, 0xed, 0x01, 0x45, 0x34, 0xfb,
|
||||
0x2d, 0x7a, 0x42, 0x33, 0x9e, 0x38, 0x4e, 0xd2, 0x90, 0xa5, 0x2b, 0xed, 0x2d, 0xf3, 0xe6, 0xfd,
|
||||
0x7e, 0xbf, 0xf7, 0x9e, 0xdf, 0x7b, 0x13, 0x64, 0x9f, 0x6c, 0x31, 0xcb, 0x0f, 0x6d, 0x1a, 0xf9,
|
||||
0xb6, 0x0b, 0x31, 0xf7, 0x1f, 0xf8, 0x2e, 0xe5, 0xc0, 0xec, 0xde, 0xc6, 0x11, 0x70, 0xba, 0x61,
|
||||
0x7b, 0x10, 0x40, 0x4c, 0x39, 0x74, 0xac, 0x28, 0x0e, 0x79, 0x88, 0x8d, 0x14, 0x60, 0xd1, 0xc8,
|
||||
0xb7, 0xf2, 0x00, 0x4b, 0x01, 0x1a, 0xef, 0x79, 0x3e, 0x3f, 0x4e, 0x8e, 0x2c, 0x37, 0xec, 0xda,
|
||||
0x5e, 0xe8, 0x85, 0xb6, 0xc4, 0x1d, 0x25, 0x0f, 0xe4, 0x49, 0x1e, 0xe4, 0xaf, 0x94, 0xaf, 0x61,
|
||||
0xe6, 0x03, 0x08, 0x63, 0xb0, 0x7b, 0x33, 0x9a, 0x8d, 0x3b, 0x63, 0x9f, 0x2e, 0x75, 0x8f, 0xfd,
|
||||
0x00, 0xe2, 0xbe, 0x1d, 0x9d, 0x78, 0xc2, 0xc0, 0xec, 0x2e, 0x70, 0x7a, 0x15, 0xca, 0x9e, 0x87,
|
||||
0x8a, 0x93, 0x80, 0xfb, 0x5d, 0x98, 0x01, 0x7c, 0xb4, 0x08, 0xc0, 0xdc, 0x63, 0xe8, 0xd2, 0x69,
|
||||
0x9c, 0xf9, 0xc7, 0x12, 0x7a, 0xad, 0x3d, 0x2e, 0xc5, 0xbe, 0xef, 0x05, 0x7e, 0xe0, 0x11, 0xf8,
|
||||
0x31, 0x01, 0xc6, 0xf1, 0x7d, 0x54, 0x15, 0x11, 0x76, 0x28, 0xa7, 0xba, 0xd6, 0xd2, 0xd6, 0xeb,
|
||||
0x9b, 0xef, 0x5b, 0xe3, 0x1a, 0x66, 0x42, 0x56, 0x74, 0xe2, 0x09, 0x03, 0xb3, 0x84, 0xb7, 0xd5,
|
||||
0xdb, 0xb0, 0xbe, 0x3a, 0x7a, 0x08, 0x2e, 0xbf, 0x07, 0x9c, 0x3a, 0xf8, 0x6c, 0x60, 0x14, 0x86,
|
||||
0x03, 0x03, 0x8d, 0x6d, 0x24, 0x63, 0xc5, 0xf7, 0x51, 0x89, 0x45, 0xe0, 0xea, 0x4b, 0x92, 0xfd,
|
||||
0x63, 0x6b, 0xc1, 0x17, 0xb2, 0xe6, 0xc6, 0xba, 0x1f, 0x81, 0xeb, 0xac, 0x28, 0xad, 0x92, 0x38,
|
||||
0x11, 0xc9, 0x8c, 0x8f, 0x51, 0x85, 0x71, 0xca, 0x13, 0xa6, 0x17, 0xa5, 0xc6, 0x27, 0xcf, 0xa1,
|
||||
0x21, 0x79, 0x9c, 0x55, 0xa5, 0x52, 0x49, 0xcf, 0x44, 0xf1, 0x9b, 0x4f, 0x8b, 0xc8, 0x9c, 0x8b,
|
||||
0x6d, 0x87, 0x41, 0xc7, 0xe7, 0x7e, 0x18, 0xe0, 0x2d, 0x54, 0xe2, 0xfd, 0x08, 0x64, 0x41, 0x6b,
|
||||
0xce, 0xeb, 0xa3, 0x90, 0x0f, 0xfa, 0x11, 0x5c, 0x0e, 0x8c, 0x57, 0xa6, 0xfd, 0x85, 0x9d, 0x48,
|
||||
0x04, 0xde, 0xcb, 0x52, 0xa9, 0x48, 0xec, 0x9d, 0xc9, 0x40, 0x2e, 0x07, 0xc6, 0x15, 0x1d, 0x69,
|
||||
0x65, 0x4c, 0x93, 0xe1, 0xe2, 0x37, 0x51, 0x25, 0x06, 0xca, 0xc2, 0x40, 0x16, 0xbf, 0x36, 0x4e,
|
||||
0x8b, 0x48, 0x2b, 0x51, 0xb7, 0xf8, 0x2d, 0xb4, 0xdc, 0x05, 0xc6, 0xa8, 0x07, 0xb2, 0x82, 0x35,
|
||||
0xe7, 0x86, 0x72, 0x5c, 0xbe, 0x97, 0x9a, 0xc9, 0xe8, 0x1e, 0x3f, 0x44, 0xab, 0xa7, 0x94, 0xf1,
|
||||
0xc3, 0xa8, 0x43, 0x39, 0x1c, 0xf8, 0x5d, 0xd0, 0x4b, 0xb2, 0xe6, 0x6f, 0x3f, 0x5b, 0xd7, 0x08,
|
||||
0x84, 0xb3, 0xa6, 0xd8, 0x57, 0xf7, 0x26, 0x98, 0xc8, 0x14, 0x33, 0xee, 0x21, 0x2c, 0x2c, 0x07,
|
||||
0x31, 0x0d, 0x58, 0x5a, 0x28, 0xa1, 0x57, 0xfe, 0xdf, 0x7a, 0x0d, 0xa5, 0x87, 0xf7, 0x66, 0xd8,
|
||||
0xc8, 0x15, 0x0a, 0xe6, 0x40, 0x43, 0xb7, 0xe7, 0x7e, 0xe5, 0x3d, 0x9f, 0x71, 0xfc, 0xfd, 0xcc,
|
||||
0xd4, 0x58, 0xcf, 0x16, 0x8f, 0x40, 0xcb, 0x99, 0xb9, 0xa9, 0x62, 0xaa, 0x8e, 0x2c, 0xb9, 0x89,
|
||||
0xf9, 0x01, 0x95, 0x7d, 0x0e, 0x5d, 0xa6, 0x2f, 0xb5, 0x8a, 0xeb, 0xf5, 0xcd, 0xed, 0xeb, 0xb7,
|
||||
0xb3, 0xf3, 0x92, 0x92, 0x29, 0xef, 0x0a, 0x42, 0x92, 0xf2, 0x9a, 0xbf, 0x97, 0xfe, 0x23, 0x41,
|
||||
0x31, 0x58, 0xf8, 0x0d, 0xb4, 0x1c, 0xa7, 0x47, 0x99, 0xdf, 0x8a, 0x53, 0x17, 0xdd, 0xa0, 0x3c,
|
||||
0xc8, 0xe8, 0x0e, 0x5b, 0x08, 0x31, 0xdf, 0x0b, 0x20, 0xfe, 0x92, 0x76, 0x41, 0x5f, 0x4e, 0x9b,
|
||||
0x4c, 0x6c, 0x82, 0xfd, 0xcc, 0x4a, 0x72, 0x1e, 0xb8, 0x8d, 0x6e, 0xc1, 0xa3, 0xc8, 0x8f, 0xa9,
|
||||
0x6c, 0x56, 0x70, 0xc3, 0xa0, 0xc3, 0xf4, 0x6a, 0x4b, 0x5b, 0x2f, 0x3b, 0xaf, 0x0e, 0x07, 0xc6,
|
||||
0xad, 0x9d, 0xe9, 0x4b, 0x32, 0xeb, 0x8f, 0x2d, 0x54, 0x49, 0x44, 0x2f, 0x32, 0xbd, 0xdc, 0x2a,
|
||||
0xae, 0xd7, 0x9c, 0x35, 0xd1, 0xd1, 0x87, 0xd2, 0x72, 0x39, 0x30, 0xaa, 0x5f, 0x40, 0x5f, 0x1e,
|
||||
0x88, 0xf2, 0xc2, 0xef, 0xa2, 0x6a, 0xc2, 0x20, 0x0e, 0x44, 0x88, 0xe9, 0x1c, 0x64, 0xc5, 0x3f,
|
||||
0x54, 0x76, 0x92, 0x79, 0xe0, 0xdb, 0xa8, 0x98, 0xf8, 0x1d, 0x35, 0x07, 0x75, 0xe5, 0x58, 0x3c,
|
||||
0xdc, 0xfd, 0x8c, 0x08, 0x3b, 0x36, 0x51, 0xc5, 0x8b, 0xc3, 0x24, 0x62, 0x7a, 0x49, 0x8a, 0x23,
|
||||
0x21, 0xfe, 0xb9, 0xb4, 0x10, 0x75, 0x83, 0x03, 0x54, 0x86, 0x47, 0x3c, 0xa6, 0x7a, 0x45, 0x7e,
|
||||
0xbf, 0xdd, 0xe7, 0x5b, 0x79, 0xd6, 0x8e, 0xe0, 0xda, 0x09, 0x78, 0xdc, 0x1f, 0x7f, 0x4e, 0x69,
|
||||
0x23, 0xa9, 0x4c, 0x03, 0x10, 0x1a, 0xfb, 0xe0, 0x9b, 0xa8, 0x78, 0x02, 0xfd, 0x74, 0xf7, 0x10,
|
||||
0xf1, 0x13, 0x7f, 0x8a, 0xca, 0x3d, 0x7a, 0x9a, 0x80, 0x5a, 0xc1, 0xef, 0x2c, 0x8c, 0x47, 0xb2,
|
||||
0x7d, 0x2d, 0x20, 0x24, 0x45, 0x6e, 0x2f, 0x6d, 0x69, 0xe6, 0x9f, 0x1a, 0x32, 0x16, 0x2c, 0x4e,
|
||||
0xfc, 0x13, 0x42, 0xee, 0x68, 0x19, 0x31, 0x5d, 0x93, 0xf9, 0xb7, 0xaf, 0x9f, 0x7f, 0xb6, 0xd8,
|
||||
0xc6, 0x6f, 0x4c, 0x66, 0x62, 0x24, 0x27, 0x85, 0x37, 0x50, 0x3d, 0x47, 0x2d, 0x33, 0x5d, 0x71,
|
||||
0x6e, 0x0c, 0x07, 0x46, 0x3d, 0x47, 0x4e, 0xf2, 0x3e, 0xe6, 0x5f, 0x1a, 0xc2, 0xed, 0xd3, 0x84,
|
||||
0x71, 0x88, 0x0f, 0xe2, 0x84, 0x71, 0x27, 0x09, 0x3a, 0xa7, 0xf0, 0x02, 0x5e, 0xc4, 0x6f, 0x27,
|
||||
0x5e, 0xc4, 0xbb, 0x8b, 0xcb, 0x33, 0x13, 0xe4, 0xbc, 0xa7, 0xd0, 0x3c, 0xd7, 0xd0, 0xda, 0xac,
|
||||
0xfb, 0x0b, 0xd8, 0x59, 0xdf, 0x4c, 0xee, 0xac, 0x0f, 0xae, 0x91, 0xd4, 0x9c, 0x65, 0xf5, 0xf3,
|
||||
0x95, 0x29, 0xc9, 0x2d, 0xb5, 0x39, 0xb1, 0x7e, 0xd2, 0xd7, 0x36, 0x2b, 0xfd, 0x9c, 0x15, 0xf4,
|
||||
0x21, 0xaa, 0xf3, 0x31, 0x8d, 0x5a, 0x08, 0x2f, 0x2b, 0x50, 0x3d, 0xa7, 0x40, 0xf2, 0x7e, 0xe6,
|
||||
0x5d, 0x35, 0x63, 0x72, 0x2a, 0xb0, 0x31, 0xca, 0x56, 0x93, 0x4b, 0xa0, 0x36, 0x1d, 0xf4, 0x76,
|
||||
0xf5, 0xd7, 0xdf, 0x8c, 0xc2, 0xe3, 0xbf, 0x5b, 0x05, 0x67, 0xe7, 0xec, 0xa2, 0x59, 0x38, 0xbf,
|
||||
0x68, 0x16, 0x9e, 0x5c, 0x34, 0x0b, 0x8f, 0x87, 0x4d, 0xed, 0x6c, 0xd8, 0xd4, 0xce, 0x87, 0x4d,
|
||||
0xed, 0xc9, 0xb0, 0xa9, 0xfd, 0x33, 0x6c, 0x6a, 0xbf, 0x3c, 0x6d, 0x16, 0xbe, 0x33, 0x16, 0xfc,
|
||||
0xd1, 0xfd, 0x37, 0x00, 0x00, 0xff, 0xff, 0x17, 0xbe, 0xe3, 0x02, 0x0a, 0x0b, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *CertificateSigningRequest) Marshal() (dAtA []byte, err error) {
|
||||
@@ -595,6 +687,129 @@ func (m *CertificateSigningRequestStatus) MarshalToSizedBuffer(dAtA []byte) (int
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *ClusterTrustBundle) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *ClusterTrustBundle) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *ClusterTrustBundle) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
{
|
||||
size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
{
|
||||
size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *ClusterTrustBundleList) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *ClusterTrustBundleList) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *ClusterTrustBundleList) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Items) > 0 {
|
||||
for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
}
|
||||
{
|
||||
size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *ClusterTrustBundleSpec) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *ClusterTrustBundleSpec) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *ClusterTrustBundleSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
i -= len(m.TrustBundle)
|
||||
copy(dAtA[i:], m.TrustBundle)
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(len(m.TrustBundle)))
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
i -= len(m.SignerName)
|
||||
copy(dAtA[i:], m.SignerName)
|
||||
i = encodeVarintGenerated(dAtA, i, uint64(len(m.SignerName)))
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m ExtraValue) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
@@ -755,6 +970,49 @@ func (m *CertificateSigningRequestStatus) Size() (n int) {
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *ClusterTrustBundle) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = m.ObjectMeta.Size()
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
l = m.Spec.Size()
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *ClusterTrustBundleList) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = m.ListMeta.Size()
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
if len(m.Items) > 0 {
|
||||
for _, e := range m.Items {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *ClusterTrustBundleSpec) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.SignerName)
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
l = len(m.TrustBundle)
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
return n
|
||||
}
|
||||
|
||||
func (m ExtraValue) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
@@ -862,6 +1120,44 @@ func (this *CertificateSigningRequestStatus) String() string {
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func (this *ClusterTrustBundle) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
s := strings.Join([]string{`&ClusterTrustBundle{`,
|
||||
`ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`,
|
||||
`Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ClusterTrustBundleSpec", "ClusterTrustBundleSpec", 1), `&`, ``, 1) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func (this *ClusterTrustBundleList) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
repeatedStringForItems := "[]ClusterTrustBundle{"
|
||||
for _, f := range this.Items {
|
||||
repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ClusterTrustBundle", "ClusterTrustBundle", 1), `&`, ``, 1) + ","
|
||||
}
|
||||
repeatedStringForItems += "}"
|
||||
s := strings.Join([]string{`&ClusterTrustBundleList{`,
|
||||
`ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`,
|
||||
`Items:` + repeatedStringForItems + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func (this *ClusterTrustBundleSpec) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
s := strings.Join([]string{`&ClusterTrustBundleSpec{`,
|
||||
`SignerName:` + fmt.Sprintf("%v", this.SignerName) + `,`,
|
||||
`TrustBundle:` + fmt.Sprintf("%v", this.TrustBundle) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
func valueToStringGenerated(v interface{}) string {
|
||||
rv := reflect.ValueOf(v)
|
||||
if rv.IsNil() {
|
||||
@@ -1892,6 +2188,353 @@ func (m *CertificateSigningRequestStatus) Unmarshal(dAtA []byte) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *ClusterTrustBundle) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: ClusterTrustBundle: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: ClusterTrustBundle: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *ClusterTrustBundleList) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: ClusterTrustBundleList: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: ClusterTrustBundleList: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Items = append(m.Items, ClusterTrustBundle{})
|
||||
if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *ClusterTrustBundleSpec) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: ClusterTrustBundleSpec: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: ClusterTrustBundleSpec: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field SignerName", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.SignerName = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field TrustBundle", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.TrustBundle = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *ExtraValue) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
|
||||
@@ -190,6 +190,79 @@ message CertificateSigningRequestStatus {
|
||||
optional bytes certificate = 2;
|
||||
}
|
||||
|
||||
// ClusterTrustBundle is a cluster-scoped container for X.509 trust anchors
|
||||
// (root certificates).
|
||||
//
|
||||
// ClusterTrustBundle objects are considered to be readable by any authenticated
|
||||
// user in the cluster, because they can be mounted by pods using the
|
||||
// `clusterTrustBundle` projection. All service accounts have read access to
|
||||
// ClusterTrustBundles by default. Users who only have namespace-level access
|
||||
// to a cluster can read ClusterTrustBundles by impersonating a serviceaccount
|
||||
// that they have access to.
|
||||
//
|
||||
// It can be optionally associated with a particular assigner, in which case it
|
||||
// contains one valid set of trust anchors for that signer. Signers may have
|
||||
// multiple associated ClusterTrustBundles; each is an independent set of trust
|
||||
// anchors for that signer. Admission control is used to enforce that only users
|
||||
// with permissions on the signer can create or modify the corresponding bundle.
|
||||
message ClusterTrustBundle {
|
||||
// metadata contains the object metadata.
|
||||
// +optional
|
||||
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
|
||||
|
||||
// spec contains the signer (if any) and trust anchors.
|
||||
optional ClusterTrustBundleSpec spec = 2;
|
||||
}
|
||||
|
||||
// ClusterTrustBundleList is a collection of ClusterTrustBundle objects
|
||||
message ClusterTrustBundleList {
|
||||
// metadata contains the list metadata.
|
||||
//
|
||||
// +optional
|
||||
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
|
||||
|
||||
// items is a collection of ClusterTrustBundle objects
|
||||
repeated ClusterTrustBundle items = 2;
|
||||
}
|
||||
|
||||
// ClusterTrustBundleSpec contains the signer and trust anchors.
|
||||
message ClusterTrustBundleSpec {
|
||||
// signerName indicates the associated signer, if any.
|
||||
//
|
||||
// In order to create or update a ClusterTrustBundle that sets signerName,
|
||||
// you must have the following cluster-scoped permission:
|
||||
// group=certificates.k8s.io resource=signers resourceName=<the signer name>
|
||||
// verb=attest.
|
||||
//
|
||||
// If signerName is not empty, then the ClusterTrustBundle object must be
|
||||
// named with the signer name as a prefix (translating slashes to colons).
|
||||
// For example, for the signer name `example.com/foo`, valid
|
||||
// ClusterTrustBundle object names include `example.com:foo:abc` and
|
||||
// `example.com:foo:v1`.
|
||||
//
|
||||
// If signerName is empty, then the ClusterTrustBundle object's name must
|
||||
// not have such a prefix.
|
||||
//
|
||||
// List/watch requests for ClusterTrustBundles can filter on this field
|
||||
// using a `spec.signerName=NAME` field selector.
|
||||
//
|
||||
// +optional
|
||||
optional string signerName = 1;
|
||||
|
||||
// trustBundle contains the individual X.509 trust anchors for this
|
||||
// bundle, as PEM bundle of PEM-wrapped, DER-formatted X.509 certificates.
|
||||
//
|
||||
// The data must consist only of PEM certificate blocks that parse as valid
|
||||
// X.509 certificates. Each certificate must include a basic constraints
|
||||
// extension with the CA bit set. The API server will reject objects that
|
||||
// contain duplicate certificates, or that use PEM block headers.
|
||||
//
|
||||
// Users of ClusterTrustBundles, including Kubelet, are free to reorder and
|
||||
// deduplicate certificate blocks in this file according to their own logic,
|
||||
// as well as to drop PEM block headers and inter-block data.
|
||||
optional string trustBundle = 2;
|
||||
}
|
||||
|
||||
// ExtraValue masks the value so protobuf can generate
|
||||
// +protobuf.nullable=true
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
|
||||
@@ -51,6 +51,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&CertificateSigningRequest{},
|
||||
&CertificateSigningRequestList{},
|
||||
&ClusterTrustBundle{},
|
||||
&ClusterTrustBundleList{},
|
||||
)
|
||||
|
||||
// Add the watch version that applies
|
||||
|
||||
@@ -262,3 +262,88 @@ const (
|
||||
UsageMicrosoftSGC KeyUsage = "microsoft sgc"
|
||||
UsageNetscapeSGC KeyUsage = "netscape sgc"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.33
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ClusterTrustBundle is a cluster-scoped container for X.509 trust anchors
|
||||
// (root certificates).
|
||||
//
|
||||
// ClusterTrustBundle objects are considered to be readable by any authenticated
|
||||
// user in the cluster, because they can be mounted by pods using the
|
||||
// `clusterTrustBundle` projection. All service accounts have read access to
|
||||
// ClusterTrustBundles by default. Users who only have namespace-level access
|
||||
// to a cluster can read ClusterTrustBundles by impersonating a serviceaccount
|
||||
// that they have access to.
|
||||
//
|
||||
// It can be optionally associated with a particular assigner, in which case it
|
||||
// contains one valid set of trust anchors for that signer. Signers may have
|
||||
// multiple associated ClusterTrustBundles; each is an independent set of trust
|
||||
// anchors for that signer. Admission control is used to enforce that only users
|
||||
// with permissions on the signer can create or modify the corresponding bundle.
|
||||
type ClusterTrustBundle struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// metadata contains the object metadata.
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
|
||||
// spec contains the signer (if any) and trust anchors.
|
||||
Spec ClusterTrustBundleSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"`
|
||||
}
|
||||
|
||||
// ClusterTrustBundleSpec contains the signer and trust anchors.
|
||||
type ClusterTrustBundleSpec struct {
|
||||
// signerName indicates the associated signer, if any.
|
||||
//
|
||||
// In order to create or update a ClusterTrustBundle that sets signerName,
|
||||
// you must have the following cluster-scoped permission:
|
||||
// group=certificates.k8s.io resource=signers resourceName=<the signer name>
|
||||
// verb=attest.
|
||||
//
|
||||
// If signerName is not empty, then the ClusterTrustBundle object must be
|
||||
// named with the signer name as a prefix (translating slashes to colons).
|
||||
// For example, for the signer name `example.com/foo`, valid
|
||||
// ClusterTrustBundle object names include `example.com:foo:abc` and
|
||||
// `example.com:foo:v1`.
|
||||
//
|
||||
// If signerName is empty, then the ClusterTrustBundle object's name must
|
||||
// not have such a prefix.
|
||||
//
|
||||
// List/watch requests for ClusterTrustBundles can filter on this field
|
||||
// using a `spec.signerName=NAME` field selector.
|
||||
//
|
||||
// +optional
|
||||
SignerName string `json:"signerName,omitempty" protobuf:"bytes,1,opt,name=signerName"`
|
||||
|
||||
// trustBundle contains the individual X.509 trust anchors for this
|
||||
// bundle, as PEM bundle of PEM-wrapped, DER-formatted X.509 certificates.
|
||||
//
|
||||
// The data must consist only of PEM certificate blocks that parse as valid
|
||||
// X.509 certificates. Each certificate must include a basic constraints
|
||||
// extension with the CA bit set. The API server will reject objects that
|
||||
// contain duplicate certificates, or that use PEM block headers.
|
||||
//
|
||||
// Users of ClusterTrustBundles, including Kubelet, are free to reorder and
|
||||
// deduplicate certificate blocks in this file according to their own logic,
|
||||
// as well as to drop PEM block headers and inter-block data.
|
||||
TrustBundle string `json:"trustBundle" protobuf:"bytes,2,opt,name=trustBundle"`
|
||||
}
|
||||
|
||||
// +k8s:prerelease-lifecycle-gen:introduced=1.33
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ClusterTrustBundleList is a collection of ClusterTrustBundle objects
|
||||
type ClusterTrustBundleList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// metadata contains the list metadata.
|
||||
//
|
||||
// +optional
|
||||
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
|
||||
// items is a collection of ClusterTrustBundle objects
|
||||
Items []ClusterTrustBundle `json:"items" protobuf:"bytes,2,rep,name=items"`
|
||||
}
|
||||
|
||||
@@ -75,4 +75,34 @@ func (CertificateSigningRequestStatus) SwaggerDoc() map[string]string {
|
||||
return map_CertificateSigningRequestStatus
|
||||
}
|
||||
|
||||
var map_ClusterTrustBundle = map[string]string{
|
||||
"": "ClusterTrustBundle is a cluster-scoped container for X.509 trust anchors (root certificates).\n\nClusterTrustBundle objects are considered to be readable by any authenticated user in the cluster, because they can be mounted by pods using the `clusterTrustBundle` projection. All service accounts have read access to ClusterTrustBundles by default. Users who only have namespace-level access to a cluster can read ClusterTrustBundles by impersonating a serviceaccount that they have access to.\n\nIt can be optionally associated with a particular assigner, in which case it contains one valid set of trust anchors for that signer. Signers may have multiple associated ClusterTrustBundles; each is an independent set of trust anchors for that signer. Admission control is used to enforce that only users with permissions on the signer can create or modify the corresponding bundle.",
|
||||
"metadata": "metadata contains the object metadata.",
|
||||
"spec": "spec contains the signer (if any) and trust anchors.",
|
||||
}
|
||||
|
||||
func (ClusterTrustBundle) SwaggerDoc() map[string]string {
|
||||
return map_ClusterTrustBundle
|
||||
}
|
||||
|
||||
var map_ClusterTrustBundleList = map[string]string{
|
||||
"": "ClusterTrustBundleList is a collection of ClusterTrustBundle objects",
|
||||
"metadata": "metadata contains the list metadata.",
|
||||
"items": "items is a collection of ClusterTrustBundle objects",
|
||||
}
|
||||
|
||||
func (ClusterTrustBundleList) SwaggerDoc() map[string]string {
|
||||
return map_ClusterTrustBundleList
|
||||
}
|
||||
|
||||
var map_ClusterTrustBundleSpec = map[string]string{
|
||||
"": "ClusterTrustBundleSpec contains the signer and trust anchors.",
|
||||
"signerName": "signerName indicates the associated signer, if any.\n\nIn order to create or update a ClusterTrustBundle that sets signerName, you must have the following cluster-scoped permission: group=certificates.k8s.io resource=signers resourceName=<the signer name> verb=attest.\n\nIf signerName is not empty, then the ClusterTrustBundle object must be named with the signer name as a prefix (translating slashes to colons). For example, for the signer name `example.com/foo`, valid ClusterTrustBundle object names include `example.com:foo:abc` and `example.com:foo:v1`.\n\nIf signerName is empty, then the ClusterTrustBundle object's name must not have such a prefix.\n\nList/watch requests for ClusterTrustBundles can filter on this field using a `spec.signerName=NAME` field selector.",
|
||||
"trustBundle": "trustBundle contains the individual X.509 trust anchors for this bundle, as PEM bundle of PEM-wrapped, DER-formatted X.509 certificates.\n\nThe data must consist only of PEM certificate blocks that parse as valid X.509 certificates. Each certificate must include a basic constraints extension with the CA bit set. The API server will reject objects that contain duplicate certificates, or that use PEM block headers.\n\nUsers of ClusterTrustBundles, including Kubelet, are free to reorder and deduplicate certificate blocks in this file according to their own logic, as well as to drop PEM block headers and inter-block data.",
|
||||
}
|
||||
|
||||
func (ClusterTrustBundleSpec) SwaggerDoc() map[string]string {
|
||||
return map_ClusterTrustBundleSpec
|
||||
}
|
||||
|
||||
// AUTO-GENERATED FUNCTIONS END HERE
|
||||
|
||||
@@ -188,6 +188,82 @@ func (in *CertificateSigningRequestStatus) DeepCopy() *CertificateSigningRequest
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterTrustBundle) DeepCopyInto(out *ClusterTrustBundle) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTrustBundle.
|
||||
func (in *ClusterTrustBundle) DeepCopy() *ClusterTrustBundle {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterTrustBundle)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ClusterTrustBundle) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterTrustBundleList) DeepCopyInto(out *ClusterTrustBundleList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]ClusterTrustBundle, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTrustBundleList.
|
||||
func (in *ClusterTrustBundleList) DeepCopy() *ClusterTrustBundleList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterTrustBundleList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ClusterTrustBundleList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterTrustBundleSpec) DeepCopyInto(out *ClusterTrustBundleSpec) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTrustBundleSpec.
|
||||
func (in *ClusterTrustBundleSpec) DeepCopy() *ClusterTrustBundleSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterTrustBundleSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in ExtraValue) DeepCopyInto(out *ExtraValue) {
|
||||
{
|
||||
|
||||
@@ -72,3 +72,39 @@ func (in *CertificateSigningRequestList) APILifecycleReplacement() schema.GroupV
|
||||
func (in *CertificateSigningRequestList) APILifecycleRemoved() (major, minor int) {
|
||||
return 1, 22
|
||||
}
|
||||
|
||||
// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison.
|
||||
// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go.
|
||||
func (in *ClusterTrustBundle) APILifecycleIntroduced() (major, minor int) {
|
||||
return 1, 33
|
||||
}
|
||||
|
||||
// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison.
|
||||
// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor.
|
||||
func (in *ClusterTrustBundle) APILifecycleDeprecated() (major, minor int) {
|
||||
return 1, 36
|
||||
}
|
||||
|
||||
// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison.
|
||||
// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor.
|
||||
func (in *ClusterTrustBundle) APILifecycleRemoved() (major, minor int) {
|
||||
return 1, 39
|
||||
}
|
||||
|
||||
// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison.
|
||||
// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go.
|
||||
func (in *ClusterTrustBundleList) APILifecycleIntroduced() (major, minor int) {
|
||||
return 1, 33
|
||||
}
|
||||
|
||||
// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison.
|
||||
// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor.
|
||||
func (in *ClusterTrustBundleList) APILifecycleDeprecated() (major, minor int) {
|
||||
return 1, 36
|
||||
}
|
||||
|
||||
// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison.
|
||||
// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor.
|
||||
func (in *ClusterTrustBundleList) APILifecycleRemoved() (major, minor int) {
|
||||
return 1, 39
|
||||
}
|
||||
|
||||
50
staging/src/k8s.io/api/testdata/HEAD/certificates.k8s.io.v1beta1.ClusterTrustBundle.json
vendored
Normal file
50
staging/src/k8s.io/api/testdata/HEAD/certificates.k8s.io.v1beta1.ClusterTrustBundle.json
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"kind": "ClusterTrustBundle",
|
||||
"apiVersion": "certificates.k8s.io/v1beta1",
|
||||
"metadata": {
|
||||
"name": "nameValue",
|
||||
"generateName": "generateNameValue",
|
||||
"namespace": "namespaceValue",
|
||||
"selfLink": "selfLinkValue",
|
||||
"uid": "uidValue",
|
||||
"resourceVersion": "resourceVersionValue",
|
||||
"generation": 7,
|
||||
"creationTimestamp": "2008-01-01T01:01:01Z",
|
||||
"deletionTimestamp": "2009-01-01T01:01:01Z",
|
||||
"deletionGracePeriodSeconds": 10,
|
||||
"labels": {
|
||||
"labelsKey": "labelsValue"
|
||||
},
|
||||
"annotations": {
|
||||
"annotationsKey": "annotationsValue"
|
||||
},
|
||||
"ownerReferences": [
|
||||
{
|
||||
"apiVersion": "apiVersionValue",
|
||||
"kind": "kindValue",
|
||||
"name": "nameValue",
|
||||
"uid": "uidValue",
|
||||
"controller": true,
|
||||
"blockOwnerDeletion": true
|
||||
}
|
||||
],
|
||||
"finalizers": [
|
||||
"finalizersValue"
|
||||
],
|
||||
"managedFields": [
|
||||
{
|
||||
"manager": "managerValue",
|
||||
"operation": "operationValue",
|
||||
"apiVersion": "apiVersionValue",
|
||||
"time": "2004-01-01T01:01:01Z",
|
||||
"fieldsType": "fieldsTypeValue",
|
||||
"fieldsV1": {},
|
||||
"subresource": "subresourceValue"
|
||||
}
|
||||
]
|
||||
},
|
||||
"spec": {
|
||||
"signerName": "signerNameValue",
|
||||
"trustBundle": "trustBundleValue"
|
||||
}
|
||||
}
|
||||
BIN
staging/src/k8s.io/api/testdata/HEAD/certificates.k8s.io.v1beta1.ClusterTrustBundle.pb
vendored
Normal file
BIN
staging/src/k8s.io/api/testdata/HEAD/certificates.k8s.io.v1beta1.ClusterTrustBundle.pb
vendored
Normal file
Binary file not shown.
37
staging/src/k8s.io/api/testdata/HEAD/certificates.k8s.io.v1beta1.ClusterTrustBundle.yaml
vendored
Normal file
37
staging/src/k8s.io/api/testdata/HEAD/certificates.k8s.io.v1beta1.ClusterTrustBundle.yaml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
apiVersion: certificates.k8s.io/v1beta1
|
||||
kind: ClusterTrustBundle
|
||||
metadata:
|
||||
annotations:
|
||||
annotationsKey: annotationsValue
|
||||
creationTimestamp: "2008-01-01T01:01:01Z"
|
||||
deletionGracePeriodSeconds: 10
|
||||
deletionTimestamp: "2009-01-01T01:01:01Z"
|
||||
finalizers:
|
||||
- finalizersValue
|
||||
generateName: generateNameValue
|
||||
generation: 7
|
||||
labels:
|
||||
labelsKey: labelsValue
|
||||
managedFields:
|
||||
- apiVersion: apiVersionValue
|
||||
fieldsType: fieldsTypeValue
|
||||
fieldsV1: {}
|
||||
manager: managerValue
|
||||
operation: operationValue
|
||||
subresource: subresourceValue
|
||||
time: "2004-01-01T01:01:01Z"
|
||||
name: nameValue
|
||||
namespace: namespaceValue
|
||||
ownerReferences:
|
||||
- apiVersion: apiVersionValue
|
||||
blockOwnerDeletion: true
|
||||
controller: true
|
||||
kind: kindValue
|
||||
name: nameValue
|
||||
uid: uidValue
|
||||
resourceVersion: resourceVersionValue
|
||||
selfLink: selfLinkValue
|
||||
uid: uidValue
|
||||
spec:
|
||||
signerName: signerNameValue
|
||||
trustBundle: trustBundleValue
|
||||
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
managedfields "k8s.io/apimachinery/pkg/util/managedfields"
|
||||
internal "k8s.io/client-go/applyconfigurations/internal"
|
||||
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||
)
|
||||
|
||||
// ClusterTrustBundleApplyConfiguration represents a declarative configuration of the ClusterTrustBundle type for use
|
||||
// with apply.
|
||||
type ClusterTrustBundleApplyConfiguration struct {
|
||||
v1.TypeMetaApplyConfiguration `json:",inline"`
|
||||
*v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"`
|
||||
Spec *ClusterTrustBundleSpecApplyConfiguration `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// ClusterTrustBundle constructs a declarative configuration of the ClusterTrustBundle type for use with
|
||||
// apply.
|
||||
func ClusterTrustBundle(name string) *ClusterTrustBundleApplyConfiguration {
|
||||
b := &ClusterTrustBundleApplyConfiguration{}
|
||||
b.WithName(name)
|
||||
b.WithKind("ClusterTrustBundle")
|
||||
b.WithAPIVersion("certificates.k8s.io/v1beta1")
|
||||
return b
|
||||
}
|
||||
|
||||
// ExtractClusterTrustBundle extracts the applied configuration owned by fieldManager from
|
||||
// clusterTrustBundle. If no managedFields are found in clusterTrustBundle for fieldManager, a
|
||||
// ClusterTrustBundleApplyConfiguration is returned with only the Name, Namespace (if applicable),
|
||||
// APIVersion and Kind populated. It is possible that no managed fields were found for because other
|
||||
// field managers have taken ownership of all the fields previously owned by fieldManager, or because
|
||||
// the fieldManager never owned fields any fields.
|
||||
// clusterTrustBundle must be a unmodified ClusterTrustBundle API object that was retrieved from the Kubernetes API.
|
||||
// ExtractClusterTrustBundle provides a way to perform a extract/modify-in-place/apply workflow.
|
||||
// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously
|
||||
// applied if another fieldManager has updated or force applied any of the previously applied fields.
|
||||
// Experimental!
|
||||
func ExtractClusterTrustBundle(clusterTrustBundle *certificatesv1beta1.ClusterTrustBundle, fieldManager string) (*ClusterTrustBundleApplyConfiguration, error) {
|
||||
return extractClusterTrustBundle(clusterTrustBundle, fieldManager, "")
|
||||
}
|
||||
|
||||
// ExtractClusterTrustBundleStatus is the same as ExtractClusterTrustBundle except
|
||||
// that it extracts the status subresource applied configuration.
|
||||
// Experimental!
|
||||
func ExtractClusterTrustBundleStatus(clusterTrustBundle *certificatesv1beta1.ClusterTrustBundle, fieldManager string) (*ClusterTrustBundleApplyConfiguration, error) {
|
||||
return extractClusterTrustBundle(clusterTrustBundle, fieldManager, "status")
|
||||
}
|
||||
|
||||
func extractClusterTrustBundle(clusterTrustBundle *certificatesv1beta1.ClusterTrustBundle, fieldManager string, subresource string) (*ClusterTrustBundleApplyConfiguration, error) {
|
||||
b := &ClusterTrustBundleApplyConfiguration{}
|
||||
err := managedfields.ExtractInto(clusterTrustBundle, internal.Parser().Type("io.k8s.api.certificates.v1beta1.ClusterTrustBundle"), fieldManager, b, subresource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b.WithName(clusterTrustBundle.Name)
|
||||
|
||||
b.WithKind("ClusterTrustBundle")
|
||||
b.WithAPIVersion("certificates.k8s.io/v1beta1")
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// WithKind sets the Kind 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 Kind field is set to the value of the last call.
|
||||
func (b *ClusterTrustBundleApplyConfiguration) WithKind(value string) *ClusterTrustBundleApplyConfiguration {
|
||||
b.TypeMetaApplyConfiguration.Kind = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithAPIVersion sets the APIVersion 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 APIVersion field is set to the value of the last call.
|
||||
func (b *ClusterTrustBundleApplyConfiguration) WithAPIVersion(value string) *ClusterTrustBundleApplyConfiguration {
|
||||
b.TypeMetaApplyConfiguration.APIVersion = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithName sets the Name 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 Name field is set to the value of the last call.
|
||||
func (b *ClusterTrustBundleApplyConfiguration) WithName(value string) *ClusterTrustBundleApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.Name = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithGenerateName sets the GenerateName 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 GenerateName field is set to the value of the last call.
|
||||
func (b *ClusterTrustBundleApplyConfiguration) WithGenerateName(value string) *ClusterTrustBundleApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.GenerateName = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithNamespace sets the Namespace 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 Namespace field is set to the value of the last call.
|
||||
func (b *ClusterTrustBundleApplyConfiguration) WithNamespace(value string) *ClusterTrustBundleApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.Namespace = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithUID sets the UID 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 UID field is set to the value of the last call.
|
||||
func (b *ClusterTrustBundleApplyConfiguration) WithUID(value types.UID) *ClusterTrustBundleApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.UID = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithResourceVersion sets the ResourceVersion 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 ResourceVersion field is set to the value of the last call.
|
||||
func (b *ClusterTrustBundleApplyConfiguration) WithResourceVersion(value string) *ClusterTrustBundleApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.ResourceVersion = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithGeneration sets the Generation 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 Generation field is set to the value of the last call.
|
||||
func (b *ClusterTrustBundleApplyConfiguration) WithGeneration(value int64) *ClusterTrustBundleApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.Generation = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithCreationTimestamp sets the CreationTimestamp 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 CreationTimestamp field is set to the value of the last call.
|
||||
func (b *ClusterTrustBundleApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ClusterTrustBundleApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.CreationTimestamp = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithDeletionTimestamp sets the DeletionTimestamp 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 DeletionTimestamp field is set to the value of the last call.
|
||||
func (b *ClusterTrustBundleApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ClusterTrustBundleApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds 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 DeletionGracePeriodSeconds field is set to the value of the last call.
|
||||
func (b *ClusterTrustBundleApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ClusterTrustBundleApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithLabels puts the entries into the Labels field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, the entries provided by each call will be put on the Labels field,
|
||||
// overwriting an existing map entries in Labels field with the same key.
|
||||
func (b *ClusterTrustBundleApplyConfiguration) WithLabels(entries map[string]string) *ClusterTrustBundleApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 {
|
||||
b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries))
|
||||
}
|
||||
for k, v := range entries {
|
||||
b.ObjectMetaApplyConfiguration.Labels[k] = v
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithAnnotations puts the entries into the Annotations field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, the entries provided by each call will be put on the Annotations field,
|
||||
// overwriting an existing map entries in Annotations field with the same key.
|
||||
func (b *ClusterTrustBundleApplyConfiguration) WithAnnotations(entries map[string]string) *ClusterTrustBundleApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 {
|
||||
b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries))
|
||||
}
|
||||
for k, v := range entries {
|
||||
b.ObjectMetaApplyConfiguration.Annotations[k] = v
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the OwnerReferences field.
|
||||
func (b *ClusterTrustBundleApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ClusterTrustBundleApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
for i := range values {
|
||||
if values[i] == nil {
|
||||
panic("nil value passed to WithOwnerReferences")
|
||||
}
|
||||
b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithFinalizers adds the given value to the Finalizers field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the Finalizers field.
|
||||
func (b *ClusterTrustBundleApplyConfiguration) WithFinalizers(values ...string) *ClusterTrustBundleApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
for i := range values {
|
||||
b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *ClusterTrustBundleApplyConfiguration) ensureObjectMetaApplyConfigurationExists() {
|
||||
if b.ObjectMetaApplyConfiguration == nil {
|
||||
b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{}
|
||||
}
|
||||
}
|
||||
|
||||
// WithSpec sets the Spec 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 Spec field is set to the value of the last call.
|
||||
func (b *ClusterTrustBundleApplyConfiguration) WithSpec(value *ClusterTrustBundleSpecApplyConfiguration) *ClusterTrustBundleApplyConfiguration {
|
||||
b.Spec = value
|
||||
return b
|
||||
}
|
||||
|
||||
// GetName retrieves the value of the Name field in the declarative configuration.
|
||||
func (b *ClusterTrustBundleApplyConfiguration) GetName() *string {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
return b.ObjectMetaApplyConfiguration.Name
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by applyconfiguration-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
// ClusterTrustBundleSpecApplyConfiguration represents a declarative configuration of the ClusterTrustBundleSpec type for use
|
||||
// with apply.
|
||||
type ClusterTrustBundleSpecApplyConfiguration struct {
|
||||
SignerName *string `json:"signerName,omitempty"`
|
||||
TrustBundle *string `json:"trustBundle,omitempty"`
|
||||
}
|
||||
|
||||
// ClusterTrustBundleSpecApplyConfiguration constructs a declarative configuration of the ClusterTrustBundleSpec type for use with
|
||||
// apply.
|
||||
func ClusterTrustBundleSpec() *ClusterTrustBundleSpecApplyConfiguration {
|
||||
return &ClusterTrustBundleSpecApplyConfiguration{}
|
||||
}
|
||||
|
||||
// WithSignerName sets the SignerName 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 SignerName field is set to the value of the last call.
|
||||
func (b *ClusterTrustBundleSpecApplyConfiguration) WithSignerName(value string) *ClusterTrustBundleSpecApplyConfiguration {
|
||||
b.SignerName = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithTrustBundle sets the TrustBundle 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 TrustBundle field is set to the value of the last call.
|
||||
func (b *ClusterTrustBundleSpecApplyConfiguration) WithTrustBundle(value string) *ClusterTrustBundleSpecApplyConfiguration {
|
||||
b.TrustBundle = &value
|
||||
return b
|
||||
}
|
||||
@@ -4445,6 +4445,33 @@ var schemaYAML = typed.YAMLObject(`types:
|
||||
elementRelationship: associative
|
||||
keys:
|
||||
- type
|
||||
- name: io.k8s.api.certificates.v1beta1.ClusterTrustBundle
|
||||
map:
|
||||
fields:
|
||||
- name: apiVersion
|
||||
type:
|
||||
scalar: string
|
||||
- name: kind
|
||||
type:
|
||||
scalar: string
|
||||
- name: metadata
|
||||
type:
|
||||
namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta
|
||||
default: {}
|
||||
- name: spec
|
||||
type:
|
||||
namedType: io.k8s.api.certificates.v1beta1.ClusterTrustBundleSpec
|
||||
default: {}
|
||||
- name: io.k8s.api.certificates.v1beta1.ClusterTrustBundleSpec
|
||||
map:
|
||||
fields:
|
||||
- name: signerName
|
||||
type:
|
||||
scalar: string
|
||||
- name: trustBundle
|
||||
type:
|
||||
scalar: string
|
||||
default: ""
|
||||
- name: io.k8s.api.coordination.v1.Lease
|
||||
map:
|
||||
fields:
|
||||
|
||||
@@ -624,6 +624,10 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
|
||||
return &applyconfigurationscertificatesv1beta1.CertificateSigningRequestSpecApplyConfiguration{}
|
||||
case certificatesv1beta1.SchemeGroupVersion.WithKind("CertificateSigningRequestStatus"):
|
||||
return &applyconfigurationscertificatesv1beta1.CertificateSigningRequestStatusApplyConfiguration{}
|
||||
case certificatesv1beta1.SchemeGroupVersion.WithKind("ClusterTrustBundle"):
|
||||
return &applyconfigurationscertificatesv1beta1.ClusterTrustBundleApplyConfiguration{}
|
||||
case certificatesv1beta1.SchemeGroupVersion.WithKind("ClusterTrustBundleSpec"):
|
||||
return &applyconfigurationscertificatesv1beta1.ClusterTrustBundleSpecApplyConfiguration{}
|
||||
|
||||
// Group=coordination.k8s.io, Version=v1
|
||||
case coordinationv1.SchemeGroupVersion.WithKind("Lease"):
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
time "time"
|
||||
|
||||
apicertificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
kubernetes "k8s.io/client-go/kubernetes"
|
||||
certificatesv1beta1 "k8s.io/client-go/listers/certificates/v1beta1"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// ClusterTrustBundleInformer provides access to a shared informer and lister for
|
||||
// ClusterTrustBundles.
|
||||
type ClusterTrustBundleInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() certificatesv1beta1.ClusterTrustBundleLister
|
||||
}
|
||||
|
||||
type clusterTrustBundleInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// NewClusterTrustBundleInformer constructs a new informer for ClusterTrustBundle type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewClusterTrustBundleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredClusterTrustBundleInformer(client, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredClusterTrustBundleInformer constructs a new informer for ClusterTrustBundle type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredClusterTrustBundleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CertificatesV1beta1().ClusterTrustBundles().List(context.Background(), options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CertificatesV1beta1().ClusterTrustBundles().Watch(context.Background(), options)
|
||||
},
|
||||
ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CertificatesV1beta1().ClusterTrustBundles().List(ctx, options)
|
||||
},
|
||||
WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CertificatesV1beta1().ClusterTrustBundles().Watch(ctx, options)
|
||||
},
|
||||
},
|
||||
&apicertificatesv1beta1.ClusterTrustBundle{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *clusterTrustBundleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredClusterTrustBundleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *clusterTrustBundleInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&apicertificatesv1beta1.ClusterTrustBundle{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *clusterTrustBundleInformer) Lister() certificatesv1beta1.ClusterTrustBundleLister {
|
||||
return certificatesv1beta1.NewClusterTrustBundleLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -26,6 +26,8 @@ import (
|
||||
type Interface interface {
|
||||
// CertificateSigningRequests returns a CertificateSigningRequestInformer.
|
||||
CertificateSigningRequests() CertificateSigningRequestInformer
|
||||
// ClusterTrustBundles returns a ClusterTrustBundleInformer.
|
||||
ClusterTrustBundles() ClusterTrustBundleInformer
|
||||
}
|
||||
|
||||
type version struct {
|
||||
@@ -43,3 +45,8 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
|
||||
func (v *version) CertificateSigningRequests() CertificateSigningRequestInformer {
|
||||
return &certificateSigningRequestInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// ClusterTrustBundles returns a ClusterTrustBundleInformer.
|
||||
func (v *version) ClusterTrustBundles() ClusterTrustBundleInformer {
|
||||
return &clusterTrustBundleInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
@@ -199,6 +199,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
||||
// Group=certificates.k8s.io, Version=v1beta1
|
||||
case certificatesv1beta1.SchemeGroupVersion.WithResource("certificatesigningrequests"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Certificates().V1beta1().CertificateSigningRequests().Informer()}, nil
|
||||
case certificatesv1beta1.SchemeGroupVersion.WithResource("clustertrustbundles"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Certificates().V1beta1().ClusterTrustBundles().Informer()}, nil
|
||||
|
||||
// Group=coordination.k8s.io, Version=v1
|
||||
case coordinationv1.SchemeGroupVersion.WithResource("leases"):
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
type CertificatesV1beta1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
CertificateSigningRequestsGetter
|
||||
ClusterTrustBundlesGetter
|
||||
}
|
||||
|
||||
// CertificatesV1beta1Client is used to interact with features provided by the certificates.k8s.io group.
|
||||
@@ -40,6 +41,10 @@ func (c *CertificatesV1beta1Client) CertificateSigningRequests() CertificateSign
|
||||
return newCertificateSigningRequests(c)
|
||||
}
|
||||
|
||||
func (c *CertificatesV1beta1Client) ClusterTrustBundles() ClusterTrustBundleInterface {
|
||||
return newClusterTrustBundles(c)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new CertificatesV1beta1Client for the given config.
|
||||
// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient),
|
||||
// where httpClient was generated with rest.HTTPClientFor(c).
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
applyconfigurationscertificatesv1beta1 "k8s.io/client-go/applyconfigurations/certificates/v1beta1"
|
||||
gentype "k8s.io/client-go/gentype"
|
||||
scheme "k8s.io/client-go/kubernetes/scheme"
|
||||
)
|
||||
|
||||
// ClusterTrustBundlesGetter has a method to return a ClusterTrustBundleInterface.
|
||||
// A group's client should implement this interface.
|
||||
type ClusterTrustBundlesGetter interface {
|
||||
ClusterTrustBundles() ClusterTrustBundleInterface
|
||||
}
|
||||
|
||||
// ClusterTrustBundleInterface has methods to work with ClusterTrustBundle resources.
|
||||
type ClusterTrustBundleInterface interface {
|
||||
Create(ctx context.Context, clusterTrustBundle *certificatesv1beta1.ClusterTrustBundle, opts v1.CreateOptions) (*certificatesv1beta1.ClusterTrustBundle, error)
|
||||
Update(ctx context.Context, clusterTrustBundle *certificatesv1beta1.ClusterTrustBundle, opts v1.UpdateOptions) (*certificatesv1beta1.ClusterTrustBundle, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*certificatesv1beta1.ClusterTrustBundle, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*certificatesv1beta1.ClusterTrustBundleList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *certificatesv1beta1.ClusterTrustBundle, err error)
|
||||
Apply(ctx context.Context, clusterTrustBundle *applyconfigurationscertificatesv1beta1.ClusterTrustBundleApplyConfiguration, opts v1.ApplyOptions) (result *certificatesv1beta1.ClusterTrustBundle, err error)
|
||||
ClusterTrustBundleExpansion
|
||||
}
|
||||
|
||||
// clusterTrustBundles implements ClusterTrustBundleInterface
|
||||
type clusterTrustBundles struct {
|
||||
*gentype.ClientWithListAndApply[*certificatesv1beta1.ClusterTrustBundle, *certificatesv1beta1.ClusterTrustBundleList, *applyconfigurationscertificatesv1beta1.ClusterTrustBundleApplyConfiguration]
|
||||
}
|
||||
|
||||
// newClusterTrustBundles returns a ClusterTrustBundles
|
||||
func newClusterTrustBundles(c *CertificatesV1beta1Client) *clusterTrustBundles {
|
||||
return &clusterTrustBundles{
|
||||
gentype.NewClientWithListAndApply[*certificatesv1beta1.ClusterTrustBundle, *certificatesv1beta1.ClusterTrustBundleList, *applyconfigurationscertificatesv1beta1.ClusterTrustBundleApplyConfiguration](
|
||||
"clustertrustbundles",
|
||||
c.RESTClient(),
|
||||
scheme.ParameterCodec,
|
||||
"",
|
||||
func() *certificatesv1beta1.ClusterTrustBundle { return &certificatesv1beta1.ClusterTrustBundle{} },
|
||||
func() *certificatesv1beta1.ClusterTrustBundleList {
|
||||
return &certificatesv1beta1.ClusterTrustBundleList{}
|
||||
},
|
||||
gentype.PrefersProtobuf[*certificatesv1beta1.ClusterTrustBundle](),
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,10 @@ func (c *FakeCertificatesV1beta1) CertificateSigningRequests() v1beta1.Certifica
|
||||
return newFakeCertificateSigningRequests(c)
|
||||
}
|
||||
|
||||
func (c *FakeCertificatesV1beta1) ClusterTrustBundles() v1beta1.ClusterTrustBundleInterface {
|
||||
return newFakeClusterTrustBundles(c)
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeCertificatesV1beta1) RESTClient() rest.Interface {
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
certificatesv1beta1 "k8s.io/client-go/applyconfigurations/certificates/v1beta1"
|
||||
gentype "k8s.io/client-go/gentype"
|
||||
typedcertificatesv1beta1 "k8s.io/client-go/kubernetes/typed/certificates/v1beta1"
|
||||
)
|
||||
|
||||
// fakeClusterTrustBundles implements ClusterTrustBundleInterface
|
||||
type fakeClusterTrustBundles struct {
|
||||
*gentype.FakeClientWithListAndApply[*v1beta1.ClusterTrustBundle, *v1beta1.ClusterTrustBundleList, *certificatesv1beta1.ClusterTrustBundleApplyConfiguration]
|
||||
Fake *FakeCertificatesV1beta1
|
||||
}
|
||||
|
||||
func newFakeClusterTrustBundles(fake *FakeCertificatesV1beta1) typedcertificatesv1beta1.ClusterTrustBundleInterface {
|
||||
return &fakeClusterTrustBundles{
|
||||
gentype.NewFakeClientWithListAndApply[*v1beta1.ClusterTrustBundle, *v1beta1.ClusterTrustBundleList, *certificatesv1beta1.ClusterTrustBundleApplyConfiguration](
|
||||
fake.Fake,
|
||||
"",
|
||||
v1beta1.SchemeGroupVersion.WithResource("clustertrustbundles"),
|
||||
v1beta1.SchemeGroupVersion.WithKind("ClusterTrustBundle"),
|
||||
func() *v1beta1.ClusterTrustBundle { return &v1beta1.ClusterTrustBundle{} },
|
||||
func() *v1beta1.ClusterTrustBundleList { return &v1beta1.ClusterTrustBundleList{} },
|
||||
func(dst, src *v1beta1.ClusterTrustBundleList) { dst.ListMeta = src.ListMeta },
|
||||
func(list *v1beta1.ClusterTrustBundleList) []*v1beta1.ClusterTrustBundle {
|
||||
return gentype.ToPointerSlice(list.Items)
|
||||
},
|
||||
func(list *v1beta1.ClusterTrustBundleList, items []*v1beta1.ClusterTrustBundle) {
|
||||
list.Items = gentype.FromPointerSlice(items)
|
||||
},
|
||||
),
|
||||
fake,
|
||||
}
|
||||
}
|
||||
@@ -17,3 +17,5 @@ limitations under the License.
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
type ClusterTrustBundleExpansion interface{}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
listers "k8s.io/client-go/listers"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// ClusterTrustBundleLister helps list ClusterTrustBundles.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type ClusterTrustBundleLister interface {
|
||||
// List lists all ClusterTrustBundles in the indexer.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*certificatesv1beta1.ClusterTrustBundle, err error)
|
||||
// Get retrieves the ClusterTrustBundle from the index for a given name.
|
||||
// Objects returned here must be treated as read-only.
|
||||
Get(name string) (*certificatesv1beta1.ClusterTrustBundle, error)
|
||||
ClusterTrustBundleListerExpansion
|
||||
}
|
||||
|
||||
// clusterTrustBundleLister implements the ClusterTrustBundleLister interface.
|
||||
type clusterTrustBundleLister struct {
|
||||
listers.ResourceIndexer[*certificatesv1beta1.ClusterTrustBundle]
|
||||
}
|
||||
|
||||
// NewClusterTrustBundleLister returns a new ClusterTrustBundleLister.
|
||||
func NewClusterTrustBundleLister(indexer cache.Indexer) ClusterTrustBundleLister {
|
||||
return &clusterTrustBundleLister{listers.New[*certificatesv1beta1.ClusterTrustBundle](indexer, certificatesv1beta1.Resource("clustertrustbundle"))}
|
||||
}
|
||||
@@ -21,3 +21,7 @@ package v1beta1
|
||||
// CertificateSigningRequestListerExpansion allows custom methods to be added to
|
||||
// CertificateSigningRequestLister.
|
||||
type CertificateSigningRequestListerExpansion interface{}
|
||||
|
||||
// ClusterTrustBundleListerExpansion allows custom methods to be added to
|
||||
// ClusterTrustBundleLister.
|
||||
type ClusterTrustBundleListerExpansion interface{}
|
||||
|
||||
@@ -32,7 +32,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1"
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
@@ -266,7 +266,7 @@ var _ = SIGDescribe(framework.WithFeatureGate(features.ClusterTrustBundle), fram
|
||||
ginkgo.It("should be able to mount a big number (>100) of CTBs", func(ctx context.Context) {
|
||||
const numCTBs = 150
|
||||
|
||||
var initCTBs []*certificatesv1alpha1.ClusterTrustBundle
|
||||
var initCTBs []*certificatesv1beta1.ClusterTrustBundle
|
||||
var cleanups []func(ctx context.Context)
|
||||
var projections []v1.VolumeProjection
|
||||
|
||||
@@ -443,7 +443,7 @@ func podForCTBProjection(projectionSources ...v1.VolumeProjection) *v1.Pod {
|
||||
// "signer.alive=false": <set of all PEMs whose CTBs contain `signer.alive: false` labels>,
|
||||
// "no-signer": <set of all PEMs that appear in CTBs with no specific signers>,
|
||||
// }
|
||||
func initCTBData() ([]*certificatesv1alpha1.ClusterTrustBundle, map[string]sets.Set[string]) {
|
||||
func initCTBData() ([]*certificatesv1beta1.ClusterTrustBundle, map[string]sets.Set[string]) {
|
||||
var pemSets = map[string]sets.Set[string]{
|
||||
testSignerOneName: sets.New[string](),
|
||||
testSignerTwoName: sets.New[string](),
|
||||
@@ -452,7 +452,7 @@ func initCTBData() ([]*certificatesv1alpha1.ClusterTrustBundle, map[string]sets.
|
||||
noSignerKey: sets.New[string](),
|
||||
}
|
||||
|
||||
var ctbs []*certificatesv1alpha1.ClusterTrustBundle
|
||||
var ctbs []*certificatesv1beta1.ClusterTrustBundle
|
||||
|
||||
for i := range 10 {
|
||||
caPEM := mustMakeCAPEM(fmt.Sprintf("root%d", i))
|
||||
@@ -487,20 +487,20 @@ func initCTBData() ([]*certificatesv1alpha1.ClusterTrustBundle, map[string]sets.
|
||||
return ctbs, pemSets
|
||||
}
|
||||
|
||||
func ctbForCA(ctbName, signerName, caPEM string, labels map[string]string) *certificatesv1alpha1.ClusterTrustBundle {
|
||||
return &certificatesv1alpha1.ClusterTrustBundle{
|
||||
func ctbForCA(ctbName, signerName, caPEM string, labels map[string]string) *certificatesv1beta1.ClusterTrustBundle {
|
||||
return &certificatesv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: ctbName,
|
||||
Labels: labels,
|
||||
},
|
||||
Spec: certificatesv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certificatesv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: signerName,
|
||||
TrustBundle: caPEM,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func mustInitCTBs(ctx context.Context, f *framework.Framework, ctbs []*certificatesv1alpha1.ClusterTrustBundle) func(context.Context) {
|
||||
func mustInitCTBs(ctx context.Context, f *framework.Framework, ctbs []*certificatesv1beta1.ClusterTrustBundle) func(context.Context) {
|
||||
cleanups := []func(context.Context){}
|
||||
for _, ctb := range ctbs {
|
||||
ctb := ctb
|
||||
@@ -514,15 +514,15 @@ func mustInitCTBs(ctx context.Context, f *framework.Framework, ctbs []*certifica
|
||||
}
|
||||
}
|
||||
|
||||
func mustCreateCTB(ctx context.Context, f *framework.Framework, ctb *certificatesv1alpha1.ClusterTrustBundle) func(context.Context) {
|
||||
func mustCreateCTB(ctx context.Context, f *framework.Framework, ctb *certificatesv1beta1.ClusterTrustBundle) func(context.Context) {
|
||||
mutateCTBForTesting(ctb, f.UniqueName)
|
||||
|
||||
if _, err := f.ClientSet.CertificatesV1alpha1().ClusterTrustBundles().Create(ctx, ctb, metav1.CreateOptions{}); err != nil {
|
||||
if _, err := f.ClientSet.CertificatesV1beta1().ClusterTrustBundles().Create(ctx, ctb, metav1.CreateOptions{}); err != nil {
|
||||
framework.Failf("Error while creating ClusterTrustBundle: %v", err)
|
||||
}
|
||||
|
||||
return func(ctx context.Context) {
|
||||
if err := f.ClientSet.CertificatesV1alpha1().ClusterTrustBundles().Delete(ctx, ctb.Name, metav1.DeleteOptions{}); err != nil {
|
||||
if err := f.ClientSet.CertificatesV1beta1().ClusterTrustBundles().Delete(ctx, ctb.Name, metav1.DeleteOptions{}); err != nil {
|
||||
framework.Logf("failed to remove a cluster trust bundle: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -584,7 +584,7 @@ func getFileModeRegex(filePath string, mask *int32) string {
|
||||
return fmt.Sprintf("(%s|%s)", linuxOutput, windowsOutput)
|
||||
}
|
||||
|
||||
func ctbsToPEMs(ctbs []*certificatesv1alpha1.ClusterTrustBundle) []string {
|
||||
func ctbsToPEMs(ctbs []*certificatesv1beta1.ClusterTrustBundle) []string {
|
||||
var certPEMs []string
|
||||
for _, ctb := range ctbs {
|
||||
certPEMs = append(certPEMs, ctb.Spec.TrustBundle)
|
||||
@@ -594,7 +594,7 @@ func ctbsToPEMs(ctbs []*certificatesv1alpha1.ClusterTrustBundle) []string {
|
||||
|
||||
// mutateCTBForTesting mutates the .spec.signerName and .name so that the created cluster
|
||||
// objects are unique and the tests can run in parallel
|
||||
func mutateCTBForTesting(ctb *certificatesv1alpha1.ClusterTrustBundle, uniqueName string) {
|
||||
func mutateCTBForTesting(ctb *certificatesv1beta1.ClusterTrustBundle, uniqueName string) {
|
||||
signer := ctb.Spec.SignerName
|
||||
if len(signer) == 0 {
|
||||
ctb.Name += uniqueName
|
||||
|
||||
@@ -162,12 +162,20 @@
|
||||
lockToDefault: false
|
||||
preRelease: Alpha
|
||||
version: "1.27"
|
||||
- default: false
|
||||
lockToDefault: false
|
||||
preRelease: Beta
|
||||
version: "1.33"
|
||||
- name: ClusterTrustBundleProjection
|
||||
versionedSpecs:
|
||||
- default: false
|
||||
lockToDefault: false
|
||||
preRelease: Alpha
|
||||
version: "1.29"
|
||||
- default: false
|
||||
lockToDefault: false
|
||||
preRelease: Beta
|
||||
version: "1.33"
|
||||
- name: ComponentFlagz
|
||||
versionedSpecs:
|
||||
- default: false
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
certsv1alpha1 "k8s.io/api/certificates/v1alpha1"
|
||||
certsv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@@ -38,10 +38,6 @@ import (
|
||||
// Verifies that the ClusterTrustBundle attest admission plugin correctly
|
||||
// enforces that a user has "attest" on the affected signer name.
|
||||
func TestCTBAttestPlugin(t *testing.T) {
|
||||
// KUBE_APISERVER_SERVE_REMOVED_APIS_FOR_ONE_RELEASE allows for APIs pending removal to not block tests
|
||||
// TODO: Remove this line once certificates v1alpha1 types to be removed in 1.32 are fully removed
|
||||
t.Setenv("KUBE_APISERVER_SERVE_REMOVED_APIS_FOR_ONE_RELEASE", "true")
|
||||
|
||||
testCases := []struct {
|
||||
description string
|
||||
trustBundleName string
|
||||
@@ -78,7 +74,7 @@ func TestCTBAttestPlugin(t *testing.T) {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--authorization-mode=RBAC", "--feature-gates=ClusterTrustBundle=true", fmt.Sprintf("--runtime-config=%s=true", certsv1alpha1.SchemeGroupVersion)}, framework.SharedEtcd())
|
||||
server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--authorization-mode=RBAC", "--feature-gates=ClusterTrustBundle=true", fmt.Sprintf("--runtime-config=%s=true", certsv1beta1.SchemeGroupVersion)}, framework.SharedEtcd())
|
||||
defer server.TearDownFn()
|
||||
|
||||
client := kubernetes.NewForConfigOrDie(server.ClientConfig)
|
||||
@@ -92,11 +88,11 @@ func TestCTBAttestPlugin(t *testing.T) {
|
||||
testUserConfig.Impersonate = rest.ImpersonationConfig{UserName: "test-user"}
|
||||
testUserClient := kubernetes.NewForConfigOrDie(testUserConfig)
|
||||
|
||||
bundle := &certsv1alpha1.ClusterTrustBundle{
|
||||
bundle := &certsv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: tc.trustBundleName,
|
||||
},
|
||||
Spec: certsv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certsv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: tc.targetSignerName,
|
||||
TrustBundle: mustMakePEMBlock("CERTIFICATE", nil, mustMakeCertificate(t, &x509.Certificate{
|
||||
SerialNumber: big.NewInt(0),
|
||||
@@ -108,7 +104,7 @@ func TestCTBAttestPlugin(t *testing.T) {
|
||||
})),
|
||||
},
|
||||
}
|
||||
_, err := testUserClient.CertificatesV1alpha1().ClusterTrustBundles().Create(ctx, bundle, metav1.CreateOptions{})
|
||||
_, err := testUserClient.CertificatesV1beta1().ClusterTrustBundles().Create(ctx, bundle, metav1.CreateOptions{})
|
||||
if err != nil && err.Error() != tc.wantError {
|
||||
t.Fatalf("Bad error while creating ClusterTrustBundle; got %q want %q", err.Error(), tc.wantError)
|
||||
} else if err == nil && tc.wantError != "" {
|
||||
|
||||
@@ -30,7 +30,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/certificates/v1alpha1"
|
||||
"k8s.io/api/certificates/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@@ -47,9 +47,6 @@ import (
|
||||
)
|
||||
|
||||
func TestClusterTrustBundlesPublisherController(t *testing.T) {
|
||||
// KUBE_APISERVER_SERVE_REMOVED_APIS_FOR_ONE_RELEASE allows for APIs pending removal to not block tests
|
||||
// TODO: Remove this line once certificates v1alpha1 types to be removed in 1.32 are fully removed
|
||||
t.Setenv("KUBE_APISERVER_SERVE_REMOVED_APIS_FOR_ONE_RELEASE", "true")
|
||||
ctx := ktesting.Init(t)
|
||||
|
||||
certBytes := mustMakeCertificate(t, &x509.Certificate{
|
||||
@@ -73,7 +70,7 @@ func TestClusterTrustBundlesPublisherController(t *testing.T) {
|
||||
"--disable-admission-plugins", "ServiceAccount",
|
||||
"--authorization-mode=RBAC",
|
||||
"--feature-gates", "ClusterTrustBundle=true",
|
||||
fmt.Sprintf("--runtime-config=%s=true", v1alpha1.SchemeGroupVersion),
|
||||
fmt.Sprintf("--runtime-config=%s=true", v1beta1.SchemeGroupVersion),
|
||||
}
|
||||
storageConfig := framework.SharedEtcd()
|
||||
server := kubeapiservertesting.StartTestServerOrDie(t, nil, apiServerFlags, storageConfig)
|
||||
@@ -108,12 +105,12 @@ func TestClusterTrustBundlesPublisherController(t *testing.T) {
|
||||
unrelatedPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: unrelatedSigner})
|
||||
// set up a signer that's completely unrelated to the controller to check
|
||||
// it's not anyhow handled by it
|
||||
unrelatedCTB, err := clientSet.CertificatesV1alpha1().ClusterTrustBundles().Create(ctx,
|
||||
&v1alpha1.ClusterTrustBundle{
|
||||
unrelatedCTB, err := clientSet.CertificatesV1beta1().ClusterTrustBundles().Create(ctx,
|
||||
&v1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test.test:unrelated:0",
|
||||
},
|
||||
Spec: v1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: v1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: "test.test/unrelated",
|
||||
TrustBundle: string(unrelatedPEM),
|
||||
},
|
||||
@@ -127,11 +124,11 @@ func TestClusterTrustBundlesPublisherController(t *testing.T) {
|
||||
waitUntilSingleKASSignerCTB(ctx, t, clientSet, certPEM)
|
||||
|
||||
t.Log("check that the controller deletes any additional bundles for the same signer")
|
||||
if _, err := clientSet.CertificatesV1alpha1().ClusterTrustBundles().Create(ctx, &v1alpha1.ClusterTrustBundle{
|
||||
if _, err := clientSet.CertificatesV1beta1().ClusterTrustBundles().Create(ctx, &v1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "kubernetes.io:kube-apiserver-serving:testname",
|
||||
},
|
||||
Spec: v1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: v1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: "kubernetes.io/kube-apiserver-serving",
|
||||
TrustBundle: string(certPEM),
|
||||
},
|
||||
@@ -152,7 +149,7 @@ func TestClusterTrustBundlesPublisherController(t *testing.T) {
|
||||
})
|
||||
differentSignerPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: differentSigner})
|
||||
|
||||
ctbList, err := clientSet.CertificatesV1alpha1().ClusterTrustBundles().List(ctx, metav1.ListOptions{
|
||||
ctbList, err := clientSet.CertificatesV1beta1().ClusterTrustBundles().List(ctx, metav1.ListOptions{
|
||||
FieldSelector: "spec.signerName=kubernetes.io/kube-apiserver-serving",
|
||||
})
|
||||
if err != nil || len(ctbList.Items) != 1 {
|
||||
@@ -162,13 +159,13 @@ func TestClusterTrustBundlesPublisherController(t *testing.T) {
|
||||
ctbToUpdate := ctbList.Items[0].DeepCopy()
|
||||
ctbToUpdate.Spec.TrustBundle = string(differentSignerPEM)
|
||||
|
||||
if _, err = clientSet.CertificatesV1alpha1().ClusterTrustBundles().Update(ctx, ctbToUpdate, metav1.UpdateOptions{}); err != nil {
|
||||
if _, err = clientSet.CertificatesV1beta1().ClusterTrustBundles().Update(ctx, ctbToUpdate, metav1.UpdateOptions{}); err != nil {
|
||||
t.Fatalf("failed to update ctb with new PEM bundle: %v", err)
|
||||
}
|
||||
|
||||
waitUntilSingleKASSignerCTB(ctx, t, clientSet, certPEM)
|
||||
|
||||
unrelatedCTB, err = clientSet.CertificatesV1alpha1().ClusterTrustBundles().Get(ctx, unrelatedCTB.Name, metav1.GetOptions{})
|
||||
unrelatedCTB, err = clientSet.CertificatesV1beta1().ClusterTrustBundles().Get(ctx, unrelatedCTB.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get the unrelated CTB back: %v", err)
|
||||
}
|
||||
@@ -184,7 +181,7 @@ func TestClusterTrustBundlesPublisherController(t *testing.T) {
|
||||
|
||||
func waitUntilSingleKASSignerCTB(ctx context.Context, t *testing.T, clientSet *clientset.Clientset, caPEM []byte) {
|
||||
err := wait.PollUntilContextTimeout(ctx, 200*time.Millisecond, 30*time.Second, true, func(ctx context.Context) (done bool, err error) {
|
||||
ctbList, err := clientSet.CertificatesV1alpha1().ClusterTrustBundles().List(ctx, metav1.ListOptions{
|
||||
ctbList, err := clientSet.CertificatesV1beta1().ClusterTrustBundles().List(ctx, metav1.ListOptions{
|
||||
FieldSelector: "spec.signerName=kubernetes.io/kube-apiserver-serving",
|
||||
})
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
certsv1alpha1 "k8s.io/api/certificates/v1alpha1"
|
||||
certsv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
|
||||
@@ -38,16 +38,16 @@ func TestCTBSignerNameFieldSelector(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--feature-gates=ClusterTrustBundle=true", fmt.Sprintf("--runtime-config=%s=true", certsv1alpha1.SchemeGroupVersion)}, framework.SharedEtcd())
|
||||
server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--feature-gates=ClusterTrustBundle=true", fmt.Sprintf("--runtime-config=%s=true", certsv1beta1.SchemeGroupVersion)}, framework.SharedEtcd())
|
||||
defer server.TearDownFn()
|
||||
|
||||
client := kubernetes.NewForConfigOrDie(server.ClientConfig)
|
||||
|
||||
bundle1 := &certsv1alpha1.ClusterTrustBundle{
|
||||
bundle1 := &certsv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo.com:bar:v1",
|
||||
},
|
||||
Spec: certsv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certsv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: "foo.com/bar",
|
||||
TrustBundle: mustMakePEMBlock("CERTIFICATE", nil, mustMakeCertificate(t, &x509.Certificate{
|
||||
SerialNumber: big.NewInt(0),
|
||||
@@ -59,15 +59,15 @@ func TestCTBSignerNameFieldSelector(t *testing.T) {
|
||||
})),
|
||||
},
|
||||
}
|
||||
if _, err := client.CertificatesV1alpha1().ClusterTrustBundles().Create(ctx, bundle1, metav1.CreateOptions{}); err != nil {
|
||||
if _, err := client.CertificatesV1beta1().ClusterTrustBundles().Create(ctx, bundle1, metav1.CreateOptions{}); err != nil {
|
||||
t.Fatalf("Error while creating bundle1: %v", err)
|
||||
}
|
||||
|
||||
bundle2 := &certsv1alpha1.ClusterTrustBundle{
|
||||
bundle2 := &certsv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo.com:bar:v2",
|
||||
},
|
||||
Spec: certsv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certsv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: "foo.com/bar",
|
||||
TrustBundle: mustMakePEMBlock("CERTIFICATE", nil, mustMakeCertificate(t, &x509.Certificate{
|
||||
SerialNumber: big.NewInt(0),
|
||||
@@ -79,15 +79,15 @@ func TestCTBSignerNameFieldSelector(t *testing.T) {
|
||||
})),
|
||||
},
|
||||
}
|
||||
if _, err := client.CertificatesV1alpha1().ClusterTrustBundles().Create(ctx, bundle2, metav1.CreateOptions{}); err != nil {
|
||||
if _, err := client.CertificatesV1beta1().ClusterTrustBundles().Create(ctx, bundle2, metav1.CreateOptions{}); err != nil {
|
||||
t.Fatalf("Error while creating bundle2: %v", err)
|
||||
}
|
||||
|
||||
bundle3 := &certsv1alpha1.ClusterTrustBundle{
|
||||
bundle3 := &certsv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "baz.com:bar:v1",
|
||||
},
|
||||
Spec: certsv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certsv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: "baz.com/bar",
|
||||
TrustBundle: mustMakePEMBlock("CERTIFICATE", nil, mustMakeCertificate(t, &x509.Certificate{
|
||||
SerialNumber: big.NewInt(0),
|
||||
@@ -99,11 +99,11 @@ func TestCTBSignerNameFieldSelector(t *testing.T) {
|
||||
})),
|
||||
},
|
||||
}
|
||||
if _, err := client.CertificatesV1alpha1().ClusterTrustBundles().Create(ctx, bundle3, metav1.CreateOptions{}); err != nil {
|
||||
if _, err := client.CertificatesV1beta1().ClusterTrustBundles().Create(ctx, bundle3, metav1.CreateOptions{}); err != nil {
|
||||
t.Fatalf("Error while creating bundle3: %v", err)
|
||||
}
|
||||
|
||||
fooList, err := client.CertificatesV1alpha1().ClusterTrustBundles().List(ctx, metav1.ListOptions{FieldSelector: "spec.signerName=foo.com/bar"})
|
||||
fooList, err := client.CertificatesV1beta1().ClusterTrustBundles().List(ctx, metav1.ListOptions{FieldSelector: "spec.signerName=foo.com/bar"})
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to list ClusterTrustBundles with spec.signerName=foo.com/bar")
|
||||
}
|
||||
@@ -127,7 +127,7 @@ func TestCTBSignerNameFieldSelector(t *testing.T) {
|
||||
t.Errorf("Didn't find foo.com:bar:v2 in the list when listing for foo.com/bar")
|
||||
}
|
||||
|
||||
bazList, err := client.CertificatesV1alpha1().ClusterTrustBundles().List(ctx, metav1.ListOptions{FieldSelector: "spec.signerName=baz.com/bar"})
|
||||
bazList, err := client.CertificatesV1beta1().ClusterTrustBundles().List(ctx, metav1.ListOptions{FieldSelector: "spec.signerName=baz.com/bar"})
|
||||
if err != nil {
|
||||
t.Fatalf("Unable to list ClusterTrustBundles with spec.signerName=baz.com/bar")
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
certsv1alpha1 "k8s.io/api/certificates/v1alpha1"
|
||||
certsv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
|
||||
@@ -32,10 +32,6 @@ import (
|
||||
)
|
||||
|
||||
func TestCTBSignerNameChangeForbidden(t *testing.T) {
|
||||
// KUBE_APISERVER_SERVE_REMOVED_APIS_FOR_ONE_RELEASE allows for APIs pending removal to not block tests
|
||||
// TODO: Remove this line once certificates v1alpha1 types to be removed in 1.32 are fully removed
|
||||
t.Setenv("KUBE_APISERVER_SERVE_REMOVED_APIS_FOR_ONE_RELEASE", "true")
|
||||
|
||||
testCases := []struct {
|
||||
objectName string
|
||||
signer1 string
|
||||
@@ -63,16 +59,16 @@ func TestCTBSignerNameChangeForbidden(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--feature-gates=ClusterTrustBundle=true", fmt.Sprintf("--runtime-config=%s=true", certsv1alpha1.SchemeGroupVersion)}, framework.SharedEtcd())
|
||||
server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{"--feature-gates=ClusterTrustBundle=true", fmt.Sprintf("--runtime-config=%s=true", certsv1beta1.SchemeGroupVersion)}, framework.SharedEtcd())
|
||||
defer server.TearDownFn()
|
||||
|
||||
client := kubernetes.NewForConfigOrDie(server.ClientConfig)
|
||||
|
||||
bundle1 := &certsv1alpha1.ClusterTrustBundle{
|
||||
bundle1 := &certsv1beta1.ClusterTrustBundle{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: tc.objectName,
|
||||
},
|
||||
Spec: certsv1alpha1.ClusterTrustBundleSpec{
|
||||
Spec: certsv1beta1.ClusterTrustBundleSpec{
|
||||
SignerName: tc.signer1,
|
||||
TrustBundle: mustMakePEMBlock("CERTIFICATE", nil, mustMakeCertificate(t, &x509.Certificate{
|
||||
SerialNumber: big.NewInt(0),
|
||||
@@ -84,7 +80,7 @@ func TestCTBSignerNameChangeForbidden(t *testing.T) {
|
||||
})),
|
||||
},
|
||||
}
|
||||
bundle1, err := client.CertificatesV1alpha1().ClusterTrustBundles().Create(ctx, bundle1, metav1.CreateOptions{})
|
||||
bundle1, err := client.CertificatesV1beta1().ClusterTrustBundles().Create(ctx, bundle1, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("Error while creating bundle1: %v", err)
|
||||
}
|
||||
@@ -95,7 +91,7 @@ func TestCTBSignerNameChangeForbidden(t *testing.T) {
|
||||
// cluster trust bundle.
|
||||
bundle1.Spec.SignerName = tc.signer2
|
||||
|
||||
_, err = client.CertificatesV1alpha1().ClusterTrustBundles().Update(ctx, bundle1, metav1.UpdateOptions{})
|
||||
_, err = client.CertificatesV1beta1().ClusterTrustBundles().Update(ctx, bundle1, metav1.UpdateOptions{})
|
||||
if err == nil {
|
||||
t.Fatalf("Got nil error from updating bundle foo-com--bar from signerName=foo.com/bar to signerName=foo.com/bar2, but wanted an error")
|
||||
}
|
||||
|
||||
@@ -216,13 +216,23 @@ func GetEtcdStorageDataForNamespaceServedAt(namespace string, v string, removeAl
|
||||
|
||||
// k8s.io/kubernetes/pkg/apis/certificates/v1alpha1
|
||||
gvr("certificates.k8s.io", "v1alpha1", "clustertrustbundles"): {
|
||||
Stub: `{"metadata": {"name": "example.com:signer:abc"}, "spec": {"signerName":"example.com/signer", "trustBundle": "-----BEGIN CERTIFICATE-----\nMIIBBDCBt6ADAgECAgEAMAUGAytlcDAQMQ4wDAYDVQQDEwVyb290MTAiGA8wMDAx\nMDEwMTAwMDAwMFoYDzAwMDEwMTAxMDAwMDAwWjAQMQ4wDAYDVQQDEwVyb290MTAq\nMAUGAytlcAMhAF2MoFeGa97gK2NGT1h6p1/a1GlMXAXbcjI/OShyIobPozIwMDAP\nBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTWDdK2CNQiHqRjPaAWYPPtIykQgjAF\nBgMrZXADQQCtom9WGl7m2SAa4tXM9Soo/mbInBsRhn187BMoqTAHInHchKup5/3y\nl1tYJSZZsEXnXrCvw2qLCBNif6+2YYgE\n-----END CERTIFICATE-----\n"}}`,
|
||||
ExpectedEtcdPath: "/registry/clustertrustbundles/example.com:signer:abc",
|
||||
Stub: `{"metadata": {"name": "example.com:signer:abcd"}, "spec": {"signerName":"example.com/signer", "trustBundle": "-----BEGIN CERTIFICATE-----\nMIIBBDCBt6ADAgECAgEAMAUGAytlcDAQMQ4wDAYDVQQDEwVyb290MTAiGA8wMDAx\nMDEwMTAwMDAwMFoYDzAwMDEwMTAxMDAwMDAwWjAQMQ4wDAYDVQQDEwVyb290MTAq\nMAUGAytlcAMhAF2MoFeGa97gK2NGT1h6p1/a1GlMXAXbcjI/OShyIobPozIwMDAP\nBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTWDdK2CNQiHqRjPaAWYPPtIykQgjAF\nBgMrZXADQQCtom9WGl7m2SAa4tXM9Soo/mbInBsRhn187BMoqTAHInHchKup5/3y\nl1tYJSZZsEXnXrCvw2qLCBNif6+2YYgE\n-----END CERTIFICATE-----\n"}}`,
|
||||
ExpectedEtcdPath: "/registry/clustertrustbundles/example.com:signer:abcd",
|
||||
ExpectedGVK: gvkP("certificates.k8s.io", "v1beta1", "ClusterTrustBundle"),
|
||||
IntroducedVersion: "1.26",
|
||||
RemovedVersion: "1.37",
|
||||
},
|
||||
// --
|
||||
|
||||
// k8s.io/kubernetes/pkg/apis/certificates/v1beta1
|
||||
gvr("certificates.k8s.io", "v1beta1", "clustertrustbundles"): {
|
||||
Stub: `{"metadata": {"name": "example.com:signer:abc"}, "spec": {"signerName":"example.com/signer", "trustBundle": "-----BEGIN CERTIFICATE-----\nMIIBBDCBt6ADAgECAgEAMAUGAytlcDAQMQ4wDAYDVQQDEwVyb290MTAiGA8wMDAx\nMDEwMTAwMDAwMFoYDzAwMDEwMTAxMDAwMDAwWjAQMQ4wDAYDVQQDEwVyb290MTAq\nMAUGAytlcAMhAF2MoFeGa97gK2NGT1h6p1/a1GlMXAXbcjI/OShyIobPozIwMDAP\nBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTWDdK2CNQiHqRjPaAWYPPtIykQgjAF\nBgMrZXADQQCtom9WGl7m2SAa4tXM9Soo/mbInBsRhn187BMoqTAHInHchKup5/3y\nl1tYJSZZsEXnXrCvw2qLCBNif6+2YYgE\n-----END CERTIFICATE-----\n"}}`,
|
||||
ExpectedEtcdPath: "/registry/clustertrustbundles/example.com:signer:abc",
|
||||
IntroducedVersion: "1.33",
|
||||
RemovedVersion: "1.39",
|
||||
},
|
||||
// --
|
||||
|
||||
// k8s.io/kubernetes/pkg/apis/coordination/v1
|
||||
gvr("coordination.k8s.io", "v1", "leases"): {
|
||||
Stub: `{"metadata": {"name": "leasev1"}, "spec": {"holderIdentity": "holder", "leaseDurationSeconds": 5}}`,
|
||||
|
||||
Reference in New Issue
Block a user