From 38045e6c16d664890b2f83783f6c42abb91b2dff Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Wed, 19 Jun 2019 12:00:42 +0100 Subject: [PATCH 1/7] Add podspec and checks to podtemplate Signed-off-by: Michael Tsang --- pkg/apis/certmanager/v1alpha1/types_issuer.go | 1 + .../v1alpha1/zz_generated.deepcopy.go | 1 + pkg/apis/certmanager/validation/issuer.go | 9 +- .../certmanager/validation/issuer_test.go | 93 ++++++++++++++++++- 4 files changed, 101 insertions(+), 3 deletions(-) diff --git a/pkg/apis/certmanager/v1alpha1/types_issuer.go b/pkg/apis/certmanager/v1alpha1/types_issuer.go index b49338e91..9dfe3b54c 100644 --- a/pkg/apis/certmanager/v1alpha1/types_issuer.go +++ b/pkg/apis/certmanager/v1alpha1/types_issuer.go @@ -307,6 +307,7 @@ type ACMEChallengeSolverHTTP01Ingress struct { type ACMEChallengeSolverHTTP01IngressPodTemplate struct { metav1.ObjectMeta `json:"metadata,omitempty"` + corev1.PodSpec `json:"spec,omitempty"` } type ACMEChallengeSolverDNS01 struct { diff --git a/pkg/apis/certmanager/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/certmanager/v1alpha1/zz_generated.deepcopy.go index 67bd3006a..be17dc082 100644 --- a/pkg/apis/certmanager/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/certmanager/v1alpha1/zz_generated.deepcopy.go @@ -192,6 +192,7 @@ func (in *ACMEChallengeSolverHTTP01Ingress) DeepCopy() *ACMEChallengeSolverHTTP0 func (in *ACMEChallengeSolverHTTP01IngressPodTemplate) DeepCopyInto(out *ACMEChallengeSolverHTTP01IngressPodTemplate) { *out = *in in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.PodSpec.DeepCopyInto(&out.PodSpec) return } diff --git a/pkg/apis/certmanager/validation/issuer.go b/pkg/apis/certmanager/validation/issuer.go index 1d3041547..da5e9a107 100644 --- a/pkg/apis/certmanager/validation/issuer.go +++ b/pkg/apis/certmanager/validation/issuer.go @@ -153,7 +153,14 @@ func ValidateACMEIssuerChallengeSolverHTTP01IngressPodTemplateConfig(podTempl *v cpyPodTempl.Annotations = nil if !reflect.DeepEqual(cpyPodTempl.ObjectMeta, metav1.ObjectMeta{}) { - el = append(el, field.Invalid(fldPath.Child("metadata"), "", "only labels and annotations may be set on podTemplate")) + el = append(el, field.Invalid(fldPath.Child("metadata"), "", "only labels and annotations may be set on podTemplate metadata")) + } + + cpyPodTempl.NodeSelector = nil + cpyPodTempl.Tolerations = nil + + if !reflect.DeepEqual(cpyPodTempl.PodSpec, corev1.PodSpec{}) { + el = append(el, field.Invalid(fldPath.Child("spec"), "", "only nodeSelector and tolerations may be set on podTemplate spec")) } return el diff --git a/pkg/apis/certmanager/validation/issuer_test.go b/pkg/apis/certmanager/validation/issuer_test.go index e3aacca3b..c45aa4c12 100644 --- a/pkg/apis/certmanager/validation/issuer_test.go +++ b/pkg/apis/certmanager/validation/issuer_test.go @@ -200,7 +200,7 @@ func TestValidateACMEIssuerConfig(t *testing.T) { field.Invalid(fldPath.Child("http01", "serviceType"), corev1.ServiceType("InvalidServiceType"), "optional field serviceType must be one of [\"ClusterIP\" \"NodePort\"]"), }, }, - "acme issue with valid pod template attributes": { + "acme issue with valid pod template ObjectMeta attributes": { spec: &v1alpha1.ACMEIssuer{ Email: "valid-email", Server: "valid-server", @@ -253,7 +253,96 @@ func TestValidateACMEIssuerConfig(t *testing.T) { }, errs: []*field.Error{ field.Invalid(fldPath.Child("solver", "http01", "ingress", "podTemplate", "metadata"), - "", "only labels and annotations may be set on podTemplate"), + "", "only labels and annotations may be set on podTemplate metadata"), + }, + }, + "acme issue with valid pod template PodSpec attributes": { + spec: &v1alpha1.ACMEIssuer{ + Email: "valid-email", + Server: "valid-server", + PrivateKey: validSecretKeyRef, + Solvers: []v1alpha1.ACMEChallengeSolver{ + { + HTTP01: &v1alpha1.ACMEChallengeSolverHTTP01{ + Ingress: &v1alpha1.ACMEChallengeSolverHTTP01Ingress{ + PodTemplate: &v1alpha1.ACMEChallengeSolverHTTP01IngressPodTemplate{ + PodSpec: corev1.PodSpec{ + NodeSelector: map[string]string{ + "valid_to_contain": "nodeSelector", + }, + Tolerations: []corev1.Toleration{ + { + Key: "valid_key", + Operator: "Exists", + Effect: "NoSchedule", + }, + }, + }, + }, + }, + }, + }, + }, + HTTP01: &v1alpha1.ACMEIssuerHTTP01Config{ + ServiceType: corev1.ServiceType("NodePort"), + }, + }, + }, + "acme issue with invalid pod template PodSpec attributes": { + spec: &v1alpha1.ACMEIssuer{ + Email: "valid-email", + Server: "valid-server", + PrivateKey: validSecretKeyRef, + Solvers: []v1alpha1.ACMEChallengeSolver{ + { + HTTP01: &v1alpha1.ACMEChallengeSolverHTTP01{ + Ingress: &v1alpha1.ACMEChallengeSolverHTTP01Ingress{ + PodTemplate: &v1alpha1.ACMEChallengeSolverHTTP01IngressPodTemplate{ + PodSpec: corev1.PodSpec{ + NodeSelector: map[string]string{ + "valid_to_contain": "nodeSelector", + }, + NodeName: "unable-to-change-nodeName", + }, + }, + }, + }, + }, + }, + }, + errs: []*field.Error{ + field.Invalid(fldPath.Child("solver", "http01", "ingress", "podTemplate", "spec"), + "", "only nodeSelector and tolerations may be set on podTemplate spec"), + }, + }, + "acme issue with valid pod template ObjectMeta and PodSpec attributes": { + spec: &v1alpha1.ACMEIssuer{ + Email: "valid-email", + Server: "valid-server", + PrivateKey: validSecretKeyRef, + Solvers: []v1alpha1.ACMEChallengeSolver{ + { + HTTP01: &v1alpha1.ACMEChallengeSolverHTTP01{ + Ingress: &v1alpha1.ACMEChallengeSolverHTTP01Ingress{ + PodTemplate: &v1alpha1.ACMEChallengeSolverHTTP01IngressPodTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "valid_to_contain": "labels", + }, + }, + PodSpec: corev1.PodSpec{ + NodeSelector: map[string]string{ + "valid_to_contain": "nodeSelector", + }, + }, + }, + }, + }, + }, + }, + HTTP01: &v1alpha1.ACMEIssuerHTTP01Config{ + ServiceType: corev1.ServiceType("NodePort"), + }, }, }, } From d34effece012bd668c7b73c545f4cf1f847283f2 Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Wed, 19 Jun 2019 13:28:11 +0100 Subject: [PATCH 2/7] Add nodeselector and tolerations to pod building Signed-off-by: Michael Tsang --- .../output/reference/api-docs/index.html | 4 +++ pkg/issuer/acme/http/pod.go | 16 ++++++++++++ pkg/issuer/acme/http/pod_test.go | 25 ++++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/docs/generated/reference/output/reference/api-docs/index.html b/docs/generated/reference/output/reference/api-docs/index.html index f19a28781..00f7ae50b 100755 --- a/docs/generated/reference/output/reference/api-docs/index.html +++ b/docs/generated/reference/output/reference/api-docs/index.html @@ -835,6 +835,10 @@ Appears In: metadata
*ObjectMeta* + +spec
PodSpec + +

ACMEIssuer v1alpha1

diff --git a/pkg/issuer/acme/http/pod.go b/pkg/issuer/acme/http/pod.go index 11bb0f6ab..293507044 100644 --- a/pkg/issuer/acme/http/pod.go +++ b/pkg/issuer/acme/http/pod.go @@ -224,5 +224,21 @@ func (s *Solver) mergePodObjectMetaWithPodTemplate(pod *corev1.Pod, podTempl *v1 pod.Annotations[k] = v } + if pod.Spec.NodeSelector == nil { + pod.Spec.NodeSelector = make(map[string]string) + } + + for k, v := range podTempl.NodeSelector { + pod.Spec.NodeSelector[k] = v + } + + if pod.Spec.Tolerations == nil { + pod.Spec.Tolerations = []corev1.Toleration{} + } + + for _, t := range podTempl.Tolerations { + pod.Spec.Tolerations = append(pod.Spec.Tolerations, t) + } + return pod } diff --git a/pkg/issuer/acme/http/pod_test.go b/pkg/issuer/acme/http/pod_test.go index 8aecc060c..01d04f9e6 100644 --- a/pkg/issuer/acme/http/pod_test.go +++ b/pkg/issuer/acme/http/pod_test.go @@ -21,7 +21,8 @@ import ( "reflect" "testing" - "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" @@ -278,6 +279,18 @@ func TestMergePodObjectMetaWithPodTemplate(t *testing.T) { "foo": "bar", }, }, + PodSpec: corev1.PodSpec{ + NodeSelector: map[string]string{ + "node": "selector", + }, + Tolerations: []corev1.Toleration{ + { + Key: "key", + Operator: "Exists", + Effect: "NoSchedule", + }, + }, + }, }, }, }, @@ -296,6 +309,16 @@ func TestMergePodObjectMetaWithPodTemplate(t *testing.T) { "sidecar.istio.io/inject": "true", "foo": "bar", } + resultingPod.Spec.NodeSelector = map[string]string{ + "node": "selector", + } + resultingPod.Spec.Tolerations = []corev1.Toleration{ + { + Key: "key", + Operator: "Exists", + Effect: "NoSchedule", + }, + } s.testResources[createdPodKey] = resultingPod s.Builder.Sync() From 521f02e98822beae96b3c728fd2599761b91a8b9 Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Wed, 19 Jun 2019 13:38:38 +0100 Subject: [PATCH 3/7] Document spec in podTemplate Signed-off-by: Michael Tsang --- .../tasks/issuers/setup-acme/http01/index.rst | 51 +++++++++++-------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/docs/tasks/issuers/setup-acme/http01/index.rst b/docs/tasks/issuers/setup-acme/http01/index.rst index 7cd9188d8..e75c79945 100644 --- a/docs/tasks/issuers/setup-acme/http01/index.rst +++ b/docs/tasks/issuers/setup-acme/http01/index.rst @@ -72,31 +72,40 @@ podTemplate ----------- You may wish to change or add to the labels and annotations of solver pods. -These can be configured under the `metadata` field under `podTemplate`. No other -metadata fields can be edited. Below shows how an issuer that is configured to -add some labels and annotations to solver pods. +These can be configured under the ``metadata`` field under ``podTemplate``. + +Similarly, you can set the node selector and tolerations of solver pods by +configuring under the ``spec`` field of the ``podTemplate``. No other spec fields +can be edited. + +An example of how you could configure the template is as so: .. code-block:: yaml + :linenos: + :emphasize-lines: 13-20 - apiVersion: certmanager.k8s.io/v1alpha1 - kind: Issuer - metadata: + apiVersion: certmanager.k8s.io/v1alpha1 + kind: Issuer + metadata: + name: ... + spec: + acme: + server: ... + privateKeySecretRef: name: ... - spec: - acme: - server: ... - privateKeySecretRef: - name: ... - solvers: - - http01: - ingress: - podTemplate: - metadata: - labels: - foo: "bar" - env: "prod" - annotations: - my: "annotation" + solvers: + - http01: + ingress: + podTemplate: + metadata: + labels: + foo: "bar" + env: "prod" + spec: + nodeSelector: + bar: baz The added labels and annotations will merge on top of the cert-manager defaults, overriding entries with the same key. + +No other fields can be edited. \ No newline at end of file From 361ee83102a1b1c514851270fdd2bebc29863de4 Mon Sep 17 00:00:00 2001 From: James Munnelly Date: Fri, 5 Jul 2019 15:21:40 +0100 Subject: [PATCH 4/7] Update to use custom PodSpec struct and support Affinity too Signed-off-by: James Munnelly --- .../tasks/issuers/setup-acme/http01/index.rst | 6 +-- pkg/apis/certmanager/v1alpha1/types_issuer.go | 30 ++++++++++-- .../v1alpha1/zz_generated.deepcopy.go | 46 +++++++++++++++++-- pkg/apis/certmanager/validation/issuer.go | 7 --- .../certmanager/validation/issuer_test.go | 31 +------------ pkg/issuer/acme/http/pod.go | 8 +++- 6 files changed, 78 insertions(+), 50 deletions(-) diff --git a/docs/tasks/issuers/setup-acme/http01/index.rst b/docs/tasks/issuers/setup-acme/http01/index.rst index e75c79945..34a22df9f 100644 --- a/docs/tasks/issuers/setup-acme/http01/index.rst +++ b/docs/tasks/issuers/setup-acme/http01/index.rst @@ -74,9 +74,9 @@ podTemplate You may wish to change or add to the labels and annotations of solver pods. These can be configured under the ``metadata`` field under ``podTemplate``. -Similarly, you can set the node selector and tolerations of solver pods by -configuring under the ``spec`` field of the ``podTemplate``. No other spec fields -can be edited. +Similarly, you can set the nodeSelector, tolerations and affinity of solver +pods by configuring under the ``spec`` field of the ``podTemplate``. No other +spec fields can be edited. An example of how you could configure the template is as so: diff --git a/pkg/apis/certmanager/v1alpha1/types_issuer.go b/pkg/apis/certmanager/v1alpha1/types_issuer.go index 9dfe3b54c..4c9146ddd 100644 --- a/pkg/apis/certmanager/v1alpha1/types_issuer.go +++ b/pkg/apis/certmanager/v1alpha1/types_issuer.go @@ -298,16 +298,38 @@ type ACMEChallengeSolverHTTP01Ingress struct { Name string `json:"name,omitempty"` // Optional pod template used to configure the ACME challenge solver pods - // used for HTTP01 challenges. Only labels and annotations may be set and - // will be merged ontop of the defaults. PodTemplate labels and annotation - // fields will override fields with matching keys. + // used for HTTP01 challenges // +optional PodTemplate *ACMEChallengeSolverHTTP01IngressPodTemplate `json:"podTemplate,omitempty"` } type ACMEChallengeSolverHTTP01IngressPodTemplate struct { + // ObjectMeta overrides for the pod used to solve HTTP01 challenges. + // Only the 'labels' and 'annotations' fields may be set. + // If labels or annotations overlap with in-built value, the values here + // will override the in-built values. metav1.ObjectMeta `json:"metadata,omitempty"` - corev1.PodSpec `json:"spec,omitempty"` + + // PodSpec defines overrides for the HTTP01 challenge solver pod. + // Only the 'nodeSelector', 'affinity' and 'tolerations' fields are + // supported currently. All other fields will be ignored. + Spec ACMEChallengeSolverHTTP01IngressPodSpec `json:"spec,omitempty"` +} + +type ACMEChallengeSolverHTTP01IngressPodSpec struct { + // NodeSelector is a selector which must be true for the pod to fit on a node. + // Selector which must match a node's labels for the pod to be scheduled on that node. + // More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + // +optional + NodeSelector map[string]string `json:"nodeSelector,omitempty"` + + // If specified, the pod's scheduling constraints + // +optional + Affinity *corev1.Affinity `json:"affinity,omitempty"` + + // If specified, the pod's tolerations. + // +optional + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` } type ACMEChallengeSolverDNS01 struct { diff --git a/pkg/apis/certmanager/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/certmanager/v1alpha1/zz_generated.deepcopy.go index be17dc082..fe00dd5a9 100644 --- a/pkg/apis/certmanager/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/certmanager/v1alpha1/zz_generated.deepcopy.go @@ -21,8 +21,9 @@ limitations under the License. package v1alpha1 import ( + v1 "k8s.io/api/core/v1" v1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -188,11 +189,46 @@ func (in *ACMEChallengeSolverHTTP01Ingress) DeepCopy() *ACMEChallengeSolverHTTP0 return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ACMEChallengeSolverHTTP01IngressPodSpec) DeepCopyInto(out *ACMEChallengeSolverHTTP01IngressPodSpec) { + *out = *in + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Affinity != nil { + in, out := &in.Affinity, &out.Affinity + *out = new(v1.Affinity) + (*in).DeepCopyInto(*out) + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]v1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ACMEChallengeSolverHTTP01IngressPodSpec. +func (in *ACMEChallengeSolverHTTP01IngressPodSpec) DeepCopy() *ACMEChallengeSolverHTTP01IngressPodSpec { + if in == nil { + return nil + } + out := new(ACMEChallengeSolverHTTP01IngressPodSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ACMEChallengeSolverHTTP01IngressPodTemplate) DeepCopyInto(out *ACMEChallengeSolverHTTP01IngressPodTemplate) { *out = *in in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.PodSpec.DeepCopyInto(&out.PodSpec) + in.Spec.DeepCopyInto(&out.Spec) return } @@ -731,7 +767,7 @@ func (in *CertificateRequestSpec) DeepCopyInto(out *CertificateRequestSpec) { *out = *in if in.Duration != nil { in, out := &in.Duration, &out.Duration - *out = new(v1.Duration) + *out = new(metav1.Duration) (*in).DeepCopyInto(*out) } out.IssuerRef = in.IssuerRef @@ -796,12 +832,12 @@ func (in *CertificateSpec) DeepCopyInto(out *CertificateSpec) { } if in.Duration != nil { in, out := &in.Duration, &out.Duration - *out = new(v1.Duration) + *out = new(metav1.Duration) (*in).DeepCopyInto(*out) } if in.RenewBefore != nil { in, out := &in.RenewBefore, &out.RenewBefore - *out = new(v1.Duration) + *out = new(metav1.Duration) (*in).DeepCopyInto(*out) } if in.DNSNames != nil { diff --git a/pkg/apis/certmanager/validation/issuer.go b/pkg/apis/certmanager/validation/issuer.go index da5e9a107..f1049e754 100644 --- a/pkg/apis/certmanager/validation/issuer.go +++ b/pkg/apis/certmanager/validation/issuer.go @@ -156,13 +156,6 @@ func ValidateACMEIssuerChallengeSolverHTTP01IngressPodTemplateConfig(podTempl *v el = append(el, field.Invalid(fldPath.Child("metadata"), "", "only labels and annotations may be set on podTemplate metadata")) } - cpyPodTempl.NodeSelector = nil - cpyPodTempl.Tolerations = nil - - if !reflect.DeepEqual(cpyPodTempl.PodSpec, corev1.PodSpec{}) { - el = append(el, field.Invalid(fldPath.Child("spec"), "", "only nodeSelector and tolerations may be set on podTemplate spec")) - } - return el } diff --git a/pkg/apis/certmanager/validation/issuer_test.go b/pkg/apis/certmanager/validation/issuer_test.go index c45aa4c12..63dc28e3f 100644 --- a/pkg/apis/certmanager/validation/issuer_test.go +++ b/pkg/apis/certmanager/validation/issuer_test.go @@ -266,7 +266,7 @@ func TestValidateACMEIssuerConfig(t *testing.T) { HTTP01: &v1alpha1.ACMEChallengeSolverHTTP01{ Ingress: &v1alpha1.ACMEChallengeSolverHTTP01Ingress{ PodTemplate: &v1alpha1.ACMEChallengeSolverHTTP01IngressPodTemplate{ - PodSpec: corev1.PodSpec{ + Spec: v1alpha1.ACMEChallengeSolverHTTP01IngressPodSpec{ NodeSelector: map[string]string{ "valid_to_contain": "nodeSelector", }, @@ -288,33 +288,6 @@ func TestValidateACMEIssuerConfig(t *testing.T) { }, }, }, - "acme issue with invalid pod template PodSpec attributes": { - spec: &v1alpha1.ACMEIssuer{ - Email: "valid-email", - Server: "valid-server", - PrivateKey: validSecretKeyRef, - Solvers: []v1alpha1.ACMEChallengeSolver{ - { - HTTP01: &v1alpha1.ACMEChallengeSolverHTTP01{ - Ingress: &v1alpha1.ACMEChallengeSolverHTTP01Ingress{ - PodTemplate: &v1alpha1.ACMEChallengeSolverHTTP01IngressPodTemplate{ - PodSpec: corev1.PodSpec{ - NodeSelector: map[string]string{ - "valid_to_contain": "nodeSelector", - }, - NodeName: "unable-to-change-nodeName", - }, - }, - }, - }, - }, - }, - }, - errs: []*field.Error{ - field.Invalid(fldPath.Child("solver", "http01", "ingress", "podTemplate", "spec"), - "", "only nodeSelector and tolerations may be set on podTemplate spec"), - }, - }, "acme issue with valid pod template ObjectMeta and PodSpec attributes": { spec: &v1alpha1.ACMEIssuer{ Email: "valid-email", @@ -330,7 +303,7 @@ func TestValidateACMEIssuerConfig(t *testing.T) { "valid_to_contain": "labels", }, }, - PodSpec: corev1.PodSpec{ + Spec: v1alpha1.ACMEChallengeSolverHTTP01IngressPodSpec{ NodeSelector: map[string]string{ "valid_to_contain": "nodeSelector", }, diff --git a/pkg/issuer/acme/http/pod.go b/pkg/issuer/acme/http/pod.go index 293507044..94fe5d9d5 100644 --- a/pkg/issuer/acme/http/pod.go +++ b/pkg/issuer/acme/http/pod.go @@ -228,7 +228,7 @@ func (s *Solver) mergePodObjectMetaWithPodTemplate(pod *corev1.Pod, podTempl *v1 pod.Spec.NodeSelector = make(map[string]string) } - for k, v := range podTempl.NodeSelector { + for k, v := range podTempl.Spec.NodeSelector { pod.Spec.NodeSelector[k] = v } @@ -236,9 +236,13 @@ func (s *Solver) mergePodObjectMetaWithPodTemplate(pod *corev1.Pod, podTempl *v1 pod.Spec.Tolerations = []corev1.Toleration{} } - for _, t := range podTempl.Tolerations { + for _, t := range podTempl.Spec.Tolerations { pod.Spec.Tolerations = append(pod.Spec.Tolerations, t) } + if podTempl.Spec.Affinity != nil { + pod.Spec.Affinity = podTempl.Spec.Affinity + } + return pod } From 161745fa7c194b973fce24a6875a58d9bd55351d Mon Sep 17 00:00:00 2001 From: James Munnelly Date: Fri, 5 Jul 2019 15:22:26 +0100 Subject: [PATCH 5/7] update reference docs Signed-off-by: James Munnelly --- .../output/reference/api-docs/index.html | 52 +++++++++++++++++-- .../output/reference/api-docs/navData.js | 2 +- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/docs/generated/reference/output/reference/api-docs/index.html b/docs/generated/reference/output/reference/api-docs/index.html index 00f7ae50b..90d34a427 100755 --- a/docs/generated/reference/output/reference/api-docs/index.html +++ b/docs/generated/reference/output/reference/api-docs/index.html @@ -11,7 +11,7 @@ - +

    cert-manager

    @@ -795,13 +795,55 @@ Appears In:
    - +
    podTemplate
    *ACMEChallengeSolverHTTP01IngressPodTemplate*
    Optional pod template used to configure the ACME challenge solver pods used for HTTP01 challenges. Only labels and annotations may be set and will be merged ontop of the defaults. PodTemplate labels and annotation fields will override fields with matching keys.Optional pod template used to configure the ACME challenge solver pods used for HTTP01 challenges
    serviceType
    string
    Optional service type for Kubernetes solver service
    +

    ACMEChallengeSolverHTTP01IngressPodSpec v1alpha1

    + + + + + + + + + + + + + +
    GroupVersionKind
    certmanagerv1alpha1ACMEChallengeSolverHTTP01IngressPodSpec
    + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    affinity
    Affinity
    If specified, the pod's scheduling constraints
    nodeSelector
    object
    NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
    tolerations
    Toleration array
    If specified, the pod's tolerations.

    ACMEChallengeSolverHTTP01IngressPodTemplate v1alpha1

    @@ -833,11 +875,11 @@ Appears In: - + - - + +
    metadata
    *ObjectMeta*
    ObjectMeta overrides for the pod used to solve HTTP01 challenges. Only the 'labels' and 'annotations' fields may be set. If labels or annotations overlap with in-built value, the values here will override the in-built values.
    spec
    PodSpec
    spec
    *ACMEChallengeSolverHTTP01IngressPodSpec*
    PodSpec defines overrides for the HTTP01 challenge solver pod. Only the 'nodeSelector', 'affinity' and 'tolerations' fields are supported currently. All other fields will be ignored.

    ACMEIssuer v1alpha1

    diff --git a/docs/generated/reference/output/reference/api-docs/navData.js b/docs/generated/reference/output/reference/api-docs/navData.js index ed0f1d8f8..b7941c651 100755 --- a/docs/generated/reference/output/reference/api-docs/navData.js +++ b/docs/generated/reference/output/reference/api-docs/navData.js @@ -1 +1 @@ -(function(){navData = {"toc":[{"section":"-strong-field-definitions-strong-","subsections":[{"section":"venafitpp-v1alpha1"},{"section":"venafiissuer-v1alpha1"},{"section":"venaficloud-v1alpha1"},{"section":"vaultissuer-v1alpha1"},{"section":"vaultauth-v1alpha1"},{"section":"vaultapprole-v1alpha1"},{"section":"time-v1"},{"section":"statusdetails-v1"},{"section":"statuscause-v1"},{"section":"status-v1"},{"section":"solverconfig-v1alpha1"},{"section":"selfsignedissuer-v1alpha1"},{"section":"secretkeyselector-v1alpha1"},{"section":"ownerreference-v1"},{"section":"objectreference-v1alpha1"},{"section":"objectmeta-v1"},{"section":"managedfieldsentry-v1"},{"section":"localobjectreference-v1alpha1"},{"section":"listmeta-v1"},{"section":"issuercondition-v1alpha1"},{"section":"initializers-v1"},{"section":"initializer-v1"},{"section":"http01solverconfig-v1alpha1"},{"section":"fields-v1"},{"section":"duration-v1"},{"section":"domainsolverconfig-v1alpha1"},{"section":"dns01solverconfig-v1alpha1"},{"section":"certificatednsnameselector-v1alpha1"},{"section":"certificatecondition-v1alpha1"},{"section":"caissuer-v1alpha1"},{"section":"acmeissuerhttp01config-v1alpha1"},{"section":"acmeissuerdns01providerwebhook-v1alpha1"},{"section":"acmeissuerdns01providerroute53-v1alpha1"},{"section":"acmeissuerdns01providerrfc2136-v1alpha1"},{"section":"acmeissuerdns01providerdigitalocean-v1alpha1"},{"section":"acmeissuerdns01providercloudflare-v1alpha1"},{"section":"acmeissuerdns01providerclouddns-v1alpha1"},{"section":"acmeissuerdns01providerazuredns-v1alpha1"},{"section":"acmeissuerdns01providerakamai-v1alpha1"},{"section":"acmeissuerdns01provideracmedns-v1alpha1"},{"section":"acmeissuerdns01provider-v1alpha1"},{"section":"acmeissuerdns01config-v1alpha1"},{"section":"acmeissuer-v1alpha1"},{"section":"acmechallengesolverhttp01ingresspodtemplate-v1alpha1"},{"section":"acmechallengesolverhttp01ingress-v1alpha1"},{"section":"acmechallengesolverhttp01-v1alpha1"},{"section":"acmechallengesolverdns01-v1alpha1"},{"section":"acmechallengesolver-v1alpha1"},{"section":"acmecertificateconfig-v1alpha1"}]},{"section":"-strong-old-api-versions-strong-","subsections":[]},{"section":"challenge-v1alpha1","subsections":[]},{"section":"order-v1alpha1","subsections":[]},{"section":"issuer-v1alpha1","subsections":[]},{"section":"clusterissuer-v1alpha1","subsections":[]},{"section":"certificate-v1alpha1","subsections":[]},{"section":"-strong-cert-manager-strong-","subsections":[]}],"flatToc":["venafitpp-v1alpha1","venafiissuer-v1alpha1","venaficloud-v1alpha1","vaultissuer-v1alpha1","vaultauth-v1alpha1","vaultapprole-v1alpha1","time-v1","statusdetails-v1","statuscause-v1","status-v1","solverconfig-v1alpha1","selfsignedissuer-v1alpha1","secretkeyselector-v1alpha1","ownerreference-v1","objectreference-v1alpha1","objectmeta-v1","managedfieldsentry-v1","localobjectreference-v1alpha1","listmeta-v1","issuercondition-v1alpha1","initializers-v1","initializer-v1","http01solverconfig-v1alpha1","fields-v1","duration-v1","domainsolverconfig-v1alpha1","dns01solverconfig-v1alpha1","certificatednsnameselector-v1alpha1","certificatecondition-v1alpha1","caissuer-v1alpha1","acmeissuerhttp01config-v1alpha1","acmeissuerdns01providerwebhook-v1alpha1","acmeissuerdns01providerroute53-v1alpha1","acmeissuerdns01providerrfc2136-v1alpha1","acmeissuerdns01providerdigitalocean-v1alpha1","acmeissuerdns01providercloudflare-v1alpha1","acmeissuerdns01providerclouddns-v1alpha1","acmeissuerdns01providerazuredns-v1alpha1","acmeissuerdns01providerakamai-v1alpha1","acmeissuerdns01provideracmedns-v1alpha1","acmeissuerdns01provider-v1alpha1","acmeissuerdns01config-v1alpha1","acmeissuer-v1alpha1","acmechallengesolverhttp01ingresspodtemplate-v1alpha1","acmechallengesolverhttp01ingress-v1alpha1","acmechallengesolverhttp01-v1alpha1","acmechallengesolverdns01-v1alpha1","acmechallengesolver-v1alpha1","acmecertificateconfig-v1alpha1","-strong-field-definitions-strong-","-strong-old-api-versions-strong-","challenge-v1alpha1","order-v1alpha1","issuer-v1alpha1","clusterissuer-v1alpha1","certificate-v1alpha1","-strong-cert-manager-strong-"]};})(); \ No newline at end of file +(function(){navData = {"toc":[{"section":"-strong-field-definitions-strong-","subsections":[{"section":"venafitpp-v1alpha1"},{"section":"venafiissuer-v1alpha1"},{"section":"venaficloud-v1alpha1"},{"section":"vaultissuer-v1alpha1"},{"section":"vaultauth-v1alpha1"},{"section":"vaultapprole-v1alpha1"},{"section":"time-v1"},{"section":"statusdetails-v1"},{"section":"statuscause-v1"},{"section":"status-v1"},{"section":"solverconfig-v1alpha1"},{"section":"selfsignedissuer-v1alpha1"},{"section":"secretkeyselector-v1alpha1"},{"section":"ownerreference-v1"},{"section":"objectreference-v1alpha1"},{"section":"objectmeta-v1"},{"section":"managedfieldsentry-v1"},{"section":"localobjectreference-v1alpha1"},{"section":"listmeta-v1"},{"section":"issuercondition-v1alpha1"},{"section":"initializers-v1"},{"section":"initializer-v1"},{"section":"http01solverconfig-v1alpha1"},{"section":"fields-v1"},{"section":"duration-v1"},{"section":"domainsolverconfig-v1alpha1"},{"section":"dns01solverconfig-v1alpha1"},{"section":"certificatednsnameselector-v1alpha1"},{"section":"certificatecondition-v1alpha1"},{"section":"caissuer-v1alpha1"},{"section":"acmeissuerhttp01config-v1alpha1"},{"section":"acmeissuerdns01providerwebhook-v1alpha1"},{"section":"acmeissuerdns01providerroute53-v1alpha1"},{"section":"acmeissuerdns01providerrfc2136-v1alpha1"},{"section":"acmeissuerdns01providerdigitalocean-v1alpha1"},{"section":"acmeissuerdns01providercloudflare-v1alpha1"},{"section":"acmeissuerdns01providerclouddns-v1alpha1"},{"section":"acmeissuerdns01providerazuredns-v1alpha1"},{"section":"acmeissuerdns01providerakamai-v1alpha1"},{"section":"acmeissuerdns01provideracmedns-v1alpha1"},{"section":"acmeissuerdns01provider-v1alpha1"},{"section":"acmeissuerdns01config-v1alpha1"},{"section":"acmeissuer-v1alpha1"},{"section":"acmechallengesolverhttp01ingresspodtemplate-v1alpha1"},{"section":"acmechallengesolverhttp01ingresspodspec-v1alpha1"},{"section":"acmechallengesolverhttp01ingress-v1alpha1"},{"section":"acmechallengesolverhttp01-v1alpha1"},{"section":"acmechallengesolverdns01-v1alpha1"},{"section":"acmechallengesolver-v1alpha1"},{"section":"acmecertificateconfig-v1alpha1"}]},{"section":"-strong-old-api-versions-strong-","subsections":[]},{"section":"challenge-v1alpha1","subsections":[]},{"section":"order-v1alpha1","subsections":[]},{"section":"issuer-v1alpha1","subsections":[]},{"section":"clusterissuer-v1alpha1","subsections":[]},{"section":"certificate-v1alpha1","subsections":[]},{"section":"-strong-cert-manager-strong-","subsections":[]}],"flatToc":["venafitpp-v1alpha1","venafiissuer-v1alpha1","venaficloud-v1alpha1","vaultissuer-v1alpha1","vaultauth-v1alpha1","vaultapprole-v1alpha1","time-v1","statusdetails-v1","statuscause-v1","status-v1","solverconfig-v1alpha1","selfsignedissuer-v1alpha1","secretkeyselector-v1alpha1","ownerreference-v1","objectreference-v1alpha1","objectmeta-v1","managedfieldsentry-v1","localobjectreference-v1alpha1","listmeta-v1","issuercondition-v1alpha1","initializers-v1","initializer-v1","http01solverconfig-v1alpha1","fields-v1","duration-v1","domainsolverconfig-v1alpha1","dns01solverconfig-v1alpha1","certificatednsnameselector-v1alpha1","certificatecondition-v1alpha1","caissuer-v1alpha1","acmeissuerhttp01config-v1alpha1","acmeissuerdns01providerwebhook-v1alpha1","acmeissuerdns01providerroute53-v1alpha1","acmeissuerdns01providerrfc2136-v1alpha1","acmeissuerdns01providerdigitalocean-v1alpha1","acmeissuerdns01providercloudflare-v1alpha1","acmeissuerdns01providerclouddns-v1alpha1","acmeissuerdns01providerazuredns-v1alpha1","acmeissuerdns01providerakamai-v1alpha1","acmeissuerdns01provideracmedns-v1alpha1","acmeissuerdns01provider-v1alpha1","acmeissuerdns01config-v1alpha1","acmeissuer-v1alpha1","acmechallengesolverhttp01ingresspodtemplate-v1alpha1","acmechallengesolverhttp01ingresspodspec-v1alpha1","acmechallengesolverhttp01ingress-v1alpha1","acmechallengesolverhttp01-v1alpha1","acmechallengesolverdns01-v1alpha1","acmechallengesolver-v1alpha1","acmecertificateconfig-v1alpha1","-strong-field-definitions-strong-","-strong-old-api-versions-strong-","challenge-v1alpha1","order-v1alpha1","issuer-v1alpha1","clusterissuer-v1alpha1","certificate-v1alpha1","-strong-cert-manager-strong-"]};})(); \ No newline at end of file From 46a3144c33cbd3276903ad5f372b963151746be8 Mon Sep 17 00:00:00 2001 From: James Munnelly Date: Fri, 5 Jul 2019 15:27:43 +0100 Subject: [PATCH 6/7] Mark fields optional Signed-off-by: James Munnelly --- pkg/apis/certmanager/v1alpha1/types_issuer.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/apis/certmanager/v1alpha1/types_issuer.go b/pkg/apis/certmanager/v1alpha1/types_issuer.go index 4c9146ddd..8b36b4a5e 100644 --- a/pkg/apis/certmanager/v1alpha1/types_issuer.go +++ b/pkg/apis/certmanager/v1alpha1/types_issuer.go @@ -308,11 +308,13 @@ type ACMEChallengeSolverHTTP01IngressPodTemplate struct { // Only the 'labels' and 'annotations' fields may be set. // If labels or annotations overlap with in-built value, the values here // will override the in-built values. + // +optional metav1.ObjectMeta `json:"metadata,omitempty"` // PodSpec defines overrides for the HTTP01 challenge solver pod. // Only the 'nodeSelector', 'affinity' and 'tolerations' fields are // supported currently. All other fields will be ignored. + // +optional Spec ACMEChallengeSolverHTTP01IngressPodSpec `json:"spec,omitempty"` } From aa3e2fa4aa416eb92ac080f27691c2714d37c1bc Mon Sep 17 00:00:00 2001 From: James Munnelly Date: Fri, 5 Jul 2019 15:30:32 +0100 Subject: [PATCH 7/7] Fix typos and tidy up imports Signed-off-by: James Munnelly --- .../reference/output/reference/api-docs/index.html | 2 +- pkg/apis/certmanager/v1alpha1/types_issuer.go | 2 +- pkg/issuer/acme/http/pod_test.go | 9 ++++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/generated/reference/output/reference/api-docs/index.html b/docs/generated/reference/output/reference/api-docs/index.html index 90d34a427..b31c4282b 100755 --- a/docs/generated/reference/output/reference/api-docs/index.html +++ b/docs/generated/reference/output/reference/api-docs/index.html @@ -875,7 +875,7 @@ Appears In: metadata
    *ObjectMeta* -ObjectMeta overrides for the pod used to solve HTTP01 challenges. Only the 'labels' and 'annotations' fields may be set. If labels or annotations overlap with in-built value, the values here will override the in-built values. +ObjectMeta overrides for the pod used to solve HTTP01 challenges. Only the 'labels' and 'annotations' fields may be set. If labels or annotations overlap with in-built values, the values here will override the in-built values. spec
    *ACMEChallengeSolverHTTP01IngressPodSpec* diff --git a/pkg/apis/certmanager/v1alpha1/types_issuer.go b/pkg/apis/certmanager/v1alpha1/types_issuer.go index 8b36b4a5e..5a19bb958 100644 --- a/pkg/apis/certmanager/v1alpha1/types_issuer.go +++ b/pkg/apis/certmanager/v1alpha1/types_issuer.go @@ -306,7 +306,7 @@ type ACMEChallengeSolverHTTP01Ingress struct { type ACMEChallengeSolverHTTP01IngressPodTemplate struct { // ObjectMeta overrides for the pod used to solve HTTP01 challenges. // Only the 'labels' and 'annotations' fields may be set. - // If labels or annotations overlap with in-built value, the values here + // If labels or annotations overlap with in-built values, the values here // will override the in-built values. // +optional metav1.ObjectMeta `json:"metadata,omitempty"` diff --git a/pkg/issuer/acme/http/pod_test.go b/pkg/issuer/acme/http/pod_test.go index 01d04f9e6..ac98d87a1 100644 --- a/pkg/issuer/acme/http/pod_test.go +++ b/pkg/issuer/acme/http/pod_test.go @@ -21,8 +21,7 @@ import ( "reflect" "testing" - corev1 "k8s.io/api/core/v1" - v1 "k8s.io/api/core/v1" + "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" @@ -279,11 +278,11 @@ func TestMergePodObjectMetaWithPodTemplate(t *testing.T) { "foo": "bar", }, }, - PodSpec: corev1.PodSpec{ + Spec: v1alpha1.ACMEChallengeSolverHTTP01IngressPodSpec{ NodeSelector: map[string]string{ "node": "selector", }, - Tolerations: []corev1.Toleration{ + Tolerations: []v1.Toleration{ { Key: "key", Operator: "Exists", @@ -312,7 +311,7 @@ func TestMergePodObjectMetaWithPodTemplate(t *testing.T) { resultingPod.Spec.NodeSelector = map[string]string{ "node": "selector", } - resultingPod.Spec.Tolerations = []corev1.Toleration{ + resultingPod.Spec.Tolerations = []v1.Toleration{ { Key: "key", Operator: "Exists",