Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: WebAssembly filter chains #362

Merged
merged 10 commits into from
Apr 1, 2024
9 changes: 7 additions & 2 deletions .ci/_common.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/bin/bash

readonly DOCKER_LABEL=com.konghq.deck.ci=1

# Usage: waitContainer "PostgreSQL" 5432 0.2
function waitContainer()
{
Expand All @@ -9,7 +11,7 @@ function waitContainer()

for try in {1..100}; do
echo "waiting for ${container}.."
nc localhost ${port} && break;
nc localhost ${port} </dev/null && break;
sleep ${sleep_time}
done
}
Expand All @@ -18,7 +20,8 @@ function create_network()
{
# create docker network if it doesn't exist
if [[ -z $(docker network ls --filter name=${NETWORK_NAME} -q) ]]; then
docker network create ${NETWORK_NAME}
docker network create "${NETWORK_NAME}" \
--label "$DOCKER_LABEL"
fi
}

Expand All @@ -41,6 +44,7 @@ function deploy_pg()
-e "POSTGRES_USER=$DATABASE_USER" \
-e "POSTGRES_DB=$DATABASE_NAME" \
-e "POSTGRES_PASSWORD=$KONG_DB_PASSWORD" \
--label "$DOCKER_LABEL" \
postgres:9.6

waitContainer "PostgreSQL" 5432 0.2
Expand All @@ -56,6 +60,7 @@ function perform_migrations()
-e "KONG_PG_PASSWORD=$KONG_DB_PASSWORD" \
-e "KONG_PASSWORD=$KONG_DB_PASSWORD" \
-e "KONG_LICENSE_DATA=$KONG_LICENSE_DATA" \
--label "$DOCKER_LABEL" \
$KONG_IMAGE kong migrations bootstrap && break
done
}
10 changes: 10 additions & 0 deletions .ci/setup_kong.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ DATABASE_USER=kong
DATABASE_NAME=kong
KONG_DB_PASSWORD=kong
KONG_PG_HOST=pg
KONG_WASM_FILTERS_PATH=$PWD/assets/filters

GATEWAY_CONTAINER_NAME=kong

Expand All @@ -32,13 +33,18 @@ function deploy_kong_postgres()
-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \
-e "KONG_ADMIN_GUI_AUTH=basic-auth" \
-e "KONG_ADMIN_GUI_SESSION_CONF={}" \
-e "KONG_ENFORCE_RBAC=on" \
-e "KONG_PORTAL=on" \
-e "KONG_ROUTER_FLAVOR=${KONG_ROUTER_FLAVOR}" \
-e "KONG_WASM=on" \
-e "KONG_WASM_FILTERS_PATH=/wasm/filters" \
-v "$KONG_WASM_FILTERS_PATH:/wasm/filters:ro" \
-p 8000:8000 \
-p 8443:8443 \
-p 127.0.0.1:8001:8001 \
-p 127.0.0.1:8444:8444 \
--label "$DOCKER_LABEL" \
$KONG_IMAGE
waitContainer "Kong" 8001 0.2
}
Expand All @@ -57,10 +63,14 @@ function deploy_kong_dbless()
-e "KONG_ENFORCE_RBAC=on" \
-e "KONG_PORTAL=on" \
-e "KONG_ROUTER_FLAVOR=${KONG_ROUTER_FLAVOR}" \
-e "KONG_WASM=on" \
-e "KONG_WASM_FILTERS_PATH=/wasm/filters" \
-v "$KONG_WASM_FILTERS_PATH:/wasm/filters:ro" \
-p 8000:8000 \
-p 8443:8443 \
-p 127.0.0.1:8001:8001 \
-p 127.0.0.1:8444:8444 \
--label "$DOCKER_LABEL" \
$KONG_IMAGE
waitContainer "Kong" 8001 0.2
}
Expand Down
7 changes: 6 additions & 1 deletion .ci/setup_kong_ee.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -e

source $(dirname "$0")/_common.sh

KONG_IMAGE=${KONG_IMAGE_REPO:-kong/kong-gateway}:${KONG_IMAGE_TAG:-3.4}
KONG_IMAGE=${KONG_IMAGE_REPO:-kong/kong-gateway}:${KONG_IMAGE_TAG:-3.6}
NETWORK_NAME=kong-test

KONG_ROUTER_FLAVOR=${KONG_ROUTER_FLAVOR:-'traditional_compatible'}
Expand All @@ -14,6 +14,7 @@ DATABASE_USER=kong
DATABASE_NAME=kong
KONG_DB_PASSWORD=kong
KONG_PG_HOST=pg
KONG_WASM_FILTERS_PATH=$PWD/assets/filters

GATEWAY_CONTAINER_NAME=kong

Expand Down Expand Up @@ -47,6 +48,9 @@ function deploy_kong_ee()
-e "KONG_PORTAL=on" \
-e "KONG_ADMIN_GUI_SESSION_CONF={}" \
-e "KONG_ROUTER_FLAVOR=${KONG_ROUTER_FLAVOR}" \
-e "KONG_WASM=on" \
-e "KONG_WASM_FILTERS_PATH=/wasm/filters" \
-v "$KONG_WASM_FILTERS_PATH:/wasm/filters:ro" \
-p 8000:8000 \
-p 8443:8443 \
-p 8001:8001 \
Expand All @@ -55,6 +59,7 @@ function deploy_kong_ee()
-p 8445:8445 \
-p 8003:8003 \
-p 8004:8004 \
--label "$DOCKER_LABEL" \
$KONG_IMAGE
}

Expand Down
23 changes: 23 additions & 0 deletions .ci/teardown.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash

set -e

source $(dirname "$0")/_common.sh

cleanup() {
local -r resource=${1?resource type required}
shift

docker "$resource" ls "$@" \
--filter "label=$DOCKER_LABEL" \
--quiet \
| while read -r id; do
docker "$resource" rm \
--force \
"$id"
done
}

cleanup container --all
cleanup volume
cleanup network
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[*.go]
end_of_line = lf
indent_style = tab
indent_size = 2
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
KONG_ROUTER_FLAVOR: ${{ matrix.router_flavor }}
KONG_ADMIN_TOKEN: kong
KONG_IMAGE_REPO: "kong/kong-gateway-internal"
KONG_IMAGE_TAG: "master-alpine"
KONG_IMAGE_TAG: "master"
KONG_ANONYMOUS_REPORTS: "off"
TEST_KONG_PULL_USERNAME: ${{ secrets.GHA_DOCKERHUB_PULL_USER }}
TEST_KONG_PULL_PASSWORD: ${{ secrets.GHA_KONG_ORG_DOCKERHUB_PUBLIC_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/integration-test-nightly.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
env:
KONG_ROUTER_FLAVOR: ${{ matrix.router_flavor }}
KONG_IMAGE_REPO: "kong/kong"
KONG_IMAGE_TAG: "master-alpine"
KONG_IMAGE_TAG: "master"
KONG_ANONYMOUS_REPORTS: "off"
runs-on: ubuntu-latest
steps:
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ setup-kong-postgres:
setup-kong-ee:
bash .ci/setup_kong_ee.sh

.PHONY: teardown
teardown:
bash .ci/teardown.sh

.PHONY: test-coverage-enterprise
test-coverage-enterprise:
go test -tags=enterprise -race -v -count=1 -coverprofile=coverage.out.tmp ./...
Expand Down
Binary file added assets/filters/example-filter.wasm
Binary file not shown.
2 changes: 2 additions & 0 deletions kong/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ type Client struct {
Keys AbstractKeyService
KeySets AbstractKeySetService
Licenses AbstractLicenseService
FilterChains AbstractFilterChainService

credentials abstractCredentialService
KeyAuths AbstractKeyAuthService
Expand Down Expand Up @@ -161,6 +162,7 @@ func NewClient(baseURL *string, client *http.Client) (*Client, error) {
kong.Keys = (*KeyService)(&kong.common)
kong.KeySets = (*KeySetService)(&kong.common)
kong.Licenses = (*LicenseService)(&kong.common)
kong.FilterChains = (*FilterChainService)(&kong.common)

kong.credentials = (*credentialService)(&kong.common)
kong.KeyAuths = (*KeyAuthService)(&kong.common)
Expand Down
5 changes: 5 additions & 0 deletions kong/consumer_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,8 @@ func (cg *ConsumerGroup) FriendlyName() string {
}
return ""
}

type consumerGroupConsumers struct {
Consumers []*Consumer `json:"consumers,omitempty" yaml:"consumers,omitempty"`
Data []*Consumer `json:"data,omitempty" yaml:"data,omitempty"`
}
21 changes: 17 additions & 4 deletions kong/consumer_group_consumer_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type AbstractConsumerGroupConsumerService interface {
// Delete deletes a ConsumerGroupConsumer in Kong
Delete(ctx context.Context, consumerGroupNameOrID *string, consumerNameOrID *string) error
// ListAll fetches all ConsumerGroup's Consumers in Kong.
ListAll(ctx context.Context, consumerGroupNameOrID *string) (*ConsumerGroupObject, error)
ListAll(ctx context.Context, consumerGroupNameOrID *string) ([]*Consumer, error)
}

// ConsumerGroupService handles ConsumerGroup in Kong.
Expand Down Expand Up @@ -77,7 +77,7 @@ func (s *ConsumerGroupConsumerService) Delete(ctx context.Context,
// List fetches a list all of ConsumerGroup's consumers in Kong.
func (s *ConsumerGroupConsumerService) ListAll(
ctx context.Context, consumerGroupNameOrID *string,
) (*ConsumerGroupObject, error) {
) ([]*Consumer, error) {
if isEmptyString(consumerGroupNameOrID) {
return nil, fmt.Errorf("consumerGroupNameOrID cannot be nil for ListAll operation")
}
Expand All @@ -89,11 +89,24 @@ func (s *ConsumerGroupConsumerService) ListAll(
return nil, err
}

var cg ConsumerGroupObject
var cg consumerGroupConsumers
_, err = s.client.Do(ctx, req, &cg)
if err != nil {
return nil, err
}

return &cg, nil
var consumers []*Consumer

// See https://github.com/Kong/kong-ee/pull/6421
if cg.Consumers != nil {
// Kong < 3.5
consumers = cg.Consumers
} else if cg.Data != nil {
// Kong >= 3.5
consumers = cg.Data
} else {
consumers = make([]*Consumer, 0)
}

return consumers, nil
}
6 changes: 3 additions & 3 deletions kong/consumer_group_consumer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,12 @@ func TestConsumerGroupConsumersListEndpoint(t *testing.T) {
consumerGroupConsumersFromKong, err := client.ConsumerGroupConsumers.ListAll(defaultCtx, cg.Name)
require.NoError(t, err)
assert.NotNil(consumerGroupConsumersFromKong)
assert.Equal(3, len(consumerGroupConsumersFromKong.Consumers))
assert.Equal(3, len(consumerGroupConsumersFromKong))

// check if we see all consumer groups
assert.True(compareConsumers(consumers, consumerGroupConsumersFromKong.Consumers))
assert.True(compareConsumers(consumers, consumerGroupConsumersFromKong))

for i := 0; i < len(consumerGroupConsumersFromKong.Consumers); i++ {
for i := 0; i < len(consumerGroupConsumersFromKong); i++ {
assert.NoError(client.Consumers.Delete(defaultCtx, consumers[i].ID))
}

Expand Down
3 changes: 3 additions & 0 deletions kong/developer_role_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

func TestDeveloperRoleService(T *testing.T) {
RunWhenEnterprise(T, ">=0.33.0", RequiredFeatures{Portal: true})
RunWhenEnterprise(T, "<3.7.0", RequiredFeatures{Portal: true})
assert := assert.New(T)

client, err := NewTestClient(nil, nil)
Expand Down Expand Up @@ -60,6 +61,7 @@ func TestDeveloperRoleService(T *testing.T) {

func TestDeveloperRoleServiceList(T *testing.T) {
RunWhenEnterprise(T, ">=0.33.0", RequiredFeatures{Portal: true})
RunWhenEnterprise(T, "<3.7.0", RequiredFeatures{Portal: true})
assert := assert.New(T)

client, err := NewTestClient(nil, nil)
Expand Down Expand Up @@ -98,6 +100,7 @@ func TestDeveloperRoleServiceList(T *testing.T) {

func TestDeveloperRoleListEndpoint(T *testing.T) {
RunWhenEnterprise(T, ">=0.33.0", RequiredFeatures{Portal: true})
RunWhenEnterprise(T, "<3.7.0", RequiredFeatures{Portal: true})
assert := assert.New(T)

client, err := NewTestClient(nil, nil)
Expand Down
2 changes: 2 additions & 0 deletions kong/developer_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

func TestDevelopersService(T *testing.T) {
RunWhenEnterprise(T, ">=0.33.0", RequiredFeatures{Portal: true})
RunWhenEnterprise(T, "<3.7.0", RequiredFeatures{Portal: true})
assert := assert.New(T)

client, err := NewTestClient(nil, nil)
Expand Down Expand Up @@ -79,6 +80,7 @@ func TestDevelopersService(T *testing.T) {

func TestDeveloperListEndpoint(T *testing.T) {
RunWhenEnterprise(T, ">=0.33.0", RequiredFeatures{Portal: true})
RunWhenEnterprise(T, "<3.7.0", RequiredFeatures{Portal: true})
assert := assert.New(T)

client, err := NewTestClient(nil, nil)
Expand Down
37 changes: 37 additions & 0 deletions kong/filter_chain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package kong

import "encoding/json"

// FilterChain represents a FilterChain in Kong.
// Read https://docs.konghq.com/gateway/latest/admin-api/#filter-chain-object
// +k8s:deepcopy-gen=true
type FilterChain struct {
ID *string `json:"id,omitempty" yaml:"id,omitempty"`
Name *string `json:"name,omitempty" yaml:"name,omitempty"`
Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"`
Route *Route `json:"route,omitempty" yaml:"route,omitempty"`
Service *Service `json:"service,omitempty" yaml:"service,omitempty"`
Filters []*Filter `json:"filters,omitempty" yaml:"filters,omitempty"`
CreatedAt *int `json:"created_at,omitempty" yaml:"created_at,omitempty"`
UpdatedAt *int `json:"updated_at,omitempty" yaml:"updated_at,omitempty"`
Tags []*string `json:"tags,omitempty" yaml:"tags,omitempty"`
}

// Filter contains information about each filter in the chain
// +k8s:deepcopy-gen=true
type Filter struct {
Name *string `json:"name,omitempty" yaml:"name,omitempty"`
Config *json.RawMessage `json:"config,omitempty" yaml:"config,omitempty"`
Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"`
}

// FriendlyName returns the endpoint key name or ID.
func (f *FilterChain) FriendlyName() string {
if f.Name != nil {
return *f.Name
}
if f.ID != nil {
return *f.ID
}
return ""
}
Loading
Loading