Skip to content

Commit

Permalink
Support using L4 policy to TCP proxy created by Gateway API (#632)
Browse files Browse the repository at this point in the history
Fix #631
Signed-off-by: spacewander <[email protected]>
  • Loading branch information
spacewander authored Jul 9, 2024
1 parent 24e24b1 commit cd81da1
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 9 deletions.
4 changes: 0 additions & 4 deletions controller/internal/translation/init_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,6 @@ func (s *InitState) AddPolicyForK8sGateway(policy *mosniov1.FilterPolicy, gw *gw

for _, ls := range gw.Spec.Listeners {
proto := mosniov1.NormalizeK8sGatewayProtocol(ls.Protocol)
if proto != "HTTP" && proto != "HTTPS" {
continue
}

scope := PolicyScopeGateway
if targetRef != nil && targetRef.SectionName != nil {
if ls.Name != *targetRef.SectionName {
Expand Down
3 changes: 2 additions & 1 deletion e2e/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ helm: $(LOCALBIN)
.PHONY: create-cluster
create-cluster: kind kubectl
$(KIND) create cluster --name htnn --image kindest/node:v$(MIN_K8S_VERSION)
$(KUBECTL) kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v$(GATEWAY_API_VERSION)" | $(KUBECTL) apply -f -
$(KUBECTL) apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v$(GATEWAY_API_VERSION)/standard-install.yaml
$(KUBECTL) apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v$(GATEWAY_API_VERSION)/experimental-install.yaml

.PHONY: delete-cluster
delete-cluster: kind
Expand Down
6 changes: 6 additions & 0 deletions e2e/base/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ spec:
hostname: "localhost"
port: 10000
protocol: HTTP
- name: tcp
port: 10001
protocol: TCP
allowedRoutes:
kinds:
- kind: TCPRoute
---
apiVersion: v1
kind: Service
Expand Down
1 change: 1 addition & 0 deletions e2e/htnn_controller_values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pilot:
image: "htnn/controller:e2e"
env:
HTNN_ENABLE_LDS_PLUGIN_VIA_ECDS: "true"
PILOT_ENABLE_ALPHA_GATEWAY_API: true
UNSAFE_PILOT_ENABLE_RUNTIME_ASSERTIONS: "true"
UNSAFE_PILOT_ENABLE_DELTA_TEST: "true"
volumes:
Expand Down
3 changes: 2 additions & 1 deletion e2e/pkg/suite/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ func (suite *Suite) startPortForward(t *testing.T) {

cmdline := "./port-forward.sh"
dests := []string{"istio-ingressgateway", "istio-ingressgateway-tcp",
"k8s-gateway-api", "k8s-gateway-api-another"}
"k8s-gateway-api", "k8s-gateway-api-tcp",
"k8s-gateway-api-another"}
for _, d := range dests {
forwarder := exec.Command(cmdline, d)
forwarder.Stdout = os.Stdout
Expand Down
4 changes: 3 additions & 1 deletion e2e/port-forward.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ elif [[ "$DEST" == "istio-ingressgateway-tcp" ]]; then
exec kubectl port-forward -n istio-system pod/"$(kubectl -n istio-system get pods | grep '^istio-ingressgateway' | cut -d' ' -f 1)" 18001:18001
elif [[ "$DEST" == "k8s-gateway-api" ]]; then
exec kubectl port-forward -n e2e pod/"$(kubectl -n e2e get pods | grep '^default-istio' | cut -d' ' -f 1)" 10000:10000
elif [[ "$DEST" == "k8s-gateway-api-tcp" ]]; then
exec kubectl port-forward -n e2e pod/"$(kubectl -n e2e get pods | grep '^default-istio' | cut -d' ' -f 1)" 10001:10001
else
exec kubectl port-forward -n e2e-another pod/"$(kubectl -n e2e-another get pods | grep '^default-istio' | cut -d' ' -f 1)" 10001:10000
exec kubectl port-forward -n e2e-another pod/"$(kubectl -n e2e-another get pods | grep '^default-istio' | cut -d' ' -f 1)" 10100:10000
fi
2 changes: 1 addition & 1 deletion e2e/tests/httproute_other_namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func init() {

// Same host, in different gateway of different namespace
tr = &http.Transport{DialContext: func(ctx context.Context, proto, addr string) (conn net.Conn, err error) {
return net.DialTimeout("tcp", ":10001", 1*time.Second)
return net.DialTimeout("tcp", ":10100", 1*time.Second)
}}
client = &http.Client{Transport: tr, Timeout: 10 * time.Second}
rsp, err = client.Get("http://localhost:10000/echo")
Expand Down
19 changes: 19 additions & 0 deletions e2e/tests/policy_to_tcp_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,25 @@ func init() {
rsp, err := client.Get("http://default.local:18001/echo")
require.NoError(t, err)
require.Equal(t, 200, rsp.StatusCode)

// Do the same with Gateway API
tr = &http.Transport{DialContext: func(ctx context.Context, proto, addr string) (conn net.Conn, err error) {
return net.DialTimeout("tcp", ":10001", 1*time.Second)
}}
client = &http.Client{Transport: tr, Timeout: 10 * time.Second}
_, err = client.Get("http://localhost:10001/echo")
require.Error(t, err)

nsName = types.NamespacedName{Name: "policy", Namespace: k8s.DefaultNamespace}
err = c.Get(ctx, nsName, &policy)
require.NoError(t, err)
err = c.Delete(ctx, &policy)
require.NoError(t, err)

time.Sleep(1 * time.Second)
rsp, err = client.Get("http://localhost:10001/echo")
require.NoError(t, err)
require.Equal(t, 200, rsp.StatusCode)
},
})
}
61 changes: 60 additions & 1 deletion e2e/tests/policy_to_tcp_proxy.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# TODO: support Gateway API
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
Expand Down Expand Up @@ -65,3 +64,63 @@ spec:
"@type": type.googleapis.com/envoy.config.rbac.v3.Action
name: match-all
action: ALLOW
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
name: test
spec:
parentRefs:
- name: default
sectionName: tcp
rules:
- backendRefs:
- name: backend
port: 8080
---
apiVersion: htnn.mosn.io/v1
kind: FilterPolicy
metadata:
name: policy
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: default
sectionName: tcp
filters:
networkRBAC:
config:
statPrefix: network_rbac
matcher:
matcherTree:
input:
name: envoy.matching.inputs.source_ip
typedConfig:
"@type": type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.SourceIPInput
customMatch:
name: ip-matcher
typedConfig:
"@type": type.googleapis.com/xds.type.matcher.v3.IPMatcher
rangeMatchers:
- ranges:
- addressPrefix: 127.0.0.1
prefixLen: 32
onMatch:
action:
name: envoy.filters.rbac.action
typedConfig:
"@type": type.googleapis.com/envoy.config.rbac.v3.Action
name: localhost
action: DENY
# match-all action
- ranges:
- addressPrefix: 0.0.0.0
prefixLen: 0
onMatch:
action:
name: envoy.filters.rbac.action
typedConfig:
"@type": type.googleapis.com/envoy.config.rbac.v3.Action
name: match-all
action: ALLOW

0 comments on commit cd81da1

Please sign in to comment.