Merge pull request #5250 from irbekrm/remove_networking_beta

Removes support for networking/v1beta1 Ingress
This commit is contained in:
jetstack-bot 2022-07-01 16:52:38 +01:00 committed by GitHub
commit 5c6bc8fb4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 31 additions and 1417 deletions

View File

@ -20,7 +20,6 @@ filegroup(
"//internal/controller/feature:all-srcs",
"//internal/controller/issuers:all-srcs",
"//internal/controller/orders:all-srcs",
"//internal/ingress:all-srcs",
"//internal/plugin:all-srcs",
"//internal/test/paths:all-srcs",
"//internal/vault:all-srcs",

View File

@ -1,66 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"convert.go",
"ingress.go",
"v1.go",
"v1beta1.go",
],
importpath = "github.com/cert-manager/cert-manager/internal/ingress",
visibility = ["//visibility:public"],
deps = [
"//pkg/controller:go_default_library",
"@io_k8s_api//core/v1:go_default_library",
"@io_k8s_api//networking/v1:go_default_library",
"@io_k8s_api//networking/v1beta1:go_default_library",
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
"@io_k8s_apimachinery//pkg/conversion:go_default_library",
"@io_k8s_apimachinery//pkg/labels:go_default_library",
"@io_k8s_apimachinery//pkg/util/intstr:go_default_library",
"@io_k8s_client_go//discovery:go_default_library",
"@io_k8s_client_go//kubernetes:go_default_library",
"@io_k8s_client_go//listers/networking/v1:go_default_library",
"@io_k8s_client_go//listers/networking/v1beta1:go_default_library",
"@io_k8s_client_go//tools/cache:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = [
"convert_test.go",
"ingress_test.go",
],
embed = [":go_default_library"],
deps = [
"//pkg/controller:go_default_library",
"//test/unit/discovery:go_default_library",
"@com_github_google_gofuzz//:go_default_library",
"@com_github_stretchr_testify//assert:go_default_library",
"@io_k8s_api//networking/v1:go_default_library",
"@io_k8s_api//networking/v1beta1:go_default_library",
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
"@io_k8s_apimachinery//pkg/labels:go_default_library",
"@io_k8s_apimachinery//pkg/runtime/schema:go_default_library",
"@io_k8s_apimachinery//pkg/util/intstr:go_default_library",
"@io_k8s_client_go//informers:go_default_library",
"@io_k8s_client_go//kubernetes/fake:go_default_library",
"@io_k8s_utils//pointer:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -1,372 +0,0 @@
/*
Copyright 2021 The cert-manager Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package ingress
import (
"unsafe"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
networkingv1beta1 "k8s.io/api/networking/v1beta1"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/util/intstr"
)
/*
This file contains copies of functions from k8s.io/kubernetes,
as we definitely don't want to import the entire of k8s. The code
is released under the following LICENSE:
*/
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Convert_networking_Ingress_To_v1beta1_Ingress uses unsafe pointer manipulation to manipulate a
// *networkingv1beta1.Ingress into pointing at the same underlying data as the input *networkingv1.Ingress.
// Both the `in` and `out` Object's data will be manipulated by this function.
//
// Recommended usage:
// // as in and out will point to the same data, make sure any manipulation doesn't affect the original Ingress
// in := myIngress.DeepCopy()
// out := new(networkingv1beta1.Ingress)
// err := Convert_networking_Ingress_To_v1beta1_Ingress(in, out, nil)
func Convert_networking_Ingress_To_v1beta1_Ingress(in *networkingv1.Ingress, out *networkingv1beta1.Ingress, s conversion.Scope) error {
err := autoConvert_networking_Ingress_To_v1beta1_Ingress(in, out, s)
if err != nil {
return err
}
// v1beta1 Ingresses should not have IngressClassName set but instead use the deprecated annotation.
// Move the ingress class to the annotations and then zero the IngressClassName field
if out.Spec.IngressClassName != nil {
if out.Annotations == nil {
out.Annotations = make(map[string]string)
}
out.Annotations["kubernetes.io/ingress.class"] = *out.Spec.IngressClassName
out.Spec.IngressClassName = nil
}
return nil
}
func autoConvert_networking_Ingress_To_v1beta1_Ingress(in *networkingv1.Ingress, out *networkingv1beta1.Ingress, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
if err := Convert_networking_IngressSpec_To_v1beta1_IngressSpec(&in.Spec, &out.Spec, s); err != nil {
return err
}
if err := Convert_networking_IngressStatus_To_v1beta1_IngressStatus(&in.Status, &out.Status, s); err != nil {
return err
}
return nil
}
func Convert_networking_IngressSpec_To_v1beta1_IngressSpec(in *networkingv1.IngressSpec, out *networkingv1beta1.IngressSpec, s conversion.Scope) error {
if err := autoConvert_networking_IngressSpec_To_v1beta1_IngressSpec(in, out, s); err != nil {
return nil
}
if in.DefaultBackend != nil {
out.Backend = &networkingv1beta1.IngressBackend{}
if err := Convert_networking_IngressBackend_To_v1beta1_IngressBackend(in.DefaultBackend, out.Backend, s); err != nil {
return err
}
}
return nil
}
func autoConvert_networking_IngressSpec_To_v1beta1_IngressSpec(in *networkingv1.IngressSpec, out *networkingv1beta1.IngressSpec, s conversion.Scope) error {
out.IngressClassName = (*string)(unsafe.Pointer(in.IngressClassName))
// WARNING: in.DefaultBackend requires manual conversion: does not exist in peer-type
out.TLS = *(*[]networkingv1beta1.IngressTLS)(unsafe.Pointer(&in.TLS))
if in.Rules != nil {
in, out := &in.Rules, &out.Rules
*out = make([]networkingv1beta1.IngressRule, len(*in))
for i := range *in {
if err := Convert_networking_IngressRule_To_v1beta1_IngressRule(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Rules = nil
}
return nil
}
func Convert_networking_IngressStatus_To_v1beta1_IngressStatus(in *networkingv1.IngressStatus, out *networkingv1beta1.IngressStatus, s conversion.Scope) error {
return autoConvert_networking_IngressStatus_To_v1beta1_IngressStatus(in, out, s)
}
func autoConvert_networking_IngressStatus_To_v1beta1_IngressStatus(in *networkingv1.IngressStatus, out *networkingv1beta1.IngressStatus, s conversion.Scope) error {
if err := Convert_core_LoadBalancerStatus_To_v1_LoadBalancerStatus(&in.LoadBalancer, &out.LoadBalancer, s); err != nil {
return err
}
return nil
}
func Convert_core_LoadBalancerStatus_To_v1_LoadBalancerStatus(in *corev1.LoadBalancerStatus, out *corev1.LoadBalancerStatus, s conversion.Scope) error {
return autoConvert_core_LoadBalancerStatus_To_v1_LoadBalancerStatus(in, out, s)
}
func autoConvert_core_LoadBalancerStatus_To_v1_LoadBalancerStatus(in *corev1.LoadBalancerStatus, out *corev1.LoadBalancerStatus, s conversion.Scope) error {
out.Ingress = *(*[]corev1.LoadBalancerIngress)(unsafe.Pointer(&in.Ingress))
return nil
}
func Convert_networking_IngressRule_To_v1beta1_IngressRule(in *networkingv1.IngressRule, out *networkingv1beta1.IngressRule, s conversion.Scope) error {
return autoConvert_networking_IngressRule_To_v1beta1_IngressRule(in, out, s)
}
func autoConvert_networking_IngressRule_To_v1beta1_IngressRule(in *networkingv1.IngressRule, out *networkingv1beta1.IngressRule, s conversion.Scope) error {
out.Host = in.Host
if err := Convert_networking_IngressRuleValue_To_v1beta1_IngressRuleValue(&in.IngressRuleValue, &out.IngressRuleValue, s); err != nil {
return err
}
return nil
}
func Convert_networking_IngressRuleValue_To_v1beta1_IngressRuleValue(in *networkingv1.IngressRuleValue, out *networkingv1beta1.IngressRuleValue, s conversion.Scope) error {
return autoConvert_networking_IngressRuleValue_To_v1beta1_IngressRuleValue(in, out, s)
}
func autoConvert_networking_IngressRuleValue_To_v1beta1_IngressRuleValue(in *networkingv1.IngressRuleValue, out *networkingv1beta1.IngressRuleValue, s conversion.Scope) error {
if in.HTTP != nil {
in, out := &in.HTTP, &out.HTTP
*out = new(networkingv1beta1.HTTPIngressRuleValue)
if err := Convert_networking_HTTPIngressRuleValue_To_v1beta1_HTTPIngressRuleValue(*in, *out, s); err != nil {
return err
}
} else {
out.HTTP = nil
}
return nil
}
func Convert_networking_HTTPIngressRuleValue_To_v1beta1_HTTPIngressRuleValue(in *networkingv1.HTTPIngressRuleValue, out *networkingv1beta1.HTTPIngressRuleValue, s conversion.Scope) error {
return autoConvert_networking_HTTPIngressRuleValue_To_v1beta1_HTTPIngressRuleValue(in, out, s)
}
func autoConvert_networking_HTTPIngressRuleValue_To_v1beta1_HTTPIngressRuleValue(in *networkingv1.HTTPIngressRuleValue, out *networkingv1beta1.HTTPIngressRuleValue, s conversion.Scope) error {
if in.Paths != nil {
in, out := &in.Paths, &out.Paths
*out = make([]networkingv1beta1.HTTPIngressPath, len(*in))
for i := range *in {
if err := Convert_networking_HTTPIngressPath_To_v1beta1_HTTPIngressPath(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Paths = nil
}
return nil
}
func Convert_networking_HTTPIngressPath_To_v1beta1_HTTPIngressPath(in *networkingv1.HTTPIngressPath, out *networkingv1beta1.HTTPIngressPath, s conversion.Scope) error {
return autoConvert_networking_HTTPIngressPath_To_v1beta1_HTTPIngressPath(in, out, s)
}
func autoConvert_networking_HTTPIngressPath_To_v1beta1_HTTPIngressPath(in *networkingv1.HTTPIngressPath, out *networkingv1beta1.HTTPIngressPath, s conversion.Scope) error {
out.Path = in.Path
out.PathType = (*networkingv1beta1.PathType)(unsafe.Pointer(in.PathType))
if err := Convert_networking_IngressBackend_To_v1beta1_IngressBackend(&in.Backend, &out.Backend, s); err != nil {
return err
}
return nil
}
func Convert_networking_IngressBackend_To_v1beta1_IngressBackend(in *networkingv1.IngressBackend, out *networkingv1beta1.IngressBackend, s conversion.Scope) error {
if err := autoConvert_networking_IngressBackend_To_v1beta1_IngressBackend(in, out, s); err != nil {
return err
}
if in.Service != nil {
out.ServiceName = in.Service.Name
if len(in.Service.Port.Name) > 0 {
out.ServicePort = intstr.FromString(in.Service.Port.Name)
} else {
out.ServicePort = intstr.FromInt(int(in.Service.Port.Number))
}
}
return nil
}
func autoConvert_networking_IngressBackend_To_v1beta1_IngressBackend(in *networkingv1.IngressBackend, out *networkingv1beta1.IngressBackend, s conversion.Scope) error {
// WARNING: in.Service requires manual conversion: does not exist in peer-type
out.Resource = (*corev1.TypedLocalObjectReference)(unsafe.Pointer(in.Resource))
return nil
}
// Convert_v1beta1_Ingress_To_networking_Ingress uses unsafe pointer manipulation to manipulate a
// *networkingv1.Ingress into pointing at the same underlying data as the input *networkingv1beta1.Ingress.
// Both the `in` and `out` Object's data will be manipulated by this function.
//
// Recommended usage:
// // as in and out will point to the same data, make sure any manipulation doesn't affect the original Ingress
// in := myIngress.DeepCopy()
// out := new(networkingv1.Ingress)
// err := Convert_v1beta1_Ingress_To_networking_Ingress(in, out, nil)
func Convert_v1beta1_Ingress_To_networking_Ingress(in *networkingv1beta1.Ingress, out *networkingv1.Ingress, s conversion.Scope) error {
return autoConvert_v1beta1_Ingress_To_networking_Ingress(in, out, s)
}
func autoConvert_v1beta1_Ingress_To_networking_Ingress(in *networkingv1beta1.Ingress, out *networkingv1.Ingress, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
if err := Convert_v1beta1_IngressSpec_To_networking_IngressSpec(&in.Spec, &out.Spec, s); err != nil {
return err
}
if err := Convert_v1beta1_IngressStatus_To_networking_IngressStatus(&in.Status, &out.Status, s); err != nil {
return err
}
return nil
}
func Convert_v1beta1_IngressSpec_To_networking_IngressSpec(in *networkingv1beta1.IngressSpec, out *networkingv1.IngressSpec, s conversion.Scope) error {
if err := autoConvert_v1beta1_IngressSpec_To_networking_IngressSpec(in, out, s); err != nil {
return nil
}
if in.Backend != nil {
out.DefaultBackend = &networkingv1.IngressBackend{}
if err := Convert_v1beta1_IngressBackend_To_networking_IngressBackend(in.Backend, out.DefaultBackend, s); err != nil {
return err
}
}
return nil
}
func autoConvert_v1beta1_IngressSpec_To_networking_IngressSpec(in *networkingv1beta1.IngressSpec, out *networkingv1.IngressSpec, s conversion.Scope) error {
out.IngressClassName = (*string)(unsafe.Pointer(in.IngressClassName))
// WARNING: in.Backend requires manual conversion: does not exist in peer-type
out.TLS = *(*[]networkingv1.IngressTLS)(unsafe.Pointer(&in.TLS))
if in.Rules != nil {
in, out := &in.Rules, &out.Rules
*out = make([]networkingv1.IngressRule, len(*in))
for i := range *in {
if err := Convert_v1beta1_IngressRule_To_networking_IngressRule(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Rules = nil
}
return nil
}
func Convert_v1beta1_IngressStatus_To_networking_IngressStatus(in *networkingv1beta1.IngressStatus, out *networkingv1.IngressStatus, s conversion.Scope) error {
return autoConvert_v1beta1_IngressStatus_To_networking_IngressStatus(in, out, s)
}
func autoConvert_v1beta1_IngressStatus_To_networking_IngressStatus(in *networkingv1beta1.IngressStatus, out *networkingv1.IngressStatus, s conversion.Scope) error {
if err := Convert_v1_LoadBalancerStatus_To_core_LoadBalancerStatus(&in.LoadBalancer, &out.LoadBalancer, s); err != nil {
return err
}
return nil
}
func Convert_v1_LoadBalancerStatus_To_core_LoadBalancerStatus(in *corev1.LoadBalancerStatus, out *corev1.LoadBalancerStatus, s conversion.Scope) error {
return autoConvert_v1_LoadBalancerStatus_To_core_LoadBalancerStatus(in, out, s)
}
func autoConvert_v1_LoadBalancerStatus_To_core_LoadBalancerStatus(in *corev1.LoadBalancerStatus, out *corev1.LoadBalancerStatus, s conversion.Scope) error {
out.Ingress = *(*[]corev1.LoadBalancerIngress)(unsafe.Pointer(&in.Ingress))
return nil
}
func Convert_v1beta1_IngressRule_To_networking_IngressRule(in *networkingv1beta1.IngressRule, out *networkingv1.IngressRule, s conversion.Scope) error {
return autoConvert_v1beta1_IngressRule_To_networking_IngressRule(in, out, s)
}
func autoConvert_v1beta1_IngressRule_To_networking_IngressRule(in *networkingv1beta1.IngressRule, out *networkingv1.IngressRule, s conversion.Scope) error {
out.Host = in.Host
if err := Convert_v1beta1_IngressRuleValue_To_networking_IngressRuleValue(&in.IngressRuleValue, &out.IngressRuleValue, s); err != nil {
return err
}
return nil
}
func Convert_v1beta1_IngressRuleValue_To_networking_IngressRuleValue(in *networkingv1beta1.IngressRuleValue, out *networkingv1.IngressRuleValue, s conversion.Scope) error {
return autoConvert_v1beta1_IngressRuleValue_To_networking_IngressRuleValue(in, out, s)
}
func autoConvert_v1beta1_IngressRuleValue_To_networking_IngressRuleValue(in *networkingv1beta1.IngressRuleValue, out *networkingv1.IngressRuleValue, s conversion.Scope) error {
if in.HTTP != nil {
in, out := &in.HTTP, &out.HTTP
*out = new(networkingv1.HTTPIngressRuleValue)
if err := Convert_v1beta1_HTTPIngressRuleValue_To_networking_HTTPIngressRuleValue(*in, *out, s); err != nil {
return err
}
} else {
out.HTTP = nil
}
return nil
}
func Convert_v1beta1_HTTPIngressRuleValue_To_networking_HTTPIngressRuleValue(in *networkingv1beta1.HTTPIngressRuleValue, out *networkingv1.HTTPIngressRuleValue, s conversion.Scope) error {
return autoConvert_v1beta1_HTTPIngressRuleValue_To_networking_HTTPIngressRuleValue(in, out, s)
}
func autoConvert_v1beta1_HTTPIngressRuleValue_To_networking_HTTPIngressRuleValue(in *networkingv1beta1.HTTPIngressRuleValue, out *networkingv1.HTTPIngressRuleValue, s conversion.Scope) error {
if in.Paths != nil {
in, out := &in.Paths, &out.Paths
*out = make([]networkingv1.HTTPIngressPath, len(*in))
for i := range *in {
if err := Convert_v1beta1_HTTPIngressPath_To_networking_HTTPIngressPath(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Paths = nil
}
return nil
}
func Convert_v1beta1_HTTPIngressPath_To_networking_HTTPIngressPath(in *networkingv1beta1.HTTPIngressPath, out *networkingv1.HTTPIngressPath, s conversion.Scope) error {
return autoConvert_v1beta1_HTTPIngressPath_To_networking_HTTPIngressPath(in, out, s)
}
func autoConvert_v1beta1_HTTPIngressPath_To_networking_HTTPIngressPath(in *networkingv1beta1.HTTPIngressPath, out *networkingv1.HTTPIngressPath, s conversion.Scope) error {
out.Path = in.Path
out.PathType = (*networkingv1.PathType)(unsafe.Pointer(in.PathType))
if err := Convert_v1beta1_IngressBackend_To_networking_IngressBackend(&in.Backend, &out.Backend, s); err != nil {
return err
}
return nil
}
func Convert_v1beta1_IngressBackend_To_networking_IngressBackend(in *networkingv1beta1.IngressBackend, out *networkingv1.IngressBackend, s conversion.Scope) error {
if err := autoConvert_v1beta1_IngressBackend_To_networking_IngressBackend(in, out, s); err != nil {
return err
}
if len(in.ServiceName) > 0 || in.ServicePort.IntVal != 0 || in.ServicePort.StrVal != "" || in.ServicePort.Type == intstr.String {
out.Service = &networkingv1.IngressServiceBackend{}
out.Service.Name = in.ServiceName
out.Service.Port.Name = in.ServicePort.StrVal
out.Service.Port.Number = in.ServicePort.IntVal
}
return nil
}
func autoConvert_v1beta1_IngressBackend_To_networking_IngressBackend(in *networkingv1beta1.IngressBackend, out *networkingv1.IngressBackend, s conversion.Scope) error {
// WARNING: in.ServiceName requires manual conversion: does not exist in peer-type
// WARNING: in.ServicePort requires manual conversion: does not exist in peer-type
out.Resource = (*corev1.TypedLocalObjectReference)(unsafe.Pointer(in.Resource))
return nil
}

View File

@ -1,261 +0,0 @@
/*
Copyright 2021 The cert-manager Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package ingress
import (
"regexp"
"testing"
fuzz "github.com/google/gofuzz"
"github.com/stretchr/testify/assert"
networkingv1 "k8s.io/api/networking/v1"
networkingv1beta1 "k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/utils/pointer"
)
var v1TestIngress = &networkingv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: "test-networkingv1-ingress",
Namespace: "test-networkingv1-namespace",
Annotations: map[string]string{
"test.key": "test.value",
"kubernetes.io/ingress.class": "bogus-ingress-class",
},
Labels: map[string]string{
"labelkey": "labelvalue",
},
},
Spec: networkingv1.IngressSpec{
// As discussed in https://github.com/cert-manager/cert-manager/issues/4537
// the IngressClassName field is not directly equivalent to the
// kubernetes.io/ingress.class annotation. According to the Ingress graduation KEP:
// https://github.com/kubernetes/enhancements/blob/master/keps/sig-network/758-ingress-api-group/README.md
// the annotation, if present, overrides this field.
//
// As the goal of cert-manager is to be as widely compatible as possible, we can only use the
// annotation to describe an ingress class.
IngressClassName: nil,
DefaultBackend: &networkingv1.IngressBackend{
Service: &networkingv1.IngressServiceBackend{
Name: "default-backend-svc",
Port: networkingv1.ServiceBackendPort{
Number: 1234,
},
},
},
TLS: []networkingv1.IngressTLS{
{
Hosts: []string{"aaa.", "bbb.", "ccc.ddd"},
SecretName: "test-secret-1",
},
{
Hosts: []string{"eee"},
SecretName: "test-secret-2",
},
},
Rules: []networkingv1.IngressRule{
{
Host: "aaa",
IngressRuleValue: networkingv1.IngressRuleValue{
HTTP: &networkingv1.HTTPIngressRuleValue{
Paths: []networkingv1.HTTPIngressPath{
{
Path: "/.well-known/acme-challenge",
PathType: func() *networkingv1.PathType { p := networkingv1.PathTypeImplementationSpecific; return &p }(),
Backend: networkingv1.IngressBackend{
Service: &networkingv1.IngressServiceBackend{
Name: "test-solver-backend",
Port: networkingv1.ServiceBackendPort{Number: 80},
},
},
},
},
},
},
},
},
},
}
var v1beta1TestIngress = &networkingv1beta1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: "test-networkingv1-ingress",
Namespace: "test-networkingv1-namespace",
Annotations: map[string]string{
"test.key": "test.value",
"kubernetes.io/ingress.class": "bogus-ingress-class",
},
Labels: map[string]string{
"labelkey": "labelvalue",
},
},
Spec: networkingv1beta1.IngressSpec{
Backend: &networkingv1beta1.IngressBackend{
ServiceName: "default-backend-svc",
ServicePort: intstr.IntOrString{
Type: intstr.Int,
IntVal: 1234,
},
},
Rules: []networkingv1beta1.IngressRule{
{
Host: "aaa",
IngressRuleValue: networkingv1beta1.IngressRuleValue{
HTTP: &networkingv1beta1.HTTPIngressRuleValue{
Paths: []networkingv1beta1.HTTPIngressPath{
{
Path: "/.well-known/acme-challenge",
PathType: func() *networkingv1beta1.PathType { p := networkingv1beta1.PathTypeImplementationSpecific; return &p }(),
Backend: networkingv1beta1.IngressBackend{
ServiceName: "test-solver-backend",
ServicePort: intstr.IntOrString{
Type: intstr.Int,
IntVal: 80,
},
},
},
},
},
},
},
},
TLS: []networkingv1beta1.IngressTLS{
{
Hosts: []string{"aaa.", "bbb.", "ccc.ddd"},
SecretName: "test-secret-1",
},
{
Hosts: []string{"eee"},
SecretName: "test-secret-2",
},
},
},
Status: networkingv1beta1.IngressStatus{},
}
func TestConvert_networking_Ingress_To_v1beta1_Ingress(t *testing.T) {
tests := map[string]func(t *testing.T){
"convert networkingv1 Ingresss to networkingv1beta1 Ingress": func(t *testing.T) {
in := v1TestIngress.DeepCopy()
out := new(networkingv1beta1.Ingress)
err := Convert_networking_Ingress_To_v1beta1_Ingress(in, out, nil)
assert.NoError(t, err, "conversion should not fail")
expected := v1beta1TestIngress.DeepCopy()
assert.Equal(t, expected, out, "conversion was not as expected")
},
"mutation side effects": func(t *testing.T) {
in := v1TestIngress.DeepCopy()
out := &networkingv1beta1.Ingress{}
err := Convert_networking_Ingress_To_v1beta1_Ingress(in, out, nil)
assert.NoError(t, err, "conversion should not fail")
expected := v1beta1TestIngress.DeepCopy()
assert.Equal(t, expected, out, "conversion was not as expected")
// as the convert functions use unsafe.Pointer to make out point to the same
// underlying data as in, in should end up mutated. This test ensures if
// a future maintainer touches this code they understand the side effects
assert.Equal(t, in.Annotations, out.Annotations, "conversion did not have expected side effects: annotations differ")
},
"ingress without annotations ends up with annotations": func(t *testing.T) {
in := &networkingv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: "name",
Namespace: "namespaces",
},
Spec: networkingv1.IngressSpec{
IngressClassName: pointer.String("some-class"),
},
}
out := new(networkingv1beta1.Ingress)
err := Convert_networking_Ingress_To_v1beta1_Ingress(in, out, nil)
assert.NoError(t, err, "conversion should not fail")
expected := &networkingv1beta1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: "name",
Namespace: "namespaces",
Annotations: map[string]string{
"kubernetes.io/ingress.class": "some-class",
},
},
}
assert.Equal(t, expected, out, "conversion was not as expected")
},
"v1 -> v1beta1 -> v1 round trip preserves fields": func(t *testing.T) {
// Something mentioned in a previous code review is we should make sure we do not
// remove fields during conversion. There may be a better way of doing this, but this
// test will fill every field with a fuzzer and perform a conversion round trip.
base := new(networkingv1.Ingress)
f := fuzz.New().
// Filling both the port name and port number is invalid so skip the number for now
// (the fuzzer will put some negative ports in as well).
SkipFieldsWithPattern(regexp.MustCompile("Number")).
// The IngressClassNameLogic is tested below
SkipFieldsWithPattern(regexp.MustCompile("IngressClassName"))
f.Fuzz(base)
in := base.DeepCopy()
expected := in.DeepCopy()
intermediate := new(networkingv1beta1.Ingress)
out := new(networkingv1.Ingress)
err := Convert_networking_Ingress_To_v1beta1_Ingress(in, intermediate, nil)
assert.NoError(t, err, "conversion from v1 to v1beta1 should not fail")
err = Convert_v1beta1_Ingress_To_networking_Ingress(intermediate.DeepCopy(), out, nil)
assert.NoError(t, err, "conversion from v1beta1 to v1 should not fail")
assert.Equal(t, expected.Spec, out.Spec, "output Spec was not equal to input Spec after round trip")
},
}
for name, test := range tests {
t.Run(name, test)
}
}
func TestConvert_v1beta1_Ingress_To_networking_Ingress(t *testing.T) {
tests := map[string]func(t *testing.T){
"convert networkingv1beta1 Ingresss to networkingv1 Ingress": func(t *testing.T) {
in := v1beta1TestIngress.DeepCopy()
out := new(networkingv1.Ingress)
err := Convert_v1beta1_Ingress_To_networking_Ingress(in, out, nil)
assert.NoError(t, err, "conversion should not fail")
expected := v1TestIngress.DeepCopy()
assert.Equal(t, expected, out, "conversion was not as expected")
},
"conversion with no ingress class annotation works": func(t *testing.T) {
in := v1beta1TestIngress.DeepCopy()
out := new(networkingv1.Ingress)
delete(in.Annotations, "kubernetes.io/ingress.class")
err := Convert_v1beta1_Ingress_To_networking_Ingress(in, out, nil)
assert.NoError(t, err, "conversion should not fail")
assert.Nil(t, out.Spec.IngressClassName, "ingress class should not be set on output")
},
"mutation side effects": func(t *testing.T) {
// as the convert functions use unsafe.Pointer to make out point to the same
// underlying data as in, in should end up mutated. This test ensures if
// a future maintainer touches this code they understand the side effects
in := v1beta1TestIngress.DeepCopy()
out := new(networkingv1.Ingress)
err := Convert_v1beta1_Ingress_To_networking_Ingress(in, out, nil)
assert.NoError(t, err, "conversion should not fail")
assert.Equal(t, in.Annotations, out.Annotations, "conversion did not have expected side effects: annotations differ")
},
}
for name, test := range tests {
t.Run(name, test)
}
}

View File

@ -1,157 +0,0 @@
/*
Copyright 2021 The cert-manager Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package ingress lets us use an internal type for supporting multiple kinds of ingresses.
//
// This package's sole reason for existence is for compatibility with Kubernetes API servers
// below v1.18. However, our client-go library is already beyond the supported version skew
// (https://kubernetes.io/releases/version-skew-policy/) so it is not guaranteed to continue
// working in the future, and will definitely be removed once cert-manager no longer supports
// Kubernetes 1.17.
package ingress
import (
"context"
"fmt"
"sync"
"sync/atomic"
networkingv1 "k8s.io/api/networking/v1"
networkingv1beta1 "k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/discovery"
"k8s.io/client-go/tools/cache"
"github.com/cert-manager/cert-manager/pkg/controller"
)
// keep an internal cache of known API types so calls to the discovery API are kept to a minimum
// https://pkg.go.dev/sync/atomic#example-Value-ReadMostly
var (
knownAPIVersionCache atomic.Value
cacheLock sync.Mutex
)
// InternalIngressCreateUpdater mimics a client-go networking/v1 or
// networking/v1beta1 Interface.
type InternalIngressCreateUpdater interface {
Ingresses(namespace string) InternalIngressInterface
}
// InternalIngressInterface mimics a client-go networking/v1/IngressInterface
// It always returns a *networkingv1.Ingress, so when implementing this you must convert any type of
// Ingress into a v1.Ingress.
type InternalIngressInterface interface {
Create(ctx context.Context, ingress *networkingv1.Ingress, opts metav1.CreateOptions) (*networkingv1.Ingress, error)
Update(ctx context.Context, ingress *networkingv1.Ingress, opts metav1.UpdateOptions) (*networkingv1.Ingress, error)
Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error
Get(ctx context.Context, name string, opts metav1.GetOptions) (*networkingv1.Ingress, error)
}
// InternalIngressLister mimics a client-go networking/v1/IngressLister.
type InternalIngressLister interface {
List(selector labels.Selector) (ret []*networkingv1.Ingress, err error)
Ingresses(namespace string) InternalIngressNamespaceLister
}
// InternalIngressNamespaceLister mimics a client-go networking/v1/IngressNamespaceLister
type InternalIngressNamespaceLister interface {
List(selector labels.Selector) (ret []*networkingv1.Ingress, err error)
Get(name string) (*networkingv1.Ingress, error)
}
// NewListerInformer returns an InternalIngressLister configured for v1 or v1beta1 ingresses depending on the
// API Versions available in the discovery client.
func NewListerInformer(ctx *controller.Context) (InternalIngressLister, cache.SharedIndexInformer, error) {
switch {
case hasVersion(ctx.DiscoveryClient, networkingv1.SchemeGroupVersion.String()):
return &v1Lister{
lister: ctx.KubeSharedInformerFactory.Networking().V1().Ingresses().Lister(),
},
ctx.KubeSharedInformerFactory.Networking().V1().Ingresses().Informer(),
nil
case hasVersion(ctx.DiscoveryClient, networkingv1beta1.SchemeGroupVersion.String()):
return &v1beta1Lister{
lister: ctx.KubeSharedInformerFactory.Networking().V1beta1().Ingresses().Lister(),
},
ctx.KubeSharedInformerFactory.Networking().V1beta1().Ingresses().Informer(),
nil
default:
return nil, nil, fmt.Errorf("neither %s nor %s have any APIResources", networkingv1.SchemeGroupVersion, networkingv1beta1.SchemeGroupVersion)
}
}
// NewCreateUpdater returns an InternalIngressCreateUpdater configured for v1 or v1beta1 ingresses depending on the
// versions available in the discovery client
func NewCreateUpdater(ctx *controller.Context) (InternalIngressCreateUpdater, error) {
if hasVersion(ctx.DiscoveryClient, networkingv1.SchemeGroupVersion.String()) {
return &v1CreaterUpdater{
client: ctx.Client,
}, nil
} else if hasVersion(ctx.DiscoveryClient, networkingv1beta1.SchemeGroupVersion.String()) {
return &v1beta1CreaterUpdater{
client: ctx.Client,
}, nil
} else {
return nil, fmt.Errorf("neither %s nor %s have any APIResources", networkingv1.SchemeGroupVersion, networkingv1beta1.SchemeGroupVersion)
}
}
func hasVersion(d discovery.DiscoveryInterface, GroupVersion string) bool {
// check whether the GroupVersion is already known
knownVersions := knownAPIVersionCache.Load().(map[string]bool)
knownVersion, found := knownVersions[GroupVersion]
if found {
return knownVersion
}
resourceList, err := d.ServerResourcesForGroupVersion(GroupVersion)
if err != nil {
return false
}
for _, r := range resourceList.APIResources {
if r.Kind == "Ingress" {
// Now we know the APIServer supports this GroupVersion, store the result atomically
// in the knownVersions cache. Lock, get the latest copy, atomically update.
cacheLock.Lock()
oldCache := knownAPIVersionCache.Load().(map[string]bool)
newCache := make(map[string]bool)
for k, v := range oldCache {
newCache[k] = v
}
newCache[GroupVersion] = true
knownAPIVersionCache.Store(newCache)
cacheLock.Unlock()
return true
}
}
// no networking error and no Ingresses found in networking.k8s.io/<version>, cache negative result
cacheLock.Lock()
oldCache := knownAPIVersionCache.Load().(map[string]bool)
newCache := make(map[string]bool)
for k, v := range oldCache {
newCache[k] = v
}
newCache[GroupVersion] = false
knownAPIVersionCache.Store(newCache)
cacheLock.Unlock()
return false
}
func init() {
knownAPIVersionCache.Store(make(map[string]bool))
}

View File

@ -1,233 +0,0 @@
/*
Copyright 2021 The cert-manager Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package ingress
import (
"context"
"fmt"
"testing"
"time"
"github.com/stretchr/testify/assert"
networkingv1 "k8s.io/api/networking/v1"
networkingv1beta1 "k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/informers"
kubefake "k8s.io/client-go/kubernetes/fake"
"k8s.io/utils/pointer"
"github.com/cert-manager/cert-manager/pkg/controller"
discoveryfake "github.com/cert-manager/cert-manager/test/unit/discovery"
)
// Important: these tests cannot run in parallel as the cache holds internal state at the package level.
func TestFunctionalityAgainstV1(t *testing.T) {
// wipe known versions cache
cacheLock.Lock()
knownAPIVersionCache.Store(make(map[string]bool))
cacheLock.Unlock()
fakeClient := kubefake.NewSimpleClientset()
v1ctx := &controller.Context{
RootContext: context.TODO(),
Client: fakeClient,
DiscoveryClient: fakeDiscoveryFor(networkingv1.SchemeGroupVersion),
KubeSharedInformerFactory: informers.NewSharedInformerFactory(fakeClient, 10*time.Hour),
}
ch := make(chan struct{})
v1ctx.KubeSharedInformerFactory.Start(ch)
errs := testFunctionality(t, v1ctx)
assert.Len(t, errs, 0, "InternalIngress should not fail on an API server that supports networking.k8s.io/v1")
close(ch)
}
func TestFunctionalityAgainstV1Beta1(t *testing.T) {
cacheLock.Lock()
knownAPIVersionCache.Store(make(map[string]bool))
cacheLock.Unlock()
fakeClient := kubefake.NewSimpleClientset()
v1beta1ctx := &controller.Context{
RootContext: context.TODO(),
Client: fakeClient,
DiscoveryClient: fakeDiscoveryFor(networkingv1beta1.SchemeGroupVersion),
KubeSharedInformerFactory: informers.NewSharedInformerFactory(fakeClient, 10*time.Hour),
}
ch := make(chan struct{})
v1beta1ctx.KubeSharedInformerFactory.Start(ch)
errs := testFunctionality(t, v1beta1ctx)
assert.Len(t, errs, 0, "InternalIngress should not fail on an API server that supports networking.k8s.io/v1beta1")
close(ch)
}
func TestFunctionalityAgainstNone(t *testing.T) {
// wipe known versions cache
cacheLock.Lock()
knownAPIVersionCache.Store(make(map[string]bool))
cacheLock.Unlock()
fakeClient := kubefake.NewSimpleClientset()
noneCtx := &controller.Context{
RootContext: context.TODO(),
Client: fakeClient,
DiscoveryClient: uselessDiscovery(),
KubeSharedInformerFactory: informers.NewSharedInformerFactory(fakeClient, 10*time.Hour),
}
_, _, err := NewListerInformer(noneCtx)
if assert.Error(t, err) {
assert.Equal(
t,
fmt.Errorf("neither %s nor %s have any APIResources", networkingv1.SchemeGroupVersion, networkingv1beta1.SchemeGroupVersion),
err,
)
}
}
func fakeDiscoveryFor(version schema.GroupVersion) *discoveryfake.Discovery {
return discoveryfake.NewDiscovery().WithServerResourcesForGroupVersion(func(groupVersion string) (*metav1.APIResourceList, error) {
if groupVersion == version.String() {
return &metav1.APIResourceList{
TypeMeta: metav1.TypeMeta{},
GroupVersion: version.String(),
APIResources: []metav1.APIResource{
{
Name: "ingresses",
SingularName: "Ingress",
Namespaced: true,
Group: version.Group,
Version: version.Version,
Kind: version.WithKind("Ingress").Kind,
Verbs: metav1.Verbs{"get", "list", "watch", "create", "update", "patch", "delete", "deletecollection"},
ShortNames: []string{"ing"},
Categories: []string{"all"},
StorageVersionHash: "testing",
},
},
}, nil
} else {
return &metav1.APIResourceList{}, nil
}
})
}
func uselessDiscovery() *discoveryfake.Discovery {
return discoveryfake.NewDiscovery().
WithServerResourcesForGroupVersion(
func(groupVersion string) (*metav1.APIResourceList, error) {
return &metav1.APIResourceList{}, nil
},
)
}
func testFunctionality(t *testing.T, ctx *controller.Context) []error {
var ret []error
lister, _, err := NewListerInformer(ctx)
assert.NoError(t, err, "New ListerInformer should not fail")
if err != nil {
ret = append(ret, err)
}
createUpdater, err := NewCreateUpdater(ctx)
assert.NoError(t, err, "New CreateUpdater should not fail")
if err != nil {
ret = append(ret, err)
}
_, err = createUpdater.Ingresses("default").Create(context.TODO(), &networkingv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "default",
},
Spec: networkingv1.IngressSpec{
IngressClassName: pointer.StringPtr("test1"),
Rules: []networkingv1.IngressRule{
{
Host: "test",
IngressRuleValue: networkingv1.IngressRuleValue{
HTTP: &networkingv1.HTTPIngressRuleValue{
Paths: []networkingv1.HTTPIngressPath{
{
Path: "/",
PathType: func() *networkingv1.PathType { s := networkingv1.PathTypePrefix; return &s }(),
Backend: networkingv1.IngressBackend{
Service: &networkingv1.IngressServiceBackend{
Name: "test",
Port: networkingv1.ServiceBackendPort{
Number: 80,
},
},
},
},
},
},
},
},
},
},
}, metav1.CreateOptions{})
assert.NoError(t, err, "Create should not fail")
if err != nil {
ret = append(ret, err)
}
_, err = createUpdater.Ingresses("default").Update(context.TODO(), &networkingv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "default",
},
Spec: networkingv1.IngressSpec{
IngressClassName: pointer.StringPtr("test1"),
Rules: []networkingv1.IngressRule{
{
Host: "test",
IngressRuleValue: networkingv1.IngressRuleValue{
HTTP: &networkingv1.HTTPIngressRuleValue{
Paths: []networkingv1.HTTPIngressPath{
{
Path: "/",
PathType: func() *networkingv1.PathType { s := networkingv1.PathTypePrefix; return &s }(),
Backend: networkingv1.IngressBackend{
Service: &networkingv1.IngressServiceBackend{
Name: "test",
Port: networkingv1.ServiceBackendPort{
Number: 80,
},
},
},
},
},
},
},
},
},
},
}, metav1.UpdateOptions{})
assert.NoError(t, err, "Update should not fail")
if err != nil {
ret = append(ret, err)
}
_, err = lister.List(labels.Everything())
assert.NoError(t, err, "List should not fail")
err = createUpdater.Ingresses("default").Delete(context.TODO(), "test", metav1.DeleteOptions{})
assert.NoError(t, err, "delete should not fail")
if err != nil {
ret = append(ret, err)
}
return ret
}

View File

@ -1,83 +0,0 @@
/*
Copyright 2021 The cert-manager Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package ingress
import (
"context"
networkingv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"
listersv1 "k8s.io/client-go/listers/networking/v1"
)
type v1Lister struct {
lister listersv1.IngressLister
}
type v1NamespaceLister struct {
nsLister listersv1.IngressNamespaceLister
}
func (l *v1Lister) List(selector labels.Selector) ([]*networkingv1.Ingress, error) {
return l.lister.List(selector)
}
func (l *v1Lister) Ingresses(namespace string) InternalIngressNamespaceLister {
return &v1NamespaceLister{nsLister: l.lister.Ingresses(namespace)}
}
func (nl *v1NamespaceLister) List(selector labels.Selector) ([]*networkingv1.Ingress, error) {
return nl.nsLister.List(selector)
}
func (nl *v1NamespaceLister) Get(name string) (*networkingv1.Ingress, error) {
return nl.nsLister.Get(name)
}
type v1CreaterUpdater struct {
client kubernetes.Interface
}
func (v1 *v1CreaterUpdater) Ingresses(namespace string) InternalIngressInterface {
return &v1Interface{
client: v1.client,
ns: namespace,
}
}
type v1Interface struct {
client kubernetes.Interface
ns string
}
func (v1 *v1Interface) Get(ctx context.Context, name string, opts metav1.GetOptions) (*networkingv1.Ingress, error) {
return v1.client.NetworkingV1().Ingresses(v1.ns).Get(ctx, name, opts)
}
func (v1 *v1Interface) Create(ctx context.Context, ingress *networkingv1.Ingress, opts metav1.CreateOptions) (*networkingv1.Ingress, error) {
return v1.client.NetworkingV1().Ingresses(v1.ns).Create(ctx, ingress, opts)
}
func (v1 *v1Interface) Update(ctx context.Context, ingress *networkingv1.Ingress, opts metav1.UpdateOptions) (*networkingv1.Ingress, error) {
return v1.client.NetworkingV1().Ingresses(v1.ns).Update(ctx, ingress, opts)
}
func (v1 *v1Interface) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
return v1.client.NetworkingV1().Ingresses(v1.ns).Delete(ctx, name, opts)
}

View File

@ -1,182 +0,0 @@
/*
Copyright 2021 The cert-manager Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package ingress
import (
"context"
"fmt"
networkingv1 "k8s.io/api/networking/v1"
networkingv1beta1 "k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"
listersv1beta1 "k8s.io/client-go/listers/networking/v1beta1"
)
// ConvertedGVKAnnotation is the annotation key set by cert-manager on Ingress
// resources converted from networking.k8s.io/v1beta1 to networking.k8s.io/v1
//
// On Kubernetes 1.16, 1.17, and 1.18, the `networking.k8s.io/v1` API did not exist yet.
// For these Kubernetes versions, cert-manager converts `networking.k8s.io/v1beta1`
// into `networking.k8s.io/v1`, which is the one version used across cert-manager.
//
// But this conversion means that we lose the "original" apiVersion, which is needed
// by the ingress-shim sync function to set the correct `ownerReference` on the
// Certificate it creates.
//
// This annotation is only set on Ingresses on Kubernetes 1.16, 1.17, and 1.18.
const ConvertedGVKAnnotation = `internal.cert-manager.io/converted-gvk`
type v1beta1Lister struct {
lister listersv1beta1.IngressLister
}
type v1beta1NamespaceLister struct {
nsLister listersv1beta1.IngressNamespaceLister
}
func (l *v1beta1Lister) List(selector labels.Selector) ([]*networkingv1.Ingress, error) {
all, err := l.lister.List(selector)
if err != nil {
return nil, err
}
return convertV1Beta1ListToV1(all)
}
func (l *v1beta1Lister) Ingresses(namespace string) InternalIngressNamespaceLister {
return &v1beta1NamespaceLister{
nsLister: l.lister.Ingresses(namespace),
}
}
func (nl *v1beta1NamespaceLister) List(selector labels.Selector) ([]*networkingv1.Ingress, error) {
all, err := nl.nsLister.List(selector)
if err != nil {
return nil, err
}
return convertV1Beta1ListToV1(all)
}
func (nl *v1beta1NamespaceLister) Get(name string) (*networkingv1.Ingress, error) {
ing, err := nl.nsLister.Get(name)
if err != nil {
return nil, err
}
return convertV1Beta1ToV1(ing)
}
func convertV1Beta1ListToV1(list []*networkingv1beta1.Ingress) ([]*networkingv1.Ingress, error) {
var ret []*networkingv1.Ingress
for _, in := range list {
out, err := convertV1Beta1ToV1(in)
if err != nil {
return nil, err
}
ret = append(ret, out)
}
return ret, nil
}
func convertV1Beta1ToV1(in *networkingv1beta1.Ingress) (*networkingv1.Ingress, error) {
out := new(networkingv1.Ingress)
err := Convert_v1beta1_Ingress_To_networking_Ingress(in.DeepCopy(), out, nil)
if err != nil {
return nil, fmt.Errorf(
"could not convert %s to %s when processing object %s/%s: %w",
networkingv1beta1.SchemeGroupVersion,
networkingv1.SchemeGroupVersion,
in.Namespace,
in.Name,
err,
)
}
if out.Annotations == nil {
out.Annotations = make(map[string]string)
}
out.Annotations[ConvertedGVKAnnotation] = networkingv1beta1.SchemeGroupVersion.WithKind("Ingress").String()
return out, nil
}
func convertV1ToV1Beta1(in *networkingv1.Ingress) (*networkingv1beta1.Ingress, error) {
out := new(networkingv1beta1.Ingress)
err := Convert_networking_Ingress_To_v1beta1_Ingress(in.DeepCopy(), out, nil)
if err != nil {
return nil, fmt.Errorf(
"could not convert %s to %s when processing object %s/%s: %w",
networkingv1.SchemeGroupVersion,
networkingv1beta1.SchemeGroupVersion,
in.Namespace,
in.Name,
err,
)
}
return out, nil
}
type v1beta1CreaterUpdater struct {
client kubernetes.Interface
}
func (v *v1beta1CreaterUpdater) Ingresses(namespace string) InternalIngressInterface {
return &v1beta1Interface{
client: v.client,
ns: namespace,
}
}
type v1beta1Interface struct {
client kubernetes.Interface
ns string
}
func (v *v1beta1Interface) Get(ctx context.Context, name string, opts metav1.GetOptions) (*networkingv1.Ingress, error) {
ing, err := v.client.NetworkingV1beta1().Ingresses(v.ns).Get(ctx, name, opts)
if err != nil {
return nil, err
}
return convertV1Beta1ToV1(ing)
}
func (v *v1beta1Interface) Create(ctx context.Context, ingress *networkingv1.Ingress, opts metav1.CreateOptions) (*networkingv1.Ingress, error) {
ing, err := convertV1ToV1Beta1(ingress)
if err != nil {
return nil, err
}
newIng, err := v.client.NetworkingV1beta1().Ingresses(v.ns).Create(ctx, ing, opts)
if err != nil {
return nil, err
}
return convertV1Beta1ToV1(newIng)
}
func (v *v1beta1Interface) Update(ctx context.Context, ingress *networkingv1.Ingress, opts metav1.UpdateOptions) (*networkingv1.Ingress, error) {
ing, err := convertV1ToV1Beta1(ingress)
if err != nil {
return nil, err
}
newIng, err := v.client.NetworkingV1beta1().Ingresses(v.ns).Update(ctx, ing, opts)
if err != nil {
return nil, err
}
return convertV1Beta1ToV1(newIng)
}
func (v *v1beta1Interface) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
return v.client.NetworkingV1beta1().Ingresses(v.ns).Delete(ctx, name, opts)
}

View File

@ -14,7 +14,6 @@ go_library(
deps = [
"//internal/controller/challenges:go_default_library",
"//internal/controller/feature:go_default_library",
"//internal/ingress:go_default_library",
"//pkg/acme:go_default_library",
"//pkg/acme/accounts:go_default_library",
"//pkg/acme/client:go_default_library",

View File

@ -28,7 +28,6 @@ import (
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
"github.com/cert-manager/cert-manager/internal/ingress"
"github.com/cert-manager/cert-manager/pkg/acme/accounts"
cmacmelisters "github.com/cert-manager/cert-manager/pkg/client/listers/acme/v1"
cmlisters "github.com/cert-manager/cert-manager/pkg/client/listers/certmanager/v1"
@ -97,11 +96,7 @@ func (c *controller) Register(ctx *controllerpkg.Context) (workqueue.RateLimitin
// cache when managing pod/service/ingress resources
podInformer := ctx.KubeSharedInformerFactory.Core().V1().Pods()
serviceInformer := ctx.KubeSharedInformerFactory.Core().V1().Services()
_, ingressInformer, err := ingress.NewListerInformer(ctx)
if err != nil {
return nil, nil, err
}
ingressInformer := ctx.KubeSharedInformerFactory.Networking().V1().Ingresses()
// build a list of InformerSynced functions that will be returned by the Register method.
// the controller will only begin processing items once all of these informers have synced.
@ -111,7 +106,7 @@ func (c *controller) Register(ctx *controllerpkg.Context) (workqueue.RateLimitin
secretInformer.Informer().HasSynced,
podInformer.Informer().HasSynced,
serviceInformer.Informer().HasSynced,
ingressInformer.HasSynced,
ingressInformer.Informer().HasSynced,
}
if ctx.GatewaySolverEnabled {
@ -140,6 +135,7 @@ func (c *controller) Register(ctx *controllerpkg.Context) (workqueue.RateLimitin
c.recorder = ctx.Recorder
c.accountRegistry = ctx.ACMEOptions.AccountRegistry
var err error
c.httpSolver, err = http.NewSolver(ctx)
if err != nil {
return nil, nil, err

View File

@ -11,7 +11,6 @@ go_library(
deps = [
"//internal/controller/certificates:go_default_library",
"//internal/controller/feature:go_default_library",
"//internal/ingress:go_default_library",
"//pkg/api/util:go_default_library",
"//pkg/apis/acme/v1:go_default_library",
"//pkg/apis/certmanager/v1:go_default_library",
@ -24,7 +23,6 @@ go_library(
"@com_github_go_logr_logr//:go_default_library",
"@io_k8s_api//core/v1:go_default_library",
"@io_k8s_api//networking/v1:go_default_library",
"@io_k8s_api//networking/v1beta1:go_default_library",
"@io_k8s_apimachinery//pkg/api/errors:go_default_library",
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
"@io_k8s_apimachinery//pkg/labels:go_default_library",

View File

@ -6,7 +6,6 @@ go_library(
importpath = "github.com/cert-manager/cert-manager/pkg/controller/certificate-shim/ingresses",
visibility = ["//visibility:public"],
deps = [
"//internal/ingress:go_default_library",
"//pkg/apis/certmanager/v1:go_default_library",
"//pkg/controller:go_default_library",
"//pkg/controller/certificate-shim:go_default_library",
@ -14,6 +13,7 @@ go_library(
"@io_k8s_apimachinery//pkg/api/errors:go_default_library",
"@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
"@io_k8s_apimachinery//pkg/util/runtime:go_default_library",
"@io_k8s_client_go//listers/networking/v1:go_default_library",
"@io_k8s_client_go//tools/cache:go_default_library",
"@io_k8s_client_go//util/workqueue:go_default_library",
],

View File

@ -23,10 +23,10 @@ import (
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/runtime"
networkingv1listers "k8s.io/client-go/listers/networking/v1"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/workqueue"
"github.com/cert-manager/cert-manager/internal/ingress"
cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
controllerpkg "github.com/cert-manager/cert-manager/pkg/controller"
shimhelper "github.com/cert-manager/cert-manager/pkg/controller/certificate-shim"
@ -38,19 +38,15 @@ const (
)
type controller struct {
ingressLister ingress.InternalIngressLister
ingressLister networkingv1listers.IngressLister
sync shimhelper.SyncFn
}
func (c *controller) Register(ctx *controllerpkg.Context) (workqueue.RateLimitingInterface, []cache.InformerSynced, error) {
cmShared := ctx.SharedInformerFactory
internalIngressLister, internalIngressInformer, err := ingress.NewListerInformer(ctx)
if err != nil {
return nil, nil, err
}
c.ingressLister = internalIngressLister
ingressInformer := ctx.KubeSharedInformerFactory.Networking().V1().Ingresses()
c.ingressLister = ingressInformer.Lister()
log := logf.FromContext(ctx.RootContext, ControllerName)
c.sync = shimhelper.SyncFnFor(ctx.Recorder, log, ctx.CMClient, cmShared.Certmanager().V1().Certificates().Lister(), ctx.IngressShimOptions, ctx.FieldManager)
@ -58,7 +54,7 @@ func (c *controller) Register(ctx *controllerpkg.Context) (workqueue.RateLimitin
queue := workqueue.NewNamedRateLimitingQueue(controllerpkg.DefaultItemBasedRateLimiter(), ControllerName)
mustSync := []cache.InformerSynced{
internalIngressInformer.HasSynced,
ingressInformer.Informer().HasSynced,
cmShared.Certmanager().V1().Certificates().Informer().HasSynced,
}
@ -68,7 +64,7 @@ func (c *controller) Register(ctx *controllerpkg.Context) (workqueue.RateLimitin
// to do some cleanup, we would use a finalizer, and the cleanup logic would
// be triggered by the "Updated" event when the object gets marked for
// deletion.
internalIngressInformer.AddEventHandler(&controllerpkg.QueuingEventHandler{
ingressInformer.Informer().AddEventHandler(&controllerpkg.QueuingEventHandler{
Queue: queue,
})
@ -139,9 +135,6 @@ func certificateHandler(queue workqueue.RateLimitingInterface) func(obj interfac
return
}
// We don't check the apiVersion e.g. "networking.k8s.io/v1beta1"
// because there is no chance that another object called "Ingress" be
// the controller of a Certificate.
if ingress.Kind != "Ingress" {
return
}

View File

@ -27,7 +27,6 @@ import (
"github.com/go-logr/logr"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
networkingv1beta1 "k8s.io/api/networking/v1beta1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
@ -39,7 +38,6 @@ import (
internalcertificates "github.com/cert-manager/cert-manager/internal/controller/certificates"
"github.com/cert-manager/cert-manager/internal/controller/feature"
ingress "github.com/cert-manager/cert-manager/internal/ingress"
cmacme "github.com/cert-manager/cert-manager/pkg/apis/acme/v1"
cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
cmmeta "github.com/cert-manager/cert-manager/pkg/apis/meta/v1"
@ -58,7 +56,6 @@ const (
)
var ingressV1GVK = networkingv1.SchemeGroupVersion.WithKind("Ingress")
var ingressV1Beta1GVK = networkingv1beta1.SchemeGroupVersion.WithKind("Ingress")
var gatewayGVK = gwapi.SchemeGroupVersion.WithKind("Gateway")
// SyncFn is the reconciliation function passed to a certificate-shim's
@ -351,11 +348,7 @@ func buildCertificates(
var controllerGVK schema.GroupVersionKind
switch ingLike.(type) {
case *networkingv1.Ingress:
if _, found := ingLike.GetAnnotations()[ingress.ConvertedGVKAnnotation]; found {
controllerGVK = ingressV1Beta1GVK
} else {
controllerGVK = ingressV1GVK
}
controllerGVK = ingressV1GVK
case *gwapi.Gateway:
controllerGVK = gatewayGVK
}

View File

@ -12,7 +12,6 @@ go_library(
importpath = "github.com/cert-manager/cert-manager/pkg/issuer/acme/http",
visibility = ["//visibility:public"],
deps = [
"//internal/ingress:go_default_library",
"//pkg/apis/acme/v1:go_default_library",
"//pkg/apis/certmanager/v1:go_default_library",
"//pkg/controller:go_default_library",
@ -27,6 +26,7 @@ go_library(
"@io_k8s_apimachinery//pkg/util/errors:go_default_library",
"@io_k8s_apimachinery//pkg/util/intstr:go_default_library",
"@io_k8s_client_go//listers/core/v1:go_default_library",
"@io_k8s_client_go//listers/networking/v1:go_default_library",
"@io_k8s_client_go//util/retry:go_default_library",
"@io_k8s_sigs_gateway_api//apis/v1alpha2:go_default_library",
"@io_k8s_sigs_gateway_api//pkg/client/listers/gateway/apis/v1alpha2:go_default_library",

View File

@ -30,10 +30,10 @@ import (
corev1 "k8s.io/api/core/v1"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
corev1listers "k8s.io/client-go/listers/core/v1"
networkingv1listers "k8s.io/client-go/listers/networking/v1"
k8snet "k8s.io/utils/net"
gwapilisters "sigs.k8s.io/gateway-api/pkg/client/listers/gateway/apis/v1alpha2"
"github.com/cert-manager/cert-manager/internal/ingress"
cmacme "github.com/cert-manager/cert-manager/pkg/apis/acme/v1"
v1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
"github.com/cert-manager/cert-manager/pkg/controller"
@ -59,11 +59,10 @@ var (
type Solver struct {
*controller.Context
podLister corev1listers.PodLister
serviceLister corev1listers.ServiceLister
ingressLister ingress.InternalIngressLister
ingressCreateUpdater ingress.InternalIngressCreateUpdater
httpRouteLister gwapilisters.HTTPRouteLister
podLister corev1listers.PodLister
serviceLister corev1listers.ServiceLister
ingressLister networkingv1listers.IngressLister
httpRouteLister gwapilisters.HTTPRouteLister
testReachability reachabilityTest
requiredPasses int
@ -73,23 +72,14 @@ type reachabilityTest func(ctx context.Context, url *url.URL, key string, dnsSer
// NewSolver returns a new ACME HTTP01 solver for the given *controller.Context.
func NewSolver(ctx *controller.Context) (*Solver, error) {
ingressLister, _, err := ingress.NewListerInformer(ctx)
if err != nil {
return nil, err
}
ingressCreateUpdater, err := ingress.NewCreateUpdater(ctx)
if err != nil {
return nil, err
}
return &Solver{
Context: ctx,
podLister: ctx.KubeSharedInformerFactory.Core().V1().Pods().Lister(),
serviceLister: ctx.KubeSharedInformerFactory.Core().V1().Services().Lister(),
ingressLister: ingressLister,
ingressCreateUpdater: ingressCreateUpdater,
httpRouteLister: ctx.GWShared.Gateway().V1alpha2().HTTPRoutes().Lister(),
testReachability: testReachability,
requiredPasses: 5,
Context: ctx,
podLister: ctx.KubeSharedInformerFactory.Core().V1().Pods().Lister(),
serviceLister: ctx.KubeSharedInformerFactory.Core().V1().Services().Lister(),
ingressLister: ctx.KubeSharedInformerFactory.Networking().V1().Ingresses().Lister(),
httpRouteLister: ctx.GWShared.Gateway().V1alpha2().HTTPRoutes().Lister(),
testReachability: testReachability,
requiredPasses: 5,
}, nil
}

View File

@ -138,7 +138,7 @@ func (s *Solver) createIngress(ctx context.Context, ch *cmacme.Challenge, svcNam
ing = s.mergeIngressObjectMetaWithIngressResourceTemplate(ing, ch.Spec.Solver.HTTP01.Ingress.IngressTemplate)
}
return s.ingressCreateUpdater.Ingresses(ch.Namespace).Create(ctx, ing, metav1.CreateOptions{})
return s.Client.NetworkingV1().Ingresses(ch.Namespace).Create(ctx, ing, metav1.CreateOptions{})
}
func buildIngressResource(ch *cmacme.Challenge, svcName string) (*networkingv1.Ingress, error) {
@ -256,11 +256,11 @@ func (s *Solver) addChallengePathToIngress(ctx context.Context, ch *cmacme.Chall
return ing, nil
}
rule.HTTP.Paths[i] = ingPathToAdd
return s.ingressCreateUpdater.Ingresses(ing.Namespace).Update(ctx, ing, metav1.UpdateOptions{})
return s.Client.NetworkingV1().Ingresses(ing.Namespace).Update(ctx, ing, metav1.UpdateOptions{})
}
}
rule.HTTP.Paths = append([]networkingv1.HTTPIngressPath{ingPathToAdd}, rule.HTTP.Paths...)
return s.ingressCreateUpdater.Ingresses(ing.Namespace).Update(ctx, ing, metav1.UpdateOptions{})
return s.Client.NetworkingV1().Ingresses(ing.Namespace).Update(ctx, ing, metav1.UpdateOptions{})
}
}
@ -273,7 +273,7 @@ func (s *Solver) addChallengePathToIngress(ctx context.Context, ch *cmacme.Chall
},
},
})
return s.ingressCreateUpdater.Ingresses(ing.Namespace).Update(ctx, ing, metav1.UpdateOptions{})
return s.Client.NetworkingV1().Ingresses(ing.Namespace).Update(ctx, ing, metav1.UpdateOptions{})
}
// cleanupIngresses will remove the rules added by cert-manager to an existing
@ -304,7 +304,7 @@ func (s *Solver) cleanupIngresses(ctx context.Context, ch *cmacme.Challenge) err
log := logf.WithRelatedResource(log, ingress).V(logf.DebugLevel)
log.V(logf.DebugLevel).Info("deleting ingress resource")
err := s.ingressCreateUpdater.Ingresses(ingress.Namespace).Delete(ctx, ingress.Name, metav1.DeleteOptions{})
err := s.Client.NetworkingV1().Ingresses(ingress.Namespace).Delete(ctx, ingress.Name, metav1.DeleteOptions{})
if err != nil {
log.V(logf.WarnLevel).Info("failed to delete ingress resource", "error", err)
errs = append(errs, err)
@ -316,7 +316,7 @@ func (s *Solver) cleanupIngresses(ctx context.Context, ch *cmacme.Challenge) err
}
// otherwise, we need to remove any cert-manager added rules from the ingress resource
ing, err := s.ingressCreateUpdater.Ingresses(ch.Namespace).Get(ctx, existingIngressName, metav1.GetOptions{})
ing, err := s.Client.NetworkingV1().Ingresses(ch.Namespace).Get(ctx, existingIngressName, metav1.GetOptions{})
if k8sErrors.IsNotFound(err) {
log.Error(err, "named ingress resource not found, skipping cleanup")
return nil
@ -359,7 +359,7 @@ func (s *Solver) cleanupIngresses(ctx context.Context, ch *cmacme.Challenge) err
ing.Spec.Rules = ingRules
_, err = s.ingressCreateUpdater.Ingresses(ing.Namespace).Update(ctx, ing, metav1.UpdateOptions{})
_, err = s.Client.NetworkingV1().Ingresses(ing.Namespace).Update(ctx, ing, metav1.UpdateOptions{})
if err != nil {
return err
}