diff --git a/pkg/ingress/kube/annotations/auth.go b/pkg/ingress/kube/annotations/auth.go index f9d0308fd..c67828f07 100644 --- a/pkg/ingress/kube/annotations/auth.go +++ b/pkg/ingress/kube/annotations/auth.go @@ -15,12 +15,6 @@ package annotations import ( - "errors" - "sort" - "strings" - - corev1 "k8s.io/api/core/v1" - "github.com/alibaba/higress/pkg/ingress/kube/util" . "github.com/alibaba/higress/pkg/ingress/log" ) @@ -57,101 +51,10 @@ func (a auth) Parse(annotations Annotations, config *Ingress, globalContext *Glo if !needAuthConfig(annotations) { return nil } - - authConfig := &AuthConfig{ - AuthType: defaultAuthType, - } - - // Check auth type - authType, err := annotations.ParseStringASAP(authType) - if err != nil { - IngressLog.Errorf("Parse auth type error %v within ingress %/%s", err, config.Namespace, config.Name) - return nil - } - if authType != defaultAuthType { - IngressLog.Errorf("Auth type %s within ingress %/%s is not supported yet.", authType, config.Namespace, config.Name) - return nil - } - - secretName, _ := annotations.ParseStringASAP(authSecretAnn) - namespaced := util.SplitNamespacedName(secretName) - if namespaced.Name == "" { - IngressLog.Errorf("Auth secret name within ingress %s/%s is invalid", config.Namespace, config.Name) - return nil - } - if namespaced.Namespace == "" { - namespaced.Namespace = config.Namespace - } - - configKey := util.ClusterNamespacedName{ - NamespacedName: namespaced, - ClusterId: config.ClusterId, - } - authConfig.AuthSecret = configKey - - // Subscribe secret - globalContext.WatchedSecrets.Insert(configKey.String()) - - secretType := authFileAuthSecretType - if rawSecretType, err := annotations.ParseStringASAP(authSecretTypeAnn); err == nil { - resultAuthSecretType := authSecretType(rawSecretType) - if resultAuthSecretType == authFileAuthSecretType || resultAuthSecretType == authMapAuthSecretType { - secretType = resultAuthSecretType - } - } - - authConfig.AuthRealm, _ = annotations.ParseStringASAP(authRealm) - - // Process credentials. - secretLister, exist := globalContext.ClusterSecretLister[config.ClusterId] - if !exist { - IngressLog.Errorf("secret lister of cluster %s doesn't exist", config.ClusterId) - return nil - } - authSecret, err := secretLister.Secrets(namespaced.Namespace).Get(namespaced.Name) - if err != nil { - IngressLog.Errorf("Secret %s within ingress %s/%s is not found", - namespaced.String(), config.Namespace, config.Name) - return nil - } - credentials, err := convertCredentials(secretType, authSecret) - if err != nil { - IngressLog.Errorf("Parse auth secret fail, err %v", err) - return nil - } - authConfig.Credentials = credentials - - config.Auth = authConfig + IngressLog.Error("The annotation nginx.ingress.kubernetes.io/auth-type is no longer supported after version 2.0.0, please use the higress wasm plugin (e.g., basic-auth) as an alternative.") return nil } -func convertCredentials(secretType authSecretType, secret *corev1.Secret) ([]string, error) { - var result []string - switch secretType { - case authFileAuthSecretType: - users, exist := secret.Data[authFileKey] - if !exist { - return nil, errors.New("the auth file type must has auth key in secret data") - } - userList := strings.Split(string(users), "\n") - for _, item := range userList { - if !strings.Contains(item, ":") { - continue - } - result = append(result, item) - } - case authMapAuthSecretType: - for name, password := range secret.Data { - result = append(result, name+":"+string(password)) - } - } - sort.SliceStable(result, func(i, j int) bool { - return result[i] < result[j] - }) - - return result, nil -} - func needAuthConfig(annotations Annotations) bool { return annotations.HasASAP(authType) && annotations.HasASAP(authSecretAnn) diff --git a/pkg/ingress/kube/annotations/auth_test.go b/pkg/ingress/kube/annotations/auth_test.go deleted file mode 100644 index 0ede7c4ed..000000000 --- a/pkg/ingress/kube/annotations/auth_test.go +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright (c) 2022 Alibaba Group Holding Ltd. -// -// 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 annotations - -import ( - "context" - "reflect" - "testing" - "time" - - "istio.io/istio/pkg/cluster" - "istio.io/istio/pkg/util/sets" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/informers" - "k8s.io/client-go/kubernetes/fake" - listerv1 "k8s.io/client-go/listers/core/v1" - "k8s.io/client-go/tools/cache" - - "github.com/alibaba/higress/pkg/ingress/kube/util" -) - -func TestAuthParse(t *testing.T) { - auth := auth{} - inputCases := []struct { - input map[string]string - secret *v1.Secret - expect *AuthConfig - watchedSecret string - }{ - { - secret: &v1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "bar", - Namespace: "foo", - }, - Data: map[string][]byte{ - "auth": []byte("A:a\nB:b"), - }, - }, - }, - { - input: map[string]string{ - buildNginxAnnotationKey(authType): "digest", - }, - expect: nil, - secret: &v1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "bar", - Namespace: "foo", - }, - Data: map[string][]byte{ - "auth": []byte("A:a\nB:b"), - }, - }, - }, - { - input: map[string]string{ - buildNginxAnnotationKey(authType): defaultAuthType, - buildHigressAnnotationKey(authSecretAnn): "foo/bar", - }, - secret: &v1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "bar", - Namespace: "foo", - }, - Data: map[string][]byte{ - "auth": []byte("A:a\nB:b"), - }, - }, - expect: &AuthConfig{ - AuthType: defaultAuthType, - AuthSecret: util.ClusterNamespacedName{ - NamespacedName: types.NamespacedName{ - Namespace: "foo", - Name: "bar", - }, - ClusterId: "cluster", - }, - Credentials: []string{"A:a", "B:b"}, - }, - watchedSecret: "cluster/foo/bar", - }, - { - input: map[string]string{ - buildNginxAnnotationKey(authType): defaultAuthType, - buildHigressAnnotationKey(authSecretAnn): "foo/bar", - buildNginxAnnotationKey(authSecretTypeAnn): string(authMapAuthSecretType), - }, - secret: &v1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "bar", - Namespace: "foo", - }, - Data: map[string][]byte{ - "A": []byte("a"), - "B": []byte("b"), - }, - }, - expect: &AuthConfig{ - AuthType: defaultAuthType, - AuthSecret: util.ClusterNamespacedName{ - NamespacedName: types.NamespacedName{ - Namespace: "foo", - Name: "bar", - }, - ClusterId: "cluster", - }, - Credentials: []string{"A:a", "B:b"}, - }, - watchedSecret: "cluster/foo/bar", - }, - { - input: map[string]string{ - buildNginxAnnotationKey(authType): defaultAuthType, - buildHigressAnnotationKey(authSecretAnn): "bar", - buildNginxAnnotationKey(authSecretTypeAnn): string(authFileAuthSecretType), - }, - secret: &v1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "bar", - Namespace: "default", - }, - Data: map[string][]byte{ - "auth": []byte("A:a\nB:b"), - }, - }, - expect: &AuthConfig{ - AuthType: defaultAuthType, - AuthSecret: util.ClusterNamespacedName{ - NamespacedName: types.NamespacedName{ - Namespace: "default", - Name: "bar", - }, - ClusterId: "cluster", - }, - Credentials: []string{"A:a", "B:b"}, - }, - watchedSecret: "cluster/default/bar", - }, - } - - for _, inputCase := range inputCases { - t.Run("", func(t *testing.T) { - config := &Ingress{ - Meta: Meta{ - Namespace: "default", - ClusterId: "cluster", - }, - } - - globalContext, cancel := initGlobalContext(inputCase.secret) - defer cancel() - - _ = auth.Parse(inputCase.input, config, globalContext) - if !reflect.DeepEqual(inputCase.expect, config.Auth) { - t.Fatal("Should be equal") - } - - if inputCase.watchedSecret != "" { - if !globalContext.WatchedSecrets.Contains(inputCase.watchedSecret) { - t.Fatalf("Should watch secret %s", inputCase.watchedSecret) - } - } - }) - } -} - -func initGlobalContext(secret *v1.Secret) (*GlobalContext, context.CancelFunc) { - ctx, cancel := context.WithCancel(context.Background()) - - client := fake.NewSimpleClientset(secret) - informerFactory := informers.NewSharedInformerFactory(client, time.Hour) - secretInformer := informerFactory.Core().V1().Secrets() - go secretInformer.Informer().Run(ctx.Done()) - cache.WaitForCacheSync(ctx.Done(), secretInformer.Informer().HasSynced) - - return &GlobalContext{ - WatchedSecrets: sets.New[string](), - ClusterSecretLister: map[cluster.ID]listerv1.SecretLister{ - "cluster": secretInformer.Lister(), - }, - }, cancel -}