Skip to content

Commit 4cd1005

Browse files
authored
feat: support auth-type for ingress annotations (#2636)
1 parent f418187 commit 4cd1005

File tree

4 files changed

+204
-0
lines changed

4 files changed

+204
-0
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one or more
2+
// contributor license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright ownership.
4+
// The ASF licenses this file to You under the Apache License, Version 2.0
5+
// (the "License"); you may not use this file except in compliance with
6+
// the License. You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
package plugins
17+
18+
import (
19+
adctypes "github.com/apache/apisix-ingress-controller/api/adc"
20+
"github.com/apache/apisix-ingress-controller/internal/adc/translator/annotations"
21+
)
22+
23+
type basicAuth struct{}
24+
25+
// NewkeyBasicHandler creates a handler to convert
26+
// annotations about basicAuth control to APISIX basic-auth plugin.
27+
func NewBasicAuthHandler() PluginAnnotationsHandler {
28+
return &basicAuth{}
29+
}
30+
31+
func (b *basicAuth) PluginName() string {
32+
return "basic-auth"
33+
}
34+
35+
func (b *basicAuth) Handle(e annotations.Extractor) (interface{}, error) {
36+
if e.GetStringAnnotation(annotations.AnnotationsAuthType) != "basicAuth" {
37+
return nil, nil
38+
}
39+
plugin := adctypes.BasicAuthConfig{}
40+
return &plugin, nil
41+
}
42+
43+
type keyAuth struct{}
44+
45+
// NewkeyAuthHandler creates a handler to convert
46+
// annotations about keyAuth control to APISIX key-auth plugin.
47+
func NewKeyAuthHandler() PluginAnnotationsHandler {
48+
return &keyAuth{}
49+
}
50+
51+
func (k *keyAuth) PluginName() string {
52+
return "key-auth"
53+
}
54+
55+
func (k *keyAuth) Handle(e annotations.Extractor) (interface{}, error) {
56+
if e.GetStringAnnotation(annotations.AnnotationsAuthType) != "keyAuth" {
57+
return nil, nil
58+
}
59+
plugin := adctypes.KeyAuthConfig{}
60+
return &plugin, nil
61+
}

internal/adc/translator/annotations/plugins/plugins.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ var (
4040
NewCorsHandler(),
4141
NewCSRFHandler(),
4242
NewFaultInjectionHandler(),
43+
NewBasicAuthHandler(),
44+
NewKeyAuthHandler(),
4345
}
4446
)
4547

internal/adc/translator/annotations_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,28 @@ func TestTranslateIngressAnnotations(t *testing.T) {
257257
},
258258
},
259259
},
260+
{
261+
name: "auth type basicAuth",
262+
anno: map[string]string{
263+
annotations.AnnotationsAuthType: "basicAuth",
264+
},
265+
expected: &IngressConfig{
266+
Plugins: adctypes.Plugins{
267+
"basic-auth": &adctypes.BasicAuthConfig{},
268+
},
269+
},
270+
},
271+
{
272+
name: "auth type keyAuth",
273+
anno: map[string]string{
274+
annotations.AnnotationsAuthType: "keyAuth",
275+
},
276+
expected: &IngressConfig{
277+
Plugins: adctypes.Plugins{
278+
"key-auth": &adctypes.KeyAuthConfig{},
279+
},
280+
},
281+
},
260282
}
261283

262284
for _, tt := range tests {

test/e2e/ingress/annotations.go

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,48 @@ spec:
382382
name: httpbin-service-e2e-test
383383
port:
384384
number: 80
385+
`
386+
ingressKeyAuth = `
387+
apiVersion: networking.k8s.io/v1
388+
kind: Ingress
389+
metadata:
390+
name: key-auth
391+
annotations:
392+
k8s.apisix.apache.org/auth-type: "keyAuth"
393+
spec:
394+
ingressClassName: %s
395+
rules:
396+
- host: httpbin.example
397+
http:
398+
paths:
399+
- path: /ip
400+
pathType: Exact
401+
backend:
402+
service:
403+
name: httpbin-service-e2e-test
404+
port:
405+
number: 80
406+
`
407+
ingressBasicAuth = `
408+
apiVersion: networking.k8s.io/v1
409+
kind: Ingress
410+
metadata:
411+
name: basic-auth
412+
annotations:
413+
k8s.apisix.apache.org/auth-type: "basicAuth"
414+
spec:
415+
ingressClassName: %s
416+
rules:
417+
- host: httpbin.example
418+
http:
419+
paths:
420+
- path: /get
421+
pathType: Exact
422+
backend:
423+
service:
424+
name: httpbin-service-e2e-test
425+
port:
426+
number: 80
385427
`
386428
)
387429
BeforeEach(func() {
@@ -610,5 +652,82 @@ spec:
610652
s.RequestAssert(test)
611653
}
612654
})
655+
It("authentication", func() {
656+
var (
657+
keyAuth = `
658+
apiVersion: apisix.apache.org/v2
659+
kind: ApisixConsumer
660+
metadata:
661+
name: key
662+
spec:
663+
ingressClassName: %s
664+
authParameter:
665+
keyAuth:
666+
value:
667+
key: test-key
668+
`
669+
basicAuth = `
670+
apiVersion: apisix.apache.org/v2
671+
kind: ApisixConsumer
672+
metadata:
673+
name: basic
674+
spec:
675+
ingressClassName: %s
676+
authParameter:
677+
basicAuth:
678+
value:
679+
username: test-user
680+
password: test-password
681+
`
682+
)
683+
Expect(s.CreateResourceFromString(fmt.Sprintf(keyAuth, s.Namespace()))).ShouldNot(HaveOccurred(), "creating ApisixConsumer for keyAuth")
684+
Expect(s.CreateResourceFromString(fmt.Sprintf(basicAuth, s.Namespace()))).ShouldNot(HaveOccurred(), "creating ApisixConsumer for basicAuth")
685+
Expect(s.CreateResourceFromString(fmt.Sprintf(ingressKeyAuth, s.Namespace()))).ShouldNot(HaveOccurred(), "creating Ingress")
686+
Expect(s.CreateResourceFromString(fmt.Sprintf(ingressBasicAuth, s.Namespace()))).ShouldNot(HaveOccurred(), "creating Ingress")
687+
688+
tests := []*scaffold.RequestAssert{
689+
{
690+
Method: "GET",
691+
Path: "/get",
692+
Host: "httpbin.example",
693+
BasicAuth: &scaffold.BasicAuth{
694+
Username: "test-user",
695+
Password: "test-password",
696+
},
697+
Check: scaffold.WithExpectedStatus(http.StatusOK),
698+
},
699+
{
700+
Method: "GET",
701+
Path: "/get",
702+
Host: "httpbin.example",
703+
BasicAuth: &scaffold.BasicAuth{
704+
Username: "invalid-user",
705+
Password: "invalid-password",
706+
},
707+
Check: scaffold.WithExpectedStatus(http.StatusUnauthorized),
708+
},
709+
{
710+
Method: "GET",
711+
Path: "/ip",
712+
Host: "httpbin.example",
713+
Headers: map[string]string{
714+
"apikey": "test-key",
715+
},
716+
Check: scaffold.WithExpectedStatus(http.StatusOK),
717+
},
718+
{
719+
Method: "GET",
720+
Path: "/ip",
721+
Host: "httpbin.example",
722+
Headers: map[string]string{
723+
"apikey": "invalid-key",
724+
},
725+
Check: scaffold.WithExpectedStatus(http.StatusUnauthorized),
726+
},
727+
}
728+
for _, test := range tests {
729+
s.RequestAssert(test)
730+
}
731+
})
613732
})
614733
})

0 commit comments

Comments
 (0)