You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by kv...@apache.org on 2021/09/01 06:15:30 UTC

[apisix-ingress-controller] branch master updated: Add API for getting schema of route, upstream and consumer (#655)

This is an automated email from the ASF dual-hosted git repository.

kvn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-ingress-controller.git


The following commit(s) were added to refs/heads/master by this push:
     new a9960c2  Add API for getting schema of route, upstream and consumer (#655)
a9960c2 is described below

commit a9960c2a266686fc438451904c8d66430a7d70ee
Author: Hoshea Jiang <fg...@gmail.com>
AuthorDate: Wed Sep 1 14:15:25 2021 +0800

    Add API for getting schema of route, upstream and consumer (#655)
---
 pkg/apisix/apisix.go            |  3 +++
 pkg/apisix/nonexistentclient.go | 12 ++++++++++++
 pkg/apisix/schema.go            | 19 +++++++++++++++++--
 pkg/apisix/schema_test.go       | 42 +++++++++++++++++++++++++++++++----------
 4 files changed, 64 insertions(+), 12 deletions(-)

diff --git a/pkg/apisix/apisix.go b/pkg/apisix/apisix.go
index 84f152d..6a5a4e6 100644
--- a/pkg/apisix/apisix.go
+++ b/pkg/apisix/apisix.go
@@ -129,6 +129,9 @@ type Plugin interface {
 // Schema is the specific client interface to fetch the schema of APISIX objects.
 type Schema interface {
 	GetPluginSchema(context.Context, string) (*v1.Schema, error)
+	GetRouteSchema(context.Context) (*v1.Schema, error)
+	GetUpstreamSchema(context.Context) (*v1.Schema, error)
+	GetConsumerSchema(context.Context) (*v1.Schema, error)
 }
 
 type apisix struct {
diff --git a/pkg/apisix/nonexistentclient.go b/pkg/apisix/nonexistentclient.go
index d0d1d4d..35523bc 100644
--- a/pkg/apisix/nonexistentclient.go
+++ b/pkg/apisix/nonexistentclient.go
@@ -196,6 +196,18 @@ func (f *dummySchema) GetPluginSchema(_ context.Context, _ string) (*v1.Schema,
 	return nil, ErrClusterNotExist
 }
 
+func (f *dummySchema) GetRouteSchema(_ context.Context) (*v1.Schema, error) {
+	return nil, ErrClusterNotExist
+}
+
+func (f *dummySchema) GetUpstreamSchema(_ context.Context) (*v1.Schema, error) {
+	return nil, ErrClusterNotExist
+}
+
+func (f *dummySchema) GetConsumerSchema(_ context.Context) (*v1.Schema, error) {
+	return nil, ErrClusterNotExist
+}
+
 func (nc *nonExistentCluster) Route() Route {
 	return nc.route
 }
diff --git a/pkg/apisix/schema.go b/pkg/apisix/schema.go
index 1727124..f8832bf 100644
--- a/pkg/apisix/schema.go
+++ b/pkg/apisix/schema.go
@@ -18,12 +18,12 @@ package apisix
 import (
 	"context"
 
+	"go.uber.org/zap"
+
 	"github.com/apache/apisix-ingress-controller/pkg/apisix/cache"
 	"github.com/apache/apisix-ingress-controller/pkg/id"
 	"github.com/apache/apisix-ingress-controller/pkg/log"
 	v1 "github.com/apache/apisix-ingress-controller/pkg/types/apisix/v1"
-
-	"go.uber.org/zap"
 )
 
 type schemaClient struct {
@@ -90,3 +90,18 @@ func (sc schemaClient) getSchema(ctx context.Context, name string) (*v1.Schema,
 func (sc schemaClient) GetPluginSchema(ctx context.Context, pluginName string) (*v1.Schema, error) {
 	return sc.getSchema(ctx, "plugins/"+pluginName)
 }
+
+// GetRouteSchema returns route's schema.
+func (sc schemaClient) GetRouteSchema(ctx context.Context) (*v1.Schema, error) {
+	return sc.getSchema(ctx, "route")
+}
+
+// GetUpstreamSchema returns upstream's schema.
+func (sc schemaClient) GetUpstreamSchema(ctx context.Context) (*v1.Schema, error) {
+	return sc.getSchema(ctx, "upstream")
+}
+
+// GetConsumerSchema returns consumer's schema.
+func (sc schemaClient) GetConsumerSchema(ctx context.Context) (*v1.Schema, error) {
+	return sc.getSchema(ctx, "consumer")
+}
diff --git a/pkg/apisix/schema_test.go b/pkg/apisix/schema_test.go
index cc782fb..3fe707b 100644
--- a/pkg/apisix/schema_test.go
+++ b/pkg/apisix/schema_test.go
@@ -21,9 +21,8 @@ import (
 	"strings"
 	"testing"
 
-	"golang.org/x/net/nettest"
-
 	"github.com/stretchr/testify/assert"
+	"golang.org/x/net/nettest"
 )
 
 type fakeAPISIXSchemaSrv struct {
@@ -35,6 +34,10 @@ var testData = map[string]string{
 	"plugins/key-auth":           `{"$comment":"this is a mark for our injected plugin schema","type":"object","additionalProperties":false,"properties":{"disable":{"type":"boolean"},"header":{"default":"apikey","type":"string"}}}`,
 	"plugins/batch-requests":     `{"$comment":"this is a mark for our injected plugin schema","type":"object","additionalProperties":false,"properties":{"disable":{"type":"boolean"}}}`,
 	"plugins/ext-plugin-pre-req": `{"properties":{"disable":{"type":"boolean"},"extra_info":{"items":{"type":"string","minLength":1,"maxLength":64},"minItems":1,"type":"array"},"conf":{"items":{"properties":{"value":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":128}},"type":"object"},"minItems":1,"type":"array"}},"$comment":"this is a mark for our injected plugin schema","type":"object"}`,
+
+	"route":    `{"anyOf":[{"required":["plugins","uri"]},{"required":["upstream","uri"]},{"required":["upstream_id","uri"]},{"required":["service_id","uri"]},{"required":["plugins","uris"]},{"required":["upstream","uris"]},{"required":["upstream_id","uris"]},{"required":["service_id","uris"]},{"required":["script","uri"]},{"required":["script","uris"]}],"additionalProperties":false,"not":{"anyOf":[{"required":["script","plugins"]},{"required":["script","plugin_config_id"]}]},"properties":{ [...]
+	"upstream": `{"oneOf":[{"required":["type","nodes"]},{"required":["type","service_name","discovery_type"]}],"properties":{"id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","type":"string","minLength":1,"maxLength":64},{"minimum":1,"type":"integer"}]},"name":{"type":"string","minLength":1,"maxLength":100},"create_time":{"type":"integer"},"retries":{"minimum":0,"type":"integer"},"scheme":{"enum":["grpc","grpcs","http","https"],"default":"http"},"key":{"type":"string","description":"the key of [...]
+	"consumer": `{"type":"object","properties":{"desc":{"maxLength":256,"type":"string"},"username":{"pattern":"^[a-zA-Z0-9_]+$","type":"string","minLength":1,"maxLength":32},"plugins":{"type":"object"},"labels":{"maxProperties":16,"type":"object","patternProperties":{".*":{"pattern":"^\\S+$","description":"value of label","type":"string","minLength":1,"maxLength":64}},"description":"key\/value pairs to specify attributes"},"update_time":{"type":"integer"},"create_time":{"type":"integer"}}, [...]
 }
 
 const errMsg = `{"error_msg":"not found schema"}`
@@ -107,19 +110,38 @@ func TestSchemaClient(t *testing.T) {
 		cacheSynced: closedCh,
 	})
 
+	ctx := context.TODO()
+
 	// Test `GetPluginSchema`.
 	for name := range testData {
-		list := strings.Split(name, "/")
-		assert.Greater(t, len(list), 0)
-
-		schema, err := cli.GetPluginSchema(context.Background(), list[len(list)-1])
-		assert.Nil(t, err)
-		assert.Equal(t, schema.Name, name)
-		assert.Equal(t, schema.Content, testData[name])
+		if strings.HasPrefix(name, "plugins/") {
+			list := strings.Split(name, "/")
+			assert.Greater(t, len(list), 0)
+
+			schema, err := cli.GetPluginSchema(ctx, list[len(list)-1])
+			assert.Nil(t, err)
+			assert.Equal(t, schema.Name, name)
+			assert.Equal(t, schema.Content, testData[name])
+		}
 	}
 
 	// Test getting a non-existent plugin's schema.
-	schema, err := cli.GetPluginSchema(context.Background(), "not-a-plugin")
+	schema, err := cli.GetPluginSchema(ctx, "not-a-plugin")
 	assert.Nil(t, err)
 	assert.Equal(t, schema.Content, errMsg)
+
+	// Test `GetRouteSchema`
+	routeSchema, err := cli.GetRouteSchema(ctx)
+	assert.Nil(t, err)
+	assert.Equal(t, routeSchema.Content, testData["route"])
+
+	// Test `GetRouteSchema`
+	upstreamSchema, err := cli.GetUpstreamSchema(ctx)
+	assert.Nil(t, err)
+	assert.Equal(t, upstreamSchema.Content, testData["upstream"])
+
+	// Test `GetConsumerSchema`
+	consumerSchema, err := cli.GetConsumerSchema(ctx)
+	assert.Nil(t, err)
+	assert.Equal(t, consumerSchema.Content, testData["consumer"])
 }