Skip to content

Commit

Permalink
feat: add wolf-rbac authorization method. (#1011)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlinsRan committed May 18, 2022
1 parent 3cccd56 commit bb5104e
Show file tree
Hide file tree
Showing 19 changed files with 826 additions and 27 deletions.
14 changes: 14 additions & 0 deletions pkg/kube/apisix/apis/config/v2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ type ApisixConsumerSpec struct {
type ApisixConsumerAuthParameter struct {
BasicAuth *ApisixConsumerBasicAuth `json:"basicAuth,omitempty" yaml:"basicAuth"`
KeyAuth *ApisixConsumerKeyAuth `json:"keyAuth,omitempty" yaml:"keyAuth"`
WolfRBAC *ApisixConsumerWolfRBAC `json:"wolfRBAC,omitempty" yaml:"wolfRBAC"`
JwtAuth *ApisixConsumerJwtAuth `json:"jwtAuth,omitempty" yaml:"jwtAuth"`
}

Expand All @@ -365,6 +366,19 @@ type ApisixConsumerKeyAuthValue struct {
Key string `json:"key" yaml:"key"`
}

// ApisixConsumerWolfRBAC defines the configuration for the wolf-rbac auth.
type ApisixConsumerWolfRBAC struct {
SecretRef *corev1.LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"`
Value *ApisixConsumerWolfRBACValue `json:"value,omitempty" yaml:"value,omitempty"`
}

// ApisixConsumerWolfRBAC defines the in-place server and appid and header_prefix configuration for wolf-rbac auth.
type ApisixConsumerWolfRBACValue struct {
Server string `json:"server,omitempty" yaml:"server,omitempty"`
Appid string `json:"appid,omitempty" yaml:"appid,omitempty"`
HeaderPrefix string `json:"header_prefix,omitempty" yaml:"header_prefix,omitempty"`
}

// ApisixConsumerJwtAuth defines the configuration for the jwt auth.
type ApisixConsumerJwtAuth struct {
SecretRef *corev1.LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"`
Expand Down
47 changes: 47 additions & 0 deletions pkg/kube/apisix/apis/config/v2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions pkg/kube/apisix/apis/config/v2beta3/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ type ApisixConsumerSpec struct {
type ApisixConsumerAuthParameter struct {
BasicAuth *ApisixConsumerBasicAuth `json:"basicAuth,omitempty" yaml:"basicAuth"`
KeyAuth *ApisixConsumerKeyAuth `json:"keyAuth,omitempty" yaml:"keyAuth"`
WolfRBAC *ApisixConsumerWolfRBAC `json:"wolfRBAC,omitempty" yaml:"wolfRBAC"`
JwtAuth *ApisixConsumerJwtAuth `json:"jwtAuth,omitempty" yaml:"jwtAuth"`
}

Expand All @@ -366,6 +367,19 @@ type ApisixConsumerKeyAuthValue struct {
Key string `json:"key" yaml:"key"`
}

// ApisixConsumerWolfRBAC defines the configuration for the wolf-rbac auth.
type ApisixConsumerWolfRBAC struct {
SecretRef *corev1.LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"`
Value *ApisixConsumerWolfRBACValue `json:"value,omitempty" yaml:"value,omitempty"`
}

// ApisixConsumerWolfRBAC defines the in-place server and appid and header_prefix configuration for wolf-rbac auth.
type ApisixConsumerWolfRBACValue struct {
Server string `json:"server,omitempty" yaml:"server,omitempty"`
Appid string `json:"appid,omitempty" yaml:"appid,omitempty"`
HeaderPrefix string `json:"header_prefix,omitempty" yaml:"header_prefix,omitempty"`
}

// ApisixConsumerJwtAuth defines the configuration for the jwt auth.
type ApisixConsumerJwtAuth struct {
SecretRef *corev1.LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"`
Expand Down
47 changes: 47 additions & 0 deletions pkg/kube/apisix/apis/config/v2beta3/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions pkg/kube/translation/apisix_consumer.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ func (t *translator) TranslateApisixConsumer(ac *configv2beta3.ApisixConsumer) (
return nil, fmt.Errorf("invalid jwt auth config: %s", err)
}
plugins["jwt-auth"] = cfg
} else if ac.Spec.AuthParameter.WolfRBAC != nil {
cfg, err := t.translateConsumerWolfRBACPlugin(ac.Namespace, ac.Spec.AuthParameter.WolfRBAC)
if err != nil {
return nil, fmt.Errorf("invalid wolf rbac config: %s", err)
}
plugins["wolf-rbac"] = cfg
}

consumer := apisixv1.NewDefaultConsumer()
Expand Down
24 changes: 24 additions & 0 deletions pkg/kube/translation/apisix_consumer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,30 @@ func TestTranslateApisixConsumer(t *testing.T) {
assert.Equal(t, "HS256", cfg3.Algorithm)
assert.Equal(t, int64(1000), cfg3.Exp)
assert.Equal(t, true, cfg3.Base64Secret)

ac = &configv2beta3.ApisixConsumer{
ObjectMeta: metav1.ObjectMeta{
Name: "jack",
Namespace: "qa",
},
Spec: configv2beta3.ApisixConsumerSpec{
AuthParameter: configv2beta3.ApisixConsumerAuthParameter{
WolfRBAC: &configv2beta3.ApisixConsumerWolfRBAC{
Value: &configv2beta3.ApisixConsumerWolfRBACValue{
Server: "https://httpbin.org",
Appid: "test01",
},
},
},
},
}
consumer, err = (&translator{}).TranslateApisixConsumer(ac)
assert.Nil(t, err)
assert.Len(t, consumer.Plugins, 1)
cfg4 := consumer.Plugins["wolf-rbac"].(*apisixv1.WolfRBACConsumerConfig)
assert.Equal(t, "https://httpbin.org", cfg4.Server)
assert.Equal(t, "test01", cfg4.Appid)

// No test test cases for secret references as we already test them
// in plugin_test.go.
}
8 changes: 8 additions & 0 deletions pkg/kube/translation/apisix_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ func (t *translator) translateHTTPRouteV2beta3(ctx *TranslateContext, ar *config
pluginMap["key-auth"] = part.Authentication.KeyAuth
case "basicAuth":
pluginMap["basic-auth"] = make(map[string]interface{})
case "wolfRBAC":
pluginMap["wolf-rbac"] = make(map[string]interface{})
case "jwtAuth":
pluginMap["jwt-auth"] = part.Authentication.JwtAuth
default:
Expand Down Expand Up @@ -404,6 +406,8 @@ func (t *translator) translateHTTPRouteV2(ctx *TranslateContext, ar *configv2.Ap
pluginMap["key-auth"] = part.Authentication.KeyAuth
case "basicAuth":
pluginMap["basic-auth"] = make(map[string]interface{})
case "wolfRBAC":
pluginMap["wolf-rbac"] = make(map[string]interface{})
case "jwtAuth":
pluginMap["jwt-auth"] = part.Authentication.JwtAuth
default:
Expand Down Expand Up @@ -627,6 +631,8 @@ func (t *translator) translateHTTPRouteV2beta3NotStrictly(ctx *TranslateContext,
pluginMap["key-auth"] = part.Authentication.KeyAuth
case "basicAuth":
pluginMap["basic-auth"] = make(map[string]interface{})
case "wolfRBAC":
pluginMap["wolf-rbac"] = make(map[string]interface{})
case "jwtAuth":
pluginMap["jwt-auth"] = part.Authentication.JwtAuth
default:
Expand Down Expand Up @@ -682,6 +688,8 @@ func (t *translator) translateHTTPRouteV2NotStrictly(ctx *TranslateContext, ar *
pluginMap["key-auth"] = part.Authentication.KeyAuth
case "basicAuth":
pluginMap["basic-auth"] = make(map[string]interface{})
case "wolfRBAC":
pluginMap["wolf-rbac"] = make(map[string]interface{})
case "jwtAuth":
pluginMap["jwt-auth"] = part.Authentication.JwtAuth
default:
Expand Down
22 changes: 22 additions & 0 deletions pkg/kube/translation/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,28 @@ func (t *translator) translateConsumerBasicAuthPlugin(consumerNamespace string,
}, nil
}

func (t *translator) translateConsumerWolfRBACPlugin(consumerNamespace string, cfg *configv2beta3.ApisixConsumerWolfRBAC) (*apisixv1.WolfRBACConsumerConfig, error) {
if cfg.Value != nil {
return &apisixv1.WolfRBACConsumerConfig{
Server: cfg.Value.Server,
Appid: cfg.Value.Appid,
HeaderPrefix: cfg.Value.HeaderPrefix,
}, nil
}
sec, err := t.SecretLister.Secrets(consumerNamespace).Get(cfg.SecretRef.Name)
if err != nil {
return nil, err
}
raw1 := sec.Data["server"]
raw2 := sec.Data["appid"]
raw3 := sec.Data["header_prefix"]
return &apisixv1.WolfRBACConsumerConfig{
Server: string(raw1),
Appid: string(raw2),
HeaderPrefix: string(raw3),
}, nil
}

func (t *translator) translateConsumerJwtAuthPlugin(consumerNamespace string, cfg *configv2beta3.ApisixConsumerJwtAuth) (*apisixv1.JwtAuthConsumerConfig, error) {
if cfg.Value != nil {
// The field exp must be a positive integer, default value 86400.
Expand Down
92 changes: 92 additions & 0 deletions pkg/kube/translation/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -844,3 +844,95 @@ func TestTranslateConsumerJwtAuthWithSecretRef(t *testing.T) {
close(processCh)
close(stopCh)
}

func TestTranslateConsumerWolfRBACPluginWithInPlaceValue(t *testing.T) {
wolfRBAC := &configv2beta3.ApisixConsumerWolfRBAC{
Value: &configv2beta3.ApisixConsumerWolfRBACValue{
Server: "https://httpbin.org",
Appid: "test-app",
},
}
cfg, err := (&translator{}).translateConsumerWolfRBACPlugin("default", wolfRBAC)
assert.Nil(t, err)
assert.Equal(t, "https://httpbin.org", cfg.Server)
assert.Equal(t, "test-app", cfg.Appid)
}

func TestTranslateConsumerWolfRBACWithSecretRef(t *testing.T) {
sec := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "jack-wolf-rbac",
},
Data: map[string][]byte{
"server": []byte("http://127.0.0.1:12180"),
"appid": []byte("test-app"),
"header_prefix": []byte("X-"),
},
}
client := fake.NewSimpleClientset()
informersFactory := informers.NewSharedInformerFactory(client, 0)
secretInformer := informersFactory.Core().V1().Secrets().Informer()
secretLister := informersFactory.Core().V1().Secrets().Lister()
processCh := make(chan struct{})
stopCh := make(chan struct{})
secretInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(_ interface{}) {
processCh <- struct{}{}
},
UpdateFunc: func(_, _ interface{}) {
processCh <- struct{}{}
},
})
go secretInformer.Run(stopCh)

tr := &translator{
&TranslatorOptions{
SecretLister: secretLister,
},
}
_, err := client.CoreV1().Secrets("default").Create(context.Background(), sec, metav1.CreateOptions{})
assert.Nil(t, err)

<-processCh

wolfRBAC := &configv2beta3.ApisixConsumerWolfRBAC{
SecretRef: &corev1.LocalObjectReference{Name: "jack-wolf-rbac"},
}
cfg, err := tr.translateConsumerWolfRBACPlugin("default", wolfRBAC)
assert.Nil(t, err)
assert.Equal(t, "http://127.0.0.1:12180", cfg.Server)
assert.Equal(t, "test-app", cfg.Appid)
assert.Equal(t, "X-", cfg.HeaderPrefix)

cfg, err = tr.translateConsumerWolfRBACPlugin("default2", wolfRBAC)
assert.Nil(t, cfg)
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "not found")

delete(sec.Data, "server")
_, err = client.CoreV1().Secrets("default").Update(context.Background(), sec, metav1.UpdateOptions{})
assert.Nil(t, err)
<-processCh

cfg, err = tr.translateConsumerWolfRBACPlugin("default", wolfRBAC)
assert.Nil(t, err)

delete(sec.Data, "appid")
_, err = client.CoreV1().Secrets("default").Update(context.Background(), sec, metav1.UpdateOptions{})
assert.Nil(t, err)
<-processCh

cfg, err = tr.translateConsumerWolfRBACPlugin("default", wolfRBAC)
assert.Nil(t, err)

delete(sec.Data, "header_prefix")
_, err = client.CoreV1().Secrets("default").Update(context.Background(), sec, metav1.UpdateOptions{})
assert.Nil(t, err)
<-processCh

cfg, err = tr.translateConsumerWolfRBACPlugin("default", wolfRBAC)
assert.Nil(t, err)

close(processCh)
close(stopCh)
}
9 changes: 9 additions & 0 deletions pkg/types/apisix/v1/plugin_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ type JwtAuthConsumerConfig struct {
// +k8s:deepcopy-gen=true
type BasicAuthRouteConfig struct{}

// WolfRBACConsumerConfig is the rule config for wolf-rbac plugin
// used in Consumer object.
// +k8s:deepcopy-gen=true
type WolfRBACConsumerConfig struct {
Server string `json:"server,omitempty"`
Appid string `json:"appid,omitempty"`
HeaderPrefix string `json:"header_prefix,omitempty"`
}

// RewriteConfig is the rule config for proxy-rewrite plugin.
// +k8s:deepcopy-gen=true
type RewriteConfig struct {
Expand Down
Loading

0 comments on commit bb5104e

Please sign in to comment.