mirror of
https://github.com/alibaba/higress.git
synced 2026-06-09 04:37:31 +08:00
Feat https fallback (#1020)
This commit is contained in:
@@ -17,14 +17,14 @@ package common
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/alibaba/higress/pkg/cert"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/annotations"
|
||||
networking "istio.io/api/networking/v1alpha3"
|
||||
"istio.io/istio/pilot/pkg/model"
|
||||
"istio.io/istio/pkg/config"
|
||||
gatewaytool "istio.io/istio/pkg/config/gateway"
|
||||
listerv1 "k8s.io/client-go/listers/core/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/annotations"
|
||||
)
|
||||
|
||||
type ServiceKey struct {
|
||||
@@ -121,7 +121,7 @@ type IngressController interface {
|
||||
|
||||
SecretLister() listerv1.SecretLister
|
||||
|
||||
ConvertGateway(convertOptions *ConvertOptions, wrapper *WrapperConfig) error
|
||||
ConvertGateway(convertOptions *ConvertOptions, wrapper *WrapperConfig, httpsCredentialConfig *cert.Config) error
|
||||
|
||||
ConvertHTTPRoute(convertOptions *ConvertOptions, wrapper *WrapperConfig) error
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ import (
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/secret"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/util"
|
||||
. "github.com/alibaba/higress/pkg/ingress/log"
|
||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -87,8 +88,6 @@ type controller struct {
|
||||
secretController secret.SecretController
|
||||
|
||||
statusSyncer *statusSyncer
|
||||
|
||||
configMgr *cert.ConfigMgr
|
||||
}
|
||||
|
||||
// NewController creates a new Kubernetes controller
|
||||
@@ -107,7 +106,6 @@ func NewController(localKubeClient, client kubeclient.Client, options common.Opt
|
||||
IngressLog.Infof("Skipping IngressClass, resource not supported for cluster %s", options.ClusterId)
|
||||
}
|
||||
|
||||
configMgr, _ := cert.NewConfigMgr(options.SystemNamespace, client.Kube())
|
||||
c := &controller{
|
||||
options: options,
|
||||
queue: q,
|
||||
@@ -118,7 +116,6 @@ func NewController(localKubeClient, client kubeclient.Client, options common.Opt
|
||||
serviceInformer: serviceInformer.Informer(),
|
||||
serviceLister: serviceInformer.Lister(),
|
||||
secretController: secretController,
|
||||
configMgr: configMgr,
|
||||
}
|
||||
|
||||
handler := controllers.LatestVersionHandlerFuncs(controllers.EnqueueForSelf(q))
|
||||
@@ -354,7 +351,7 @@ func extractTLSSecretName(host string, tls []ingress.IngressTLS) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *controller) ConvertGateway(convertOptions *common.ConvertOptions, wrapper *common.WrapperConfig) error {
|
||||
func (c *controller) ConvertGateway(convertOptions *common.ConvertOptions, wrapper *common.WrapperConfig, httpsCredentialConfig *cert.Config) error {
|
||||
if convertOptions == nil {
|
||||
return fmt.Errorf("convertOptions is nil")
|
||||
}
|
||||
@@ -377,7 +374,6 @@ func (c *controller) ConvertGateway(convertOptions *common.ConvertOptions, wrapp
|
||||
common.IncrementInvalidIngress(c.options.ClusterId, common.EmptyRule)
|
||||
return fmt.Errorf("invalid ingress rule %s:%s in cluster %s, either `defaultBackend` or `rules` must be specified", cfg.Namespace, cfg.Name, c.options.ClusterId)
|
||||
}
|
||||
httpsCredentialConfig, _ := c.configMgr.GetConfigFromConfigmap()
|
||||
for _, rule := range ingressV1Beta.Rules {
|
||||
// Need create builder for every rule.
|
||||
domainBuilder := &common.IngressDomainBuilder{
|
||||
@@ -429,10 +425,23 @@ func (c *controller) ConvertGateway(convertOptions *common.ConvertOptions, wrapp
|
||||
// Get tls secret matching the rule host
|
||||
secretName := extractTLSSecretName(rule.Host, ingressV1Beta.TLS)
|
||||
secretNamespace := cfg.Namespace
|
||||
// If there is no matching secret, try to get it from configmap.
|
||||
if secretName == "" && httpsCredentialConfig != nil {
|
||||
secretName = httpsCredentialConfig.MatchSecretNameByDomain(rule.Host)
|
||||
secretNamespace = c.options.SystemNamespace
|
||||
if secretName != "" {
|
||||
if httpsCredentialConfig != nil && httpsCredentialConfig.FallbackForInvalidSecret {
|
||||
_, err := c.secretController.Lister().Secrets(secretNamespace).Get(secretName)
|
||||
if err != nil {
|
||||
if k8serrors.IsNotFound(err) {
|
||||
// If there is no matching secret, try to get it from configmap.
|
||||
secretName = httpsCredentialConfig.MatchSecretNameByDomain(rule.Host)
|
||||
secretNamespace = c.options.SystemNamespace
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If there is no matching secret, try to get it from configmap.
|
||||
if httpsCredentialConfig != nil {
|
||||
secretName = httpsCredentialConfig.MatchSecretNameByDomain(rule.Host)
|
||||
secretNamespace = c.options.SystemNamespace
|
||||
}
|
||||
}
|
||||
if secretName == "" {
|
||||
// There no matching secret, so just skip.
|
||||
|
||||
@@ -334,7 +334,7 @@ func testConvertGateway(t *testing.T, c common.IngressController) {
|
||||
}
|
||||
|
||||
for _, testcase := range testcases {
|
||||
err := c.ConvertGateway(testcase.input.options, testcase.input.wrapperConfig)
|
||||
err := c.ConvertGateway(testcase.input.options, testcase.input.wrapperConfig, nil)
|
||||
if err != nil {
|
||||
require.Equal(t, testcase.expectNoError, false)
|
||||
} else {
|
||||
|
||||
@@ -54,6 +54,7 @@ import (
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/secret"
|
||||
"github.com/alibaba/higress/pkg/ingress/kube/util"
|
||||
. "github.com/alibaba/higress/pkg/ingress/log"
|
||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -85,8 +86,6 @@ type controller struct {
|
||||
secretController secret.SecretController
|
||||
|
||||
statusSyncer *statusSyncer
|
||||
|
||||
configMgr *cert.ConfigMgr
|
||||
}
|
||||
|
||||
// NewController creates a new Kubernetes controller
|
||||
@@ -99,7 +98,6 @@ func NewController(localKubeClient, client kubeclient.Client, options common.Opt
|
||||
classes := client.KubeInformer().Networking().V1().IngressClasses()
|
||||
classes.Informer()
|
||||
|
||||
configMgr, _ := cert.NewConfigMgr(options.SystemNamespace, client.Kube())
|
||||
c := &controller{
|
||||
options: options,
|
||||
queue: q,
|
||||
@@ -110,7 +108,6 @@ func NewController(localKubeClient, client kubeclient.Client, options common.Opt
|
||||
serviceInformer: serviceInformer.Informer(),
|
||||
serviceLister: serviceInformer.Lister(),
|
||||
secretController: secretController,
|
||||
configMgr: configMgr,
|
||||
}
|
||||
|
||||
handler := controllers.LatestVersionHandlerFuncs(controllers.EnqueueForSelf(q))
|
||||
@@ -346,7 +343,7 @@ func extractTLSSecretName(host string, tls []ingress.IngressTLS) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *controller) ConvertGateway(convertOptions *common.ConvertOptions, wrapper *common.WrapperConfig) error {
|
||||
func (c *controller) ConvertGateway(convertOptions *common.ConvertOptions, wrapper *common.WrapperConfig, httpsCredentialConfig *cert.Config) error {
|
||||
// Ignore canary config.
|
||||
if wrapper.AnnotationsConfig.IsCanary() {
|
||||
return nil
|
||||
@@ -363,7 +360,6 @@ func (c *controller) ConvertGateway(convertOptions *common.ConvertOptions, wrapp
|
||||
return fmt.Errorf("invalid ingress rule %s:%s in cluster %s, either `defaultBackend` or `rules` must be specified", cfg.Namespace, cfg.Name, c.options.ClusterId)
|
||||
}
|
||||
|
||||
httpsCredentialConfig, _ := c.configMgr.GetConfigFromConfigmap()
|
||||
for _, rule := range ingressV1.Rules {
|
||||
// Need create builder for every rule.
|
||||
domainBuilder := &common.IngressDomainBuilder{
|
||||
@@ -415,11 +411,25 @@ func (c *controller) ConvertGateway(convertOptions *common.ConvertOptions, wrapp
|
||||
// Get tls secret matching the rule host
|
||||
secretName := extractTLSSecretName(rule.Host, ingressV1.TLS)
|
||||
secretNamespace := cfg.Namespace
|
||||
// If there is no matching secret, try to get it from configmap.
|
||||
if secretName == "" && httpsCredentialConfig != nil {
|
||||
secretName = httpsCredentialConfig.MatchSecretNameByDomain(rule.Host)
|
||||
secretNamespace = c.options.SystemNamespace
|
||||
if secretName != "" {
|
||||
if httpsCredentialConfig != nil && httpsCredentialConfig.FallbackForInvalidSecret {
|
||||
_, err := c.secretController.Lister().Secrets(secretNamespace).Get(secretName)
|
||||
if err != nil {
|
||||
if k8serrors.IsNotFound(err) {
|
||||
// If there is no matching secret, try to get it from configmap.
|
||||
secretName = httpsCredentialConfig.MatchSecretNameByDomain(rule.Host)
|
||||
secretNamespace = c.options.SystemNamespace
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If there is no matching secret, try to get it from configmap.
|
||||
if httpsCredentialConfig != nil {
|
||||
secretName = httpsCredentialConfig.MatchSecretNameByDomain(rule.Host)
|
||||
secretNamespace = c.options.SystemNamespace
|
||||
}
|
||||
}
|
||||
|
||||
if secretName == "" {
|
||||
// There no matching secret, so just skip.
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user