Git Product home page Git Product logo

gardener-extension-shoot-cert-service's Introduction

REUSE status CI Build status Go Report Card

Project Gardener implements the automated management and operation of Kubernetes clusters as a service. Its main principle is to leverage Kubernetes concepts for all of its tasks.

Recently, most of the vendor specific logic has been developed in-tree. However, the project has grown to a size where it is very hard to extend, maintain, and test. With GEP-1 we have proposed how the architecture can be changed in a way to support external controllers that contain their very own vendor specifics. This way, we can keep Gardener core clean and independent.

Configuration

Example configuration for this extension controller:

apiVersion: shoot-cert-service.extensions.config.gardener.cloud/v1alpha1
kind: Configuration
issuerName: gardener
restrictIssuer: true # restrict issuer to any sub-domain of shoot.spec.dns.domain (default)
acme:
  email: [email protected]
  server: https://acme-v02.api.letsencrypt.org/directory
# privateKey: | # Optional key for Let's Encrypt account.
#   -----BEGIN BEGIN RSA PRIVATE KEY-----
#   ...
#   -----END RSA PRIVATE KEY-----

Extension-Resources

Example extension resource:

apiVersion: extensions.gardener.cloud/v1alpha1
kind: Extension
metadata:
  name: "extension-certificate-service"
  namespace: shoot--project--abc
spec:
  type: shoot-cert-service

When an extension resource is reconciled, the extension controller will create an instance of Cert-Management as well as an Issuer with the ACME information provided in the configuration above. These resources are placed inside the shoot namespace on the seed. Also, the controller takes care about generating necessary RBAC resources for the seed as well as for the shoot.

Please note, this extension controller relies on the Gardener-Resource-Manager to deploy k8s resources to seed and shoot clusters, i.e. it never deploys them directly.

How to start using or developing this extension controller locally

You can run the controller locally on your machine by executing make start. Please make sure to have the kubeconfig to the cluster you want to connect to ready in the ./dev/kubeconfig file. Static code checks and tests can be executed by running make verify. We are using Go modules for Golang package dependency management and Ginkgo/Gomega for testing.

Feedback and Support

Feedback and contributions are always welcome. Please report bugs or suggestions as GitHub issues or join our Slack channel #gardener (please invite yourself to the Kubernetes workspace here).

Learn more!

Please find further resources about out project here:

gardener-extension-shoot-cert-service's People

Contributors

acumino avatar andreasburger avatar danielfoehrkn avatar dependabot[bot] avatar dimitar-kostadinov avatar dimityrmirchev avatar etiennnr avatar g-pavlov avatar gardener-robot-ci-1 avatar gardener-robot-ci-2 avatar gardener-robot-ci-3 avatar ialidzhikov avatar istvanballok avatar kostov6 avatar krgostev avatar mandelsoft avatar martinweindel avatar maximilianbraun avatar n-boshnakov avatar raphaelvogel avatar rfranzke avatar scheererj avatar shafeeqes avatar stoyanr avatar timebertt avatar timuthy avatar vlerenc avatar vlvasilev avatar voelzmo avatar vpnachev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gardener-extension-shoot-cert-service's Issues

Adjust network policy and precheck nameservers for ACME on private networks

How to categorize this issue?

/area control-plane
/kind enhancement
/priority 3

What would you like to be added:
To support a private ACME provider on a private network, the network policy needs to allow access to private networks with the label networking.gardener.cloud/to-private-networks: allowed.
Additionally for the precheck of the DNS challenge by the cert-controller-manager, the precheckNameservers should optionally be overwritten in the provider config of the extension.

Why is this needed:
Support for private ACME provider.

CertConfig is missing `autoRegistration` for issuers

How to categorize this issue?

/area control-plane
/kind bug

What happened:
On creating an issuer with exteranl account binding, it was not possible to specify the autoRegistration field.

- type: shoot-cert-service
  providerConfig:
    apiVersion: service.cert.extensions.gardener.cloud/v1alpha1
    kind: CertConfig
    shootIssuers:
      enabled: true
    issuers:
      - email: ***********@***.com
        autoRegistration: true
        externalAccountBinding:
          keyID: *********************
          keySecretName: some-credentials
        name: cdf-dev-sap
        server: https://***.com/***/v1/acme/v2/directory

What you expected to happen:
Should allow to provide autoRegistration: true

How to reproduce it (as minimally and precisely as possible):

Anything else we need to know?:

Environment:

  • Gardener version (if relevant):
  • Extension version:
  • Kubernetes version (use kubectl version):
  • Cloud provider or hardware configuration:
  • Others:

Allow DNS challenges to be created in shoot clusters

What would you like to be added:
Provide an option which makes cert-management controllers create DNS records in the source (shoot) cluster instead of the target (seed) cluster.

Why is this needed:
At the moment the gardener-extension-shoot-cert-service sets up cert-management deployments in a way that DNS TXT records (DNS01 challenges) are created in the source cluster (seed cluster). This assumes that the seed cluster has a proper DNS management and also DNS providers available which are responsible for the Domains certificates are requested for.
This assumption is not true if the DNS providers are only available in the shoot cluster.

/cc @mandelsoft

Expose validating webhook for shoots in the garden cluster

What would you like to be added:
The shoot-cert-service extension should ship a validating webhook binary that can be deployed to the garden cluster and that checks whether the provided CertConfig in the .spec.extensions[].providerConfig is valid.

Why is this needed:
https://gardener.cloud/050-tutorials/content/howto/x509_certificates/#issuer states that the issuer name in the CertConfig may not be garden. This should be properly validated to prevent misconfiguration.

cert-controller-manager is in CrashLoopBackOff for Kubernetes v1.11

What happened:
cert-controller-manager is in CrashLoopBackOff for Kubernetes v1.11.

What you expected to happen:

How to reproduce it (as minimally and precisely as possible):

  1. Create Shoot with shoot-cert-service enabled and Kubernetes v1.11.

  2. Ensure that the cert-controller-manager fails with

time="2020-05-08T12:50:56Z" level=info msg="ingress-cert: responsible for classes: gardencert (['gardencert'])"
time="2020-05-08T12:50:56Z" level=info msg="ingress-cert: responsible for classes: ['gardencert'] (gardencert)"
time="2020-05-08T12:50:56Z" level=info msg="ingress-cert: target class           : "
panic: resources type Certificate.cert.gardener.cloud not found: Certificate.cert.gardener.cloud not known

goroutine 1 [running]:
github.com/gardener/controller-manager-library/pkg/controllermanager/controller/reconcile/reconcilers.ClusterResources.func1(0x18f0d80, 0xc000336100, 0x60a5b2, 0xc0002f1ce0, 0xc0003d1360)
	/tmp/build/80754af9/git-gardener_cert-management-master_master/tmp/src/github.com/gardener/cert-management/vendor/github.com/gardener/controller-manager-library/pkg/controllermanager/controller/reconcile/reconcilers/utils.go:33 +0x3db
github.com/gardener/controller-manager-library/pkg/controllermanager/controller/reconcile/reconcilers.newResources(0x18f0d80, 0xc000336100, 0xc0002bf9b0, 0x12f42b1)
	/tmp/build/80754af9/git-gardener_cert-management-master_master/tmp/src/github.com/gardener/cert-management/vendor/github.com/gardener/controller-manager-library/pkg/controllermanager/controller/reconcile/reconcilers/slavecache.go:68 +0x66
github.com/gardener/controller-manager-library/pkg/controllermanager/controller/reconcile/reconcilers.NewSlaveAccessBySpec(0x18f0d80, 0xc000336100, 0x16901ca, 0xc, 0xc0002bf9b0, 0xc000292450, 0x0)
	/tmp/build/80754af9/git-gardener_cert-management-master_master/tmp/src/github.com/gardener/cert-management/vendor/github.com/gardener/controller-manager-library/pkg/controllermanager/controller/reconcile/reconcilers/slavecache.go:105 +0x43
github.com/gardener/controller-manager-library/pkg/controllermanager/controller/reconcile/reconcilers.NewSlaveAccess(...)
	/tmp/build/80754af9/git-gardener_cert-management-master_master/tmp/src/github.com/gardener/cert-management/vendor/github.com/gardener/controller-manager-library/pkg/controllermanager/controller/reconcile/reconcilers/slavecache.go:98
github.com/gardener/cert-management/pkg/cert/source.SrcReconciler.func1(0x18f0d80, 0xc000336100, 0x16, 0xc0006feef0, 0x1, 0x1)
	/tmp/build/80754af9/git-gardener_cert-management-master_master/tmp/src/github.com/gardener/cert-management/pkg/cert/source/reconciler.go:58 +0x4dd
github.com/gardener/controller-manager-library/pkg/controllermanager/controller.NewController(0x18bf2e0, 0xc000154120, 0x18dd900, 0xc0003602d0, 0x18bf3a0, 0xc00013a520, 0x0, 0xa, 0xa)
	/tmp/build/80754af9/git-gardener_cert-management-master_master/tmp/src/github.com/gardener/cert-management/vendor/github.com/gardener/controller-manager-library/pkg/controllermanager/controller/controller.go:176 +0x1038
github.com/gardener/controller-manager-library/pkg/controllermanager.(*ControllerManager).Run(0xc000154120, 0xc0002f2600, 0xc000340a40)
	/tmp/build/80754af9/git-gardener_cert-management-master_master/tmp/src/github.com/gardener/cert-management/vendor/github.com/gardener/controller-manager-library/pkg/controllermanager/controllermanager.go:227 +0x29b
github.com/gardener/controller-manager-library/pkg/controllermanager.run(0x18b1a60, 0xc0002f2600, 0xc000340a40, 0x0, 0x0)
	/tmp/build/80754af9/git-gardener_cert-management-master_master/tmp/src/github.com/gardener/cert-management/vendor/github.com/gardener/controller-manager-library/pkg/controllermanager/main.go:157 +0x1c1
github.com/gardener/controller-manager-library/pkg/controllermanager.NewCommand.func1(0xc0002e9680, 0xc000344c30, 0x0, 0xd, 0x0, 0x0)
	/tmp/build/80754af9/git-gardener_cert-management-master_master/tmp/src/github.com/gardener/cert-management/vendor/github.com/gardener/controller-manager-library/pkg/controllermanager/main.go:112 +0x43
github.com/spf13/cobra.(*Command).execute(0xc0002e9680, 0xc00003a0f0, 0xd, 0xd, 0xc0002e9680, 0xc00003a0f0)
	/tmp/build/80754af9/git-gardener_cert-management-master_master/tmp/src/github.com/gardener/cert-management/vendor/github.com/spf13/cobra/command.go:826 +0x460
github.com/spf13/cobra.(*Command).ExecuteC(0xc0002e9680, 0xc000339080, 0x169c399, 0x17)
	/tmp/build/80754af9/git-gardener_cert-management-master_master/tmp/src/github.com/gardener/cert-management/vendor/github.com/spf13/cobra/command.go:914 +0x2fb
github.com/spf13/cobra.(*Command).Execute(...)
	/tmp/build/80754af9/git-gardener_cert-management-master_master/tmp/src/github.com/gardener/cert-management/vendor/github.com/spf13/cobra/command.go:864
github.com/gardener/controller-manager-library/pkg/controllermanager.Configuration.Start(0x169c399, 0x17, 0x168be2f, 0x7, 0x189f5a0, 0xc00000e608, 0x18c3b40, 0xc0002bf320, 0x169c399, 0x17, ...)
	/tmp/build/80754af9/git-gardener_cert-management-master_master/tmp/src/github.com/gardener/cert-management/vendor/github.com/gardener/controller-manager-library/pkg/controllermanager/main.go:95 +0x376
github.com/gardener/controller-manager-library/pkg/controllermanager.Start(0x169c399, 0x17, 0x16a4725, 0x1e, 0x168be2f, 0x7)
	/tmp/build/80754af9/git-gardener_cert-management-master_master/tmp/src/github.com/gardener/cert-management/vendor/github.com/gardener/controller-manager-library/pkg/controllermanager/main.go:40 +0x18f
main.main()
	/tmp/build/80754af9/git-gardener_cert-management-master_master/tmp/src/github.com/gardener/cert-management/cmd/cert-controller-manager/main.go:66 +0xa7
$
  1. Ensure that the root cause is that the gardener-resource-manager cannot apply the certificates.cert.gardener.cloud CRD
{"level":"error","ts":"2020-05-08T12:50:48.058Z","logger":"controller-runtime.controller","msg":"Reconciler error","controller":"resource-controller","request":"shoot--it--test2/extension-shoot-cert-service-shoot","error":"Errors occurred during applying: [error during apply of object \"apiextensions.k8s.io/v1beta1/CustomResourceDefinition/default/certificates.cert.gardener.cloud\": CustomResourceDefinition.apiextensions.k8s.io \"certificates.cert.gardener.cloud\" is invalid: spec.validation.openAPIV3Schema: Invalid value: apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"Certificate is the certificate CR.\", Type:\"object\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string{\"spec\"}, Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps{\"apiVersion\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), 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\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"kind\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), 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\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"metadata\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"\", Type:\"object\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"spec\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"CertificateSpec is the spec of the certificate to request.\", Type:\"object\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps{\"issuerRef\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"IssuerRef is the reference of the issuer to use.\", Type:\"object\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string{\"name\"}, Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps{\"name\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"Name is the name of the issuer CR in the same namespace.\", Type:\"string\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}}, AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"secretName\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"SecretName is the name of the secret object to use for storing the certificate.\", Type:\"string\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"secretRef\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"SecretRef is the reference of the secret object to use for storing the certificate.\", Type:\"object\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps{\"name\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"Name is unique within a namespace to reference a secret resource.\", Type:\"string\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"namespace\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"Namespace defines the space within which the secret name must be unique.\", Type:\"string\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}}, AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"commonName\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"CommonName is the CN for the certificate (max. 64 chars).\", Type:\"string\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"csr\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"CSR is the alternative way to provide CN,DNSNames and other information.\", Type:\"string\", Format:\"byte\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"dnsNames\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"DNSNames are the optional additional domain names of the certificate.\", Type:\"array\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(0xc432235f80), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}}, AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"status\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"CertificateStatus is the status of the certificate request.\", Type:\"object\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string{\"lastPendingTimestamp\", \"state\"}, Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps{\"state\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"State is the certificate state.\", Type:\"string\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"commonName\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"CommonName is the current CN.\", Type:\"string\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"dnsNames\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"DNSNames are the current domain names.\", Type:\"array\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(0xc432235fa0), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"expirationDate\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"ExpirationDate shows the notAfter validity date.\", Type:\"string\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"issuerRef\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"IssuerRef is the used issuer.\", Type:\"object\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string{\"name\", \"namespace\"}, Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps{\"name\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"Name is the name of the issuer CR.\", Type:\"string\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"namespace\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"Namespace is the namespace of the issuer CR.\", Type:\"string\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}}, AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"lastPendingTimestamp\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"LastPendingTimestamp contains the start timestamp of the last pending status.\", Type:\"string\", Format:\"date-time\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"message\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"Message is the status or error message.\", Type:\"string\", Format:\"\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}, \"observedGeneration\":apiextensions.JSONSchemaProps{ID:\"\", Schema:\"\", Ref:(*string)(nil), Description:\"ObservedGeneration is the observed generation of the spec.\", Type:\"integer\", Format:\"int64\", Title:\"\", Default:(*apiextensions.JSON)(nil), Maximum:(*float64)(nil), ExclusiveMaximum:false, Minimum:(*float64)(nil), ExclusiveMinimum:false, MaxLength:(*int64)(nil), MinLength:(*int64)(nil), Pattern:\"\", MaxItems:(*int64)(nil), MinItems:(*int64)(nil), UniqueItems:false, MultipleOf:(*float64)(nil), Enum:[]apiextensions.JSON(nil), MaxProperties:(*int64)(nil), MinProperties:(*int64)(nil), Required:[]string(nil), Items:(*apiextensions.JSONSchemaPropsOrArray)(nil), AllOf:[]apiextensions.JSONSchemaProps(nil), OneOf:[]apiextensions.JSONSchemaProps(nil), AnyOf:[]apiextensions.JSONSchemaProps(nil), Not:(*apiextensions.JSONSchemaProps)(nil), Properties:map[string]apiextensions.JSONSchemaProps(nil), AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}}, AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}}, AdditionalProperties:(*apiextensions.JSONSchemaPropsOrBool)(nil), PatternProperties:map[string]apiextensions.JSONSchemaProps(nil), Dependencies:apiextensions.JSONSchemaDependencies(nil), AdditionalItems:(*apiextensions.JSONSchemaPropsOrBool)(nil), Definitions:apiextensions.JSONSchemaDefinitions(nil), ExternalDocs:(*apiextensions.ExternalDocumentation)(nil), Example:(*apiextensions.JSON)(nil)}: must only have \"properties\", \"required\" or \"description\" at the root if the status subresource is enabled]","stacktrace":"github.com/go-logr/zapr.(*zapLogger).Error\n\t/go/src/github.com/gardener/gardener-resource-manager/vendor/github.com/go-logr/zapr/zapr.go:128\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler\n\t/go/src/github.com/gardener/gardener-resource-manager/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:258\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem\n\t/go/src/github.com/gardener/gardener-resource-manager/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:232\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).worker\n\t/go/src/github.com/gardener/gardener-resource-manager/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:211\nk8s.io/apimachinery/pkg/util/wait.JitterUntil.func1\n\t/go/src/github.com/gardener/gardener-resource-manager/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:152\nk8s.io/apimachinery/pkg/util/wait.JitterUntil\n\t/go/src/github.com/gardener/gardener-resource-manager/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:153\nk8s.io/apimachinery/pkg/util/wait.Until\n\t/go/src/github.com/gardener/gardener-resource-manager/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:88"}

Anything else we need to know?:

Environment:

  • Gardener version (if relevant):
  • Extension version:
  • Kubernetes version (use kubectl version):
  • Cloud provider or hardware configuration:
  • Others:

cannot apply cert for customer domain

What happened:
The secret cannot be generated on a LB svc, which is use for ingress-contrller with a custom DNS.
got event Normal cert-annotation 39s cert-controller-manager ingresscontroller-service-tls-secret: no certcontrollers running?

What you expected to happen:
can generate a secret with the tls cert

How to reproduce it (as minimally and precisely as possible):
use annotation "cert.gardener.cloud/secretname" to apply a TLS cert for ingress-controller svc, which is using a custom DNS;

Anything else we need to know?:
level=warning msg="updating status failed with: Certificate.cert.gardener.cloud \"ingressnginx-nginx-ingress-controller-service-4zshd\" is invalid: status.lastPendingTimestamp: Invalid value: \"null\": status.lastPendingTimestamp in body must be of type string: \"null\""

The offending line in the crd is probably

            required:
            - lastPendingTimestamp

Environment:

  • Gardener version (if relevant):
  • Extension version:
  • Kubernetes version (use kubectl version):
  • Cloud provider or hardware configuration:
  • Others:

Stop using github.com/pkg/errors

How to categorize this issue?

/kind enhancement
/priority 3

What would you like to be added:
Similar to gardener/gardener#4280 we should be using Go native error wrapping (available since GO 1.13).

$ grep -r '"github.com/pkg/errors"' | grep -v vendor/ | cut -f 1 -d ':' | cut -d '/' -f 1-3 | sort | uniq -c | sort
      1 pkg/controller/actuator.go

Why is this needed:
Getting rid of vendors in favor of using stdlib is always nice. Others seem to do this as well - kubernetes/kubernetes#103043 and containerd/console#54.

Allow to specify custom trusted root certificate

How to categorize this issue?

/area control-plane
/kind enhancement
/priority normal

What would you like to be added:
It should be possible to specify a custom trusted root certificate for a private ACME authority.
Similar as described in cert-manager/cert-manager#2332 (comment), the ConfigMap needs to be added to the deployment of the cert-controller-manager.

Why is this needed:
Support of a private ACME authority with a custom root certificate

Allow to specify ACME "preferred-chain" parameter

How to categorize this issue?

/area certification
/kind enhancement

What would you like to be added:
The Gardener cert-management has no support for "preferred-chain" currently, this shall be added. Discussion here

Why is this needed:
In our previous certificate pipeline, we used acme.sh to issue the certificates. There, we use the parameter --preferred-chain "ISRG Root X1" to request certificates signed by the new LE root.

Short name for Issuer CRD is invalid

How to categorize this issue?

/kind bug

What happened:
The issuer CRD definition wrongly uses the singular name as short name

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: issuers.cert.gardener.cloud
labels:
shoot.gardener.cloud/no-cleanup: "true"
app.kubernetes.io/name: gardener-extension-shoot-cert-service
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
group: cert.gardener.cloud
names:
kind: Issuer
listKind: IssuerList
plural: issuers
shortNames:
- issuer

K8s CRD controller has a validation that the short names is not re-used in other CRDs among the same group, see https://github.com/kubernetes/kubernetes/blob/e8d45596dfbdf69fd42aa6881dfdeb089a20ab33/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/status/naming_controller.go#L123-L169 and https://github.com/kubernetes/kubernetes/blob/e8d45596dfbdf69fd42aa6881dfdeb089a20ab33/staging/src/k8s.io/apiextensions-apiserver/pkg/controller/status/naming_controller.go#L89-L121

What you expected to happen:
The short names for issuer to not be the same as the singular name.

How to reproduce it (as minimally and precisely as possible):

  1. Create a k8s cluster, e.g. kind
  2. Run the following command to create the CRD without the shortNames
cat <<EOF | kubectl create -f -
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: issuers.cert.gardener.cloud
spec:
  conversion:
    strategy: None
  group: cert.gardener.cloud
  names:
    kind: Issuer
    listKind: IssuerList
    plural: issuers
    singular: issuer
  scope: Namespaced
  versions:
  - name: v1alpha1
    schema:
      openAPIV3Schema:
        type: object
        x-kubernetes-preserve-unknown-fields: true
    served: true
    storage: true
    subresources:
      status: {}
EOF
  1. Check the CRD conditions are healthy
kubectl get crd issuers.cert.gardener.cloud -o json | jq .status.conditions
[
  {
    "lastTransitionTime": "2023-10-31T11:02:59Z",
    "message": "no conflicts found",
    "reason": "NoConflicts",
    "status": "True",
    "type": "NamesAccepted"
  },
  {
    "lastTransitionTime": "2023-10-31T11:02:59Z",
    "message": "the initial names have been accepted",
    "reason": "InitialNamesAccepted",
    "status": "True",
    "type": "Established"
  }
]
  1. Update the CRD with short names
cat <<EOF | kubectl replace -f -
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: issuers.cert.gardener.cloud
spec:
  conversion:
    strategy: None
  group: cert.gardener.cloud
  names:
    kind: Issuer
    listKind: IssuerList
    plural: issuers
    singular: issuer
    shortNames:
    - issuer
  scope: Namespaced
  versions:
  - name: v1alpha1
    schema:
      openAPIV3Schema:
        type: object
        x-kubernetes-preserve-unknown-fields: true
    served: true
    storage: true
    subresources:
      status: {}
EOF
  1. Ensure the CRD status has a failing condition NamesAccepted
kubectl get crd issuers.cert.gardener.cloud -o json | jq .status.conditions
[
  {
    "lastTransitionTime": "2023-10-31T11:01:50Z",
    "message": "\"issuer\" is already in use",
    "reason": "ShortNamesConflict",
    "status": "False",
    "type": "NamesAccepted"
  },
  {
    "lastTransitionTime": "2023-10-31T11:01:03Z",
    "message": "the initial names have been accepted",
    "reason": "InitialNamesAccepted",
    "status": "True",
    "type": "Established"
  }
]

Anything else we need to know?:

Environment:

  • Gardener version (if relevant):
  • Extension version:
  • Kubernetes version (use kubectl version):
  • Cloud provider or hardware configuration:
  • Others:

cert-controller-manager liveness probe fails on startup

How to categorize this issue?

/area ops-productivity
/kind bug
/priority 3

What happened:
We noticed that for a cluster the cert-controller-manager Pod is in CrashLoopBackOff.

$ k -n shoot--foo--bar get po cert-controller-manager-6564bd874-pqspq
NAME                                      READY   STATUS             RESTARTS   AGE
cert-controller-manager-6564bd874-pqspq   0/1     CrashLoopBackOff   15         44m

The reason is that the liveness probe is failing

Events:
  Type     Reason     Age                    From               Message
  ----     ------     ----                   ----               -------

  Normal   Killing    41m (x3 over 43m)      kubelet            Container shoot-cert-management-seed failed liveness probe, will be restarted
  Normal   Created    40m (x4 over 44m)      kubelet            Created container shoot-cert-management-seed
  Normal   Started    40m (x4 over 44m)      kubelet            Started container shoot-cert-management-seed
  Warning  Unhealthy  18m (x31 over 43m)     kubelet            Liveness probe failed: Get "http://10.243.133.208:10258/healthz": dial tcp 10.243.133.208:10258: connect: connection refused
  Warning  BackOff    8m56s (x100 over 37m)  kubelet            Back-off restarting failed container

Chechking the startup logs we see the following:

W0118 08:42:27.365935       1 client_config.go:614] Neither --kubeconfig nor --master was specified.  Using the inClusterConfig.  This might not work.
time="2022-01-18T08:42:29Z" level=info msg="no cluster identity given -> checking cluster"
time="2022-01-18T08:42:29Z" level=info msg="adding cluster \"default\"[default/gardener.cloud](v1.19.15) as \"default\""
time="2022-01-18T08:42:29Z" level=info msg="adding cluster \"default\"[default/gardener.cloud](v1.19.15) as \"dns\" using default fallback"
time="2022-01-18T08:42:29Z" level=info msg="using \"/etc/shoot-cluster/kubeconfig\" for cluster \"source\"[]"
I0118 08:42:31.574217       1 request.go:655] Throttling request took 1.012813622s, request: GET:https://kube-apiserver.shoot--foo--bar/apis/cert-manager.io/v1alpha2?timeout=32s
I0118 08:42:41.874888       1 request.go:655] Throttling request took 11.213520951s, request: GET:https://kube-apiserver.shoot--foo--bar/apis/azure.microsoft.com/v1beta1?timeout=32s
time="2022-01-18T08:42:47Z" level=warning msg="failed to get all server resources for cluster source: unable to retrieve the complete list of server APIs: acme.syseleven.de/v1alpha1: the server is currently unable to handle the request"
time="2022-01-18T08:42:47Z" level=info msg="found 95 resources"
I0118 08:42:51.974851       1 request.go:655] Throttling request took 4.394967205s, request: GET:https://kube-apiserver.shoot--foo--bar/apis/caching.internal.knative.dev/v1alpha1?timeout=32s
I0118 08:43:02.173262       1 request.go:655] Throttling request took 14.59332364s, request: GET:https://kube-apiserver.shoot--foo--bar/apis/cert-manager.io/v1alpha3?timeout=32s
I0118 08:43:12.371697       1 request.go:655] Throttling request took 5.195254228s, request: GET:https://kube-apiserver.shoot--foo--bar/apis/storage.k8s.io/v1?timeout=32s
I0118 08:43:22.517665       1 request.go:655] Throttling request took 15.341179351s, request: GET:https://kube-apiserver.shoot--foo--bar/apis/admissionregistration.k8s.io/v1beta1?timeout=32s
time="2022-01-18T08:43:23Z" level=info msg="process is being terminated without grace period"
time="2022-01-18T08:43:26Z" level=warning msg="*** failed to get all preferred server resources for cluster source: unable to retrieve the complete list of server APIs: acme.syseleven.de/v1alpha1: the server is currently unable to handle the request"
time="2022-01-18T08:43:26Z" level=info msg="found 95 resources"


time="2022-01-18T08:43:26Z" level=info msg="waiting for extensions to shutdown"
time="2022-01-18T08:43:26Z" level=info msg="controllers: waiting for controllers to shutdown"
I0118 08:43:26.161991       1 leaderelection.go:243] attempting to acquire leader lease kube-system/shoot-cert-service...
time="2022-01-18T08:43:26Z" level=info msg="controllers: Lost leadership, cleaning up source (issuer, ingress-cert, service-cert)."
time="2022-01-18T08:43:26Z" level=info msg="controllers: all controllers down now"
time="2022-01-18T08:43:26Z" level=info msg="all extensions down -> exit controller manager"
time="2022-01-18T08:43:26Z" level=info msg="waiting for everything to shutdown (max. 120 seconds)"
time="2022-01-18T08:43:26Z" level=info msg="cert-controller-manager exits."

We see that the component is doing API discovery calls and this takes too much time - requests throttling times are 11.213520951s, 14.59332364s, 15.341179351s. The cluster also has high amount of APIServices such as knative, istio and others. It also has misconfigured APIService and misconfigured conversion webhook.
Does the component really need to do such discovery for each and every APIService?
From the logs it seems that discovery is done 2 times - does it need to do it 2 times?

We also see the log

time="2022-01-18T08:43:23Z" level=info msg="process is being terminated without grace period"

Most probably kubelet killed the container because of the failing liveness probe.

The liveness probe of the container is:

    livenessProbe:
      failureThreshold: 3
      httpGet:
        path: /healthz
        port: 10258
        scheme: HTTP
      initialDelaySeconds: 30
      periodSeconds: 10
      successThreshold: 1
      timeoutSeconds: 5

When we increased the initialDelaySeconds to 120 seconds, then the Pod was able to recover from this issue.

What you expected to happen:
Discovery calls to be reviewed. If they are really needed, then the livenessProbe to be adjusted so that the Pod can start successfully when there are relatively high amount of APIServices and when there are misconfigured APIServices and conversion webhooks.

How to reproduce it (as minimally and precisely as possible):
See above.

Environment:

  • Gardener version (if relevant):
  • Extension version:
  • Kubernetes version (use kubectl version):
  • Cloud provider or hardware configuration:
  • Others:

certificate support for custom domains in shoot cluster

What would you like to be added:
I would like to manage Let's Encrypt certificates for workloads on top of shoot clusters with Gardeners cert-broker.

Whenever I create an ingress resource (or a separate Certificate resource), I would like Gardener to create and manage the lifetime of the certificates so that I can use them with an ingress-controller.

I don't want to manage external-dns or cert-manager deployments/credentials myself.

Why is this needed:
A common requirement for workloads is to be addressable (DNS) and be secured (TLS). For both requirements external components exist (external-dns, cert-manager), however they need to be managed (including credentials). Since Gardener needs dns- and certificate-management internally it would be great if it could be made available to shoot clusters as well.

Allow to configure additional domain ranges for restricted default issuer

How to categorize this issue?

/area control-plane
/kind enhancement
/priority normal

What would you like to be added:
The default ACME issuer can be restricted to shoot related domains with the option restrictIssuer=true in the service config. In this case, the default issuer can only request certificates for subdomains of shoot.spec.dns.domain of the shoot spec. It would be helpful, if further custom domain name ranges could be added in this restricted mode.
For this purpose, it should be possible to specify one or more domain names in the service config to allow certificates on subdomains.

Why is this needed:

Implement extension controller for "cert-management"

We want to replace our current certificate solution with Cert-Manager/Cert-Broker by a new component called cert-management.

This will enable us to reuse the DNS providers principle and thus to support certificate services even for custom domains (#237).

Another controller for extensions of type certificate-service is needed to deploy the cert-management component for each Shoot cluster. Consequently, this new controller will also replace the currently used extension controller for certificate-services.

404 Issue

Hi Team- The list of pre-pointers in this link are all leading to 404 errors. Can you please correct the links? Thanks!
image

Shoot cert controller manager is not labelled as controlplane and hence isn't managed by DWD

How to categorize this issue?

/area control-plane robustness high-availability
/kind bug
/priority normal

What happened:
If the kube-apiserver is down for long enough, the dependent control-plane components go into CrashloopBackoff and when the kube-apiserver recovers, the dependency-watchdog pro-actively restarts (deletes) the rest of the control-plane pods that are still in CrashloopBackoff.

https://github.com/gardener/gardener/blob/b6877b359f19933b14270ce080d4b2efb3087400/charts/seed-bootstrap/charts/dependency-watchdog/templates/endpoint-configmap.yaml#L17-L20

However, the cert controller manager pod doesn't match the selector that selects control-plane pods. This prevents it from recovering as fast as possible after kube-apiserver recovers.

What you expected to happen:
The vert controller manager also should be made to recover from CrashloopBackoff by the dependency-watchdog like other control-plane pods by labelling it as control-plane.

How to reproduce it (as minimally and precisely as possible):
Manually scale-down kube-apiserver to 0 for long enough to get the cert manager pod (and other control-plane pods) into CrashloopBackoff and then scale it back up again.

Anything else we need to know?:
Please see gardener/gardener-extension-shoot-dns-service#36 and gardener/gardener-extension-shoot-dns-service#37.

Environment:

  • Gardener version (if relevant):
  • Extension version:
  • Kubernetes version (use kubectl version):
  • Cloud provider or hardware configuration:
  • Others:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.