diff --git a/internal/controllers/gatewayclass_controller.go b/internal/controllers/gatewayclass_controller.go index 2879b0b..e03ff09 100644 --- a/internal/controllers/gatewayclass_controller.go +++ b/internal/controllers/gatewayclass_controller.go @@ -63,6 +63,10 @@ func (r *GatewayClassReconciler) Reconcile(ctx context.Context, req ctrl.Request slog.Debugf("handling gatewayclass " + req.Name) if err := r.Client.Get(ctx, req.NamespacedName, &obj); err != nil { if client.IgnoreNotFound(err) == nil { + gwc := pkg.ActiveSIGs.GetGatewayClass(req.Name) + if gwc == nil { + return ctrl.Result{}, nil + } dctx := context.WithValue(lctx, deployer.CtxKey_DeletePartition, req.Name) return ctrl.Result{}, pkg.DeployForEvent(dctx, []string{req.Name}, func() string { pkg.ActiveSIGs.UnsetGatewayClass(req.Name) @@ -73,6 +77,10 @@ func (r *GatewayClassReconciler) Reconcile(ctx context.Context, req ctrl.Request } } else { ngwc := obj.DeepCopy() + if ngwc.Spec.ControllerName != gatewayv1beta1.GatewayController(pkg.ActiveSIGs.ControllerName) { + slog.Debugf("ignore this gwc " + ngwc.Name + " as its controllerName does not match " + pkg.ActiveSIGs.ControllerName) + return ctrl.Result{}, nil + } ngwc.Status.Conditions = []metav1.Condition{ { diff --git a/internal/pkg/parser.go b/internal/pkg/parser.go index 09e5fed..6f01dad 100644 --- a/internal/pkg/parser.go +++ b/internal/pkg/parser.go @@ -226,20 +226,21 @@ func parseGateway(gw *gatewayv1beta1.Gateway) (map[string]interface{}, error) { } // virtual - for _, addr := range gw.Spec.Addresses { + for i, addr := range gw.Spec.Addresses { if *addr.Type == gatewayv1beta1.IPAddressType { ipaddr := addr.Value for _, listener := range gw.Spec.Listeners { var profiles []interface{} ipProtocol := "" + lsname := gwListenerName(gw, &listener) + vrname := fmt.Sprintf("%s.%d", gwListenerName(gw, &listener), i) switch listener.Protocol { case gatewayv1beta1.HTTPProtocolType: profiles = []interface{}{map[string]string{"name": "http"}} ipProtocol = "tcp" case gatewayv1beta1.HTTPSProtocolType: profiles = []interface{}{map[string]string{"name": "http"}} - lsname := gwListenerName(gw, &listener) for _, scrt := range scrtmap[lsname] { profiles = append(profiles, map[string]string{"name": tlsName(scrt)}) } @@ -255,14 +256,13 @@ func parseGateway(gw *gatewayv1beta1.Gateway) (map[string]interface{}, error) { if ipProtocol == "" { return map[string]interface{}{}, fmt.Errorf("ipProtocol not set in %s case", listener.Protocol) } - destination := fmt.Sprintf("%s:%d", ipaddr, listener.Port) + destination := fmt.Sprintf("/%s/%s:%d", gw.Spec.GatewayClassName, ipaddr, listener.Port) if utils.IsIpv6(ipaddr) { - destination = fmt.Sprintf("%s.%d", ipaddr, listener.Port) + destination = fmt.Sprintf("/%s/%s.%d", gw.Spec.GatewayClassName, ipaddr, listener.Port) } - name := gwListenerName(gw, &listener) - rlt["ltm/virtual/"+name] = map[string]interface{}{ - "name": name, + rlt["ltm/virtual/"+vrname] = map[string]interface{}{ + "name": vrname, "profiles": profiles, "ipProtocol": ipProtocol, "destination": destination, @@ -278,8 +278,8 @@ func parseGateway(gw *gatewayv1beta1.Gateway) (map[string]interface{}, error) { "icmpEcho": "enabled", "routeAdvertisement": "disabled", } - if _, ok := irules[name]; ok { - rlt["ltm/virtual/"+name].(map[string]interface{})["rules"] = irules[name] + if _, ok := irules[lsname]; ok { + rlt["ltm/virtual/"+vrname].(map[string]interface{})["rules"] = irules[lsname] } } } else { diff --git a/tests/systest/bigip_kubernetes_gateway_suite_test.go b/tests/systest/bigip_kubernetes_gateway_suite_test.go index 441e25b..73c0e2c 100644 --- a/tests/systest/bigip_kubernetes_gateway_suite_test.go +++ b/tests/systest/bigip_kubernetes_gateway_suite_test.go @@ -2,13 +2,12 @@ package main_test import ( "context" - "embed" "testing" "github.com/f5devcentral/bigip-kubernetes-gateway/tests/systest/helpers" + "github.com/f5devcentral/f5-bigip-rest-go/utils" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/f5devcentral/f5-bigip-rest-go/utils" ) var ( @@ -45,28 +44,26 @@ var _ = BeforeSuite(func() { sc.BIGIPConfig.Username, sc.BIGIPConfig.Password, sc.BIGIPConfig.IPAddress, sc.BIGIPConfig.Port) slog.Infof("initialized bigip helper") -}) -var _ = AfterSuite(func() {}) + for _, yaml := range []string{ + "templates/basics/namespace.yaml", + } { + f, err := yamlBasics.Open(yaml) + Expect(err).To(Succeed()) + cs, err := k8s.LoadAndRender(ctx, f, dataBasics) + Expect(err).To(Succeed()) + Expect(k8s.Apply(ctx, *cs)).To(Succeed()) + } +}) -var ( - //go:embed templates/basics/*.yaml - yamlBasics embed.FS - dataBasics = map[string]interface{}{ - "gatewayclass": map[string]interface{}{ - "name": "bigip", - }, - "gateway": map[string]interface{}{ - "name": "mygateway", - "ipAddress": "10.250.17.121", - }, - "httproute": map[string]interface{}{ - "name": "myhttproute", - "hostname": "gateway.test.automation", - }, - "service": map[string]interface{}{ - "name": "test-service", - "replicas": 3, - }, +var _ = AfterSuite(func() { + for _, yaml := range []string{ + "templates/basics/namespace.yaml", + } { + f, err := yamlBasics.Open(yaml) + Expect(err).To(Succeed()) + cs, err := k8s.LoadAndRender(ctx, f, dataBasics) + Expect(err).To(Succeed()) + Expect(k8s.Delete(ctx, *cs)).To(Succeed()) } -) +}) diff --git a/tests/systest/controllers_basics_test.go b/tests/systest/controllers_basics_test.go index 02f1b9c..a5d6a60 100644 --- a/tests/systest/controllers_basics_test.go +++ b/tests/systest/controllers_basics_test.go @@ -1,6 +1,7 @@ package main_test import ( + "embed" "fmt" "time" @@ -9,88 +10,318 @@ import ( . "github.com/onsi/gomega" ) -var _ = Describe("Controllers basic test", Ordered, func() { +var ( + //go:embed templates/basics/*.yaml + yamlBasics embed.FS + dataBasics map[string]interface{} +) - BeforeAll(func() { - for _, yaml := range []string{ - "templates/basics/gatewayclass.yaml", - "templates/basics/gateway.yaml", - "templates/basics/httproute.yaml", - "templates/basics/service.yaml", - } { - f, err := yamlBasics.Open(yaml) - Expect(err).To(Succeed()) - cs, err := k8s.LoadAndRender(ctx, f, dataBasics) - Expect(err).To(Succeed()) - Expect(k8s.Apply(ctx, *cs)).To(Succeed()) - } +var _ = Describe("Controllers basic test", func() { + + dataBasics = map[string]interface{}{ + "namespace": map[string]interface{}{ + "name": "abcd", + }, + "gatewayclass": map[string]interface{}{ + "name": "bigip", + }, + "gateway": map[string]interface{}{ + "name": "mygateway", + "listeners": []map[string]interface{}{ + { + "name": "http", + "port": 80, + }, + }, + "ipAddresses": []string{"10.250.17.121"}, + }, + "referencegrant": map[string]interface{}{ + "name": "myreferencegrant", + }, + "httproute": map[string]interface{}{ + "name": "myhttproute", + "hostname": "gateway.test.automation", + }, + "service": map[string]interface{}{ + "name": "test-service", + "replicas": 3, + }, + } + + BeforeEach(func() { setup(dataBasics) }) + AfterEach(func() { teardown(dataBasics) }) + + It("resources deployed as expected", func() { + checkVirtual(dataBasics) + checkiRule(dataBasics) + checkPool(dataBasics) + checkVirtualAddress(dataBasics) + slog.Infof("finished bigip resources checking") }) +}) - AfterAll(func() { +var _ = Describe("Controllers updating test", Ordered, func() { + dataBasics = map[string]interface{}{ + "namespace": map[string]interface{}{ + "name": "abcd", + }, + "gatewayclass": map[string]interface{}{ + "name": "bigip", + }, + "gateway": map[string]interface{}{ + "name": "mygateway", + "listeners": []map[string]interface{}{ + { + "name": "http", + "port": 80, + }, + }, + "ipAddresses": []string{"10.250.17.121"}, + }, + "referencegrant": map[string]interface{}{ + "name": "myreferencegrant", + }, + "httproute": map[string]interface{}{ + "name": "myhttproute", + "hostname": "gateway.test.automation", + }, + "service": map[string]interface{}{ + "name": "test-service", + "replicas": 3, + }, + } + + BeforeEach(func() { setup(dataBasics) }) + AfterEach(func() { teardown(dataBasics) }) + + It("virtual address is replaced as expected", func() { + dataBasics["gateway"] = map[string]interface{}{ + "name": "mygateway", + "listeners": []map[string]interface{}{ + { + "name": "http", + "port": 80, + }, + }, + "ipAddresses": []string{"10.250.17.122"}, + } for _, yaml := range []string{ - "templates/basics/service.yaml", - "templates/basics/httproute.yaml", "templates/basics/gateway.yaml", - "templates/basics/gatewayclass.yaml", } { f, err := yamlBasics.Open(yaml) Expect(err).To(Succeed()) cs, err := k8s.LoadAndRender(ctx, f, dataBasics) Expect(err).To(Succeed()) - Expect(k8s.Delete(ctx, *cs)).To(Succeed()) + Expect(k8s.Apply(ctx, *cs)).To(Succeed()) } - // make sure partition is removed finally - gwcVars := dataBasics["gatewayclass"].(map[string]interface{}) - name := fmt.Sprintf(gwcVars["name"].(string)) - Eventually(bip.Exist). - ProbeEvery(time.Millisecond*500). - WithContext(ctx). - WithArguments("sys/folder", name, "", ""). - WithTimeout(time.Second * 10). - Should(Not(Succeed())) - }) - - It("resources deployed as expected", func() { - checkResourcesAsExpected() + checkVirtualAddress(dataBasics) }) }) -func checkResourcesAsExpected() { - gwVars := dataBasics["gateway"].(map[string]interface{}) - gwcVars := dataBasics["gatewayclass"].(map[string]interface{}) - hrVars := dataBasics["httproute"].(map[string]interface{}) - svcVars := dataBasics["service"].(map[string]interface{}) +var _ = Describe("Controller special cases", func() { + When("there are multiple addrs and listeners in gateway", func() { + dataBasics = map[string]interface{}{ + "namespace": map[string]interface{}{ + "name": "abcd", + }, + "gatewayclass": map[string]interface{}{ + "name": "bigip", + }, + "gateway": map[string]interface{}{ + "name": "mygateway", + "listeners": []map[string]interface{}{ + { + "name": "httpa", + "port": 80, + }, + { + "name": "httpb", + "port": 81, + }, + }, + "ipAddresses": []string{"10.250.17.121", "10.250.17.122"}, + }, + "referencegrant": map[string]interface{}{ + "name": "myreferencegrant", + }, + "httproute": map[string]interface{}{ + "name": "myhttproute", + "hostname": "gateway.test.automation", + }, + "service": map[string]interface{}{ + "name": "test-service", + "replicas": 3, + }, + } + BeforeEach(func() { setup(dataBasics) }) + AfterEach(func() { teardown(dataBasics) }) - var kind, partition, subfolder, name string - var body map[string]interface{} + It("virtuals are created as expected", func() { + checkVirtual(dataBasics) + checkiRule(dataBasics) + checkVirtualAddress(dataBasics) + }) + }) +}) - kind, partition, subfolder = "ltm/virtual", gwcVars["name"].(string), "" - name = fmt.Sprintf("gw.default.%s.http", gwVars["name"]) - body = map[string]interface{}{ - "partition": gwcVars["name"], - "destination": fmt.Sprintf("/%s/%s:80", gwcVars["name"], gwVars["ipAddress"]), - "rules": []string{ - fmt.Sprintf("/%s/hr.default.%s", gwcVars["name"], hrVars["name"]), +var _ = Describe("Controllers random resource list", func() { + dataBasics = map[string]interface{}{ + "namespace": map[string]interface{}{ + "name": "abcd", + }, + "gatewayclass": map[string]interface{}{ + "name": "bigip", + }, + "gateway": map[string]interface{}{ + "name": "mygateway", + "listeners": []map[string]interface{}{ + { + "name": "http", + "port": 80, + }, + }, + "ipAddresses": []string{"10.250.17.121"}, + }, + "referencegrant": map[string]interface{}{ + "name": "myreferencegrant", + }, + "httproute": map[string]interface{}{ + "name": "myhttproute", + "hostname": "gateway.test.automation", }, - "sourceAddressTranslation": map[string]interface{}{ - "type": "automap", + "service": map[string]interface{}{ + "name": "test-service", + "replicas": 3, }, } + BeforeEach(func() { setup(dataBasics) }) + AfterEach(func() { teardown(dataBasics) }) - Eventually(bip.Check). + for i := 0; i < 5; i++ { + It("resources deployed as expected", func() { + checkVirtual(dataBasics) + checkiRule(dataBasics) + checkVirtualAddress(dataBasics) + }) + } +}) + +func setup(data map[string]interface{}) { + for _, yaml := range []string{ + "templates/basics/gatewayclass.yaml", + "templates/basics/gateway.yaml", + "templates/basics/referencegrant.yaml", + "templates/basics/httproute.yaml", + "templates/basics/service.yaml", + } { + f, err := yamlBasics.Open(yaml) + Expect(err).To(Succeed()) + cs, err := k8s.LoadAndRender(ctx, f, dataBasics) + Expect(err).To(Succeed()) + Expect(k8s.Apply(ctx, *cs)).To(Succeed()) + } +} + +func teardown(data map[string]interface{}) { + for _, yaml := range []string{ + "templates/basics/service.yaml", + "templates/basics/httproute.yaml", + "templates/basics/referencegrant.yaml", + "templates/basics/gateway.yaml", + "templates/basics/gatewayclass.yaml", + } { + f, err := yamlBasics.Open(yaml) + Expect(err).To(Succeed()) + + cs, err := k8s.LoadAndRender(ctx, f, dataBasics) + Expect(err).To(Succeed()) + Expect(k8s.Delete(ctx, *cs)).To(Succeed()) + } + + // make sure partition is removed finally + gwcVars := dataBasics["gatewayclass"].(map[string]interface{}) + name := fmt.Sprintf(gwcVars["name"].(string)) + Eventually(bip.Exist). ProbeEvery(time.Millisecond*500). WithContext(ctx). - WithArguments(kind, name, partition, subfolder, body). + WithArguments("sys/folder", name, "", ""). WithTimeout(time.Second * 10). - Should(Succeed()) + Should(Not(Succeed())) +} + +func checkVirtualAddress(data map[string]interface{}) { + gwcVars := data["gatewayclass"].(map[string]interface{}) + gwVars := data["gateway"].(map[string]interface{}) + + var kind, partition, subfolder string + var body map[string]interface{} + + kind, partition, subfolder = "ltm/virtual-address", gwcVars["name"].(string), "" + + for _, name := range gwVars["ipAddresses"].([]string) { + body = map[string]interface{}{} + + Eventually(bip.Check). + ProbeEvery(time.Millisecond*500). + WithContext(ctx). + WithArguments(kind, name, partition, subfolder, body). + WithTimeout(time.Second * 10). + Should(Succeed()) + } + slog.Infof("virtual-address is created as expected") +} + +func checkVirtual(data map[string]interface{}) { + gwVars := data["gateway"].(map[string]interface{}) + gwcVars := data["gatewayclass"].(map[string]interface{}) + hrVars := data["httproute"].(map[string]interface{}) + nsVars := data["namespace"].(map[string]interface{}) + + var kind, partition, subfolder, name string + var body map[string]interface{} + + kind, partition, subfolder = "ltm/virtual", gwcVars["name"].(string), "" + for i, addr := range gwVars["ipAddresses"].([]string) { + for _, listener := range gwVars["listeners"].([]map[string]interface{}) { + name = fmt.Sprintf("gw.default.%s.%s.%d", gwVars["name"], listener["name"], i) + body = map[string]interface{}{ + "partition": gwcVars["name"], + "destination": fmt.Sprintf("/%s/%s:80", gwcVars["name"], addr), + "rules": []string{ + fmt.Sprintf("/%s/hr.%s.%s", gwcVars["name"], nsVars["name"], hrVars["name"]), + }, + "sourceAddressTranslation": map[string]interface{}{ + "type": "automap", + }, + } + + Eventually(bip.Check). + ProbeEvery(time.Millisecond*500). + WithContext(ctx). + WithArguments(kind, name, partition, subfolder, body). + WithTimeout(time.Second * 10). + Should(Succeed()) + } + + } slog.Infof("virtual is created as expected") +} + +func checkiRule(data map[string]interface{}) { + + gwcVars := data["gatewayclass"].(map[string]interface{}) + hrVars := data["httproute"].(map[string]interface{}) + nsVars := data["namespace"].(map[string]interface{}) + + var kind, partition, subfolder, name string + var body map[string]interface{} kind, partition, subfolder = "ltm/rule", gwcVars["name"].(string), "" - name = fmt.Sprintf("hr.default.%s", hrVars["name"]) + name = fmt.Sprintf("hr.%s.%s", nsVars["name"], hrVars["name"]) body = map[string]interface{}{ "partition": gwcVars["name"], } @@ -110,6 +341,13 @@ func checkResourcesAsExpected() { Expect(rule["apiAnonymous"]).Should(ContainSubstring(`set pool $static::pools_0([expr {int(rand()*$static::pools_0_size)}])`)) slog.Infof("irule is created as expected") +} + +func checkPool(data map[string]interface{}) { + svcVars := data["service"].(map[string]interface{}) + + var kind, partition, subfolder, name string + var body map[string]interface{} kind, partition, subfolder = "ltm/pool", "cis-c-tenant", "" name = fmt.Sprintf("default.%s", svcVars["name"]) @@ -134,14 +372,9 @@ func checkResourcesAsExpected() { }).WithContext(ctx).ProbeEvery(time.Millisecond * 500).WithTimeout(time.Second * 120).Should(BeTrue()) slog.Infof("pool is created as expected") - slog.Infof("finished bigip resources checking") } // TODO: Add tests for -// updating gateway.yaml with addresses changed -// -> check the virtual address is updated, legacy ones are removed. -// multiple addresses in the gateway -// -> check multiple virtual created // multiple gateways using the same address. // -> check virtual address are shared, and still exists when deleting one gateway. // multiple httproutes(of different classes) referring the same service diff --git a/tests/systest/controllers_resource_order_test.go b/tests/systest/controllers_resource_order_test.go deleted file mode 100644 index 8600912..0000000 --- a/tests/systest/controllers_resource_order_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package main_test - -import ( - "fmt" - "math/rand" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -var _ = Describe("Controllers random resource list", func() { - - BeforeEach(func() { - yamls := []string{ - "templates/basics/gatewayclass.yaml", - "templates/basics/gateway.yaml", - "templates/basics/httproute.yaml", - "templates/basics/service.yaml", - } - rand.Seed(time.Now().UnixNano()) - rand.Shuffle(len(yamls), func(i, j int) { - yamls[i], yamls[j] = yamls[j], yamls[i] - }) - slog.Infof("randomed yaml list: %v", yamls) - for _, yaml := range yamls { - f, err := yamlBasics.Open(yaml) - Expect(err).To(Succeed()) - cs, err := k8s.LoadAndRender(ctx, f, dataBasics) - Expect(err).To(Succeed()) - Expect(k8s.Apply(ctx, *cs)).To(Succeed()) - } - }) - - AfterEach(func() { - for _, yaml := range []string{ - "templates/basics/service.yaml", - "templates/basics/httproute.yaml", - "templates/basics/gateway.yaml", - "templates/basics/gatewayclass.yaml", - } { - f, err := yamlBasics.Open(yaml) - Expect(err).To(Succeed()) - - cs, err := k8s.LoadAndRender(ctx, f, dataBasics) - Expect(err).To(Succeed()) - Expect(k8s.Delete(ctx, *cs)).To(Succeed()) - } - - // make sure partition is removed finally - gwcVars := dataBasics["gatewayclass"].(map[string]interface{}) - name := fmt.Sprintf(gwcVars["name"].(string)) - Eventually(bip.Exist). - ProbeEvery(time.Millisecond*500). - WithContext(ctx). - WithArguments("sys/folder", name, "", ""). - WithTimeout(time.Second * 10). - Should(Not(Succeed())) - }) - - for i := 0; i < 5; i++ { - It("resources deployed as expected", func() { - checkResourcesAsExpected() - }) - } -}) diff --git a/tests/systest/helpers/k8s.go b/tests/systest/helpers/k8s.go index 3eb33f5..2f37373 100644 --- a/tests/systest/helpers/k8s.go +++ b/tests/systest/helpers/k8s.go @@ -159,7 +159,7 @@ func (k *K8SHelper) LoadAndRender(ctx context.Context, fs io.Reader, data map[st slog.Errorf("failed to render: %s", err.Error()) return nil, err } else { - slog.Tracef(s) + // slog.Infof(s) return k.Loads(ctx, s) } } diff --git a/tests/systest/templates/basics/gateway.yaml b/tests/systest/templates/basics/gateway.yaml index 1d99be7..b3ecb47 100644 --- a/tests/systest/templates/basics/gateway.yaml +++ b/tests/systest/templates/basics/gateway.yaml @@ -7,9 +7,14 @@ metadata: name: {{ .gateway.name }} spec: gatewayClassName: {{ .gatewayclass.name }} - listeners: - - name: http - port: 80 - protocol: HTTP - addresses: - - value: {{ .gateway.ipAddress }} + listeners: {{ range .gateway.listeners }} + - name: {{ .name }} + port: {{ .port }} + protocol: HTTP + allowedRoutes: + namespaces: + from: All + {{ end }} + addresses: {{ range .gateway.ipAddresses }} + - value: {{ . }} + {{ end }} diff --git a/tests/systest/templates/basics/httproute.yaml b/tests/systest/templates/basics/httproute.yaml index b2986f7..004ef84 100644 --- a/tests/systest/templates/basics/httproute.yaml +++ b/tests/systest/templates/basics/httproute.yaml @@ -5,10 +5,14 @@ apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: {{ .httproute.name }} + namespace: {{ .namespace.name }} spec: - parentRefs: - - name: {{ .gateway.name }} - sectionName: http + {{ $gwn := .gateway.name }} + parentRefs: {{ range $i := .gateway.listeners }} + - name: {{ $gwn }} + namespace: default + sectionName: {{ $i.name }} + {{ end }} hostnames: - {{ .httproute.hostname }} rules: @@ -18,5 +22,6 @@ spec: value: /path-test backendRefs: - name: {{ .service.name }} + namespace: default port: 80 diff --git a/tests/systest/templates/basics/namespace.yaml b/tests/systest/templates/basics/namespace.yaml new file mode 100644 index 0000000..2420f79 --- /dev/null +++ b/tests/systest/templates/basics/namespace.yaml @@ -0,0 +1,9 @@ + +--- + +apiVersion: v1 +kind: Namespace +metadata: + name: {{ .namespace.name }} + labels: + resource.zone: allowed-namespaces \ No newline at end of file diff --git a/tests/systest/templates/basics/referencegrant.yaml b/tests/systest/templates/basics/referencegrant.yaml new file mode 100644 index 0000000..9cdba2e --- /dev/null +++ b/tests/systest/templates/basics/referencegrant.yaml @@ -0,0 +1,14 @@ + +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: ReferenceGrant +metadata: + name: {{ .referencegrant.name }} +spec: + from: + - group: gateway.networking.k8s.io + kind: HTTPRoute + namespace: {{ .namespace.name }} + to: + - group: "" + kind: Service + # name: test-service \ No newline at end of file diff --git a/tests/systest/templates/multiple/gateway.yaml b/tests/systest/templates/multiple/gateway.yaml new file mode 100644 index 0000000..8d3785a --- /dev/null +++ b/tests/systest/templates/multiple/gateway.yaml @@ -0,0 +1,19 @@ +--- + +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: Gateway +metadata: + name: mygateway +spec: + gatewayClassName: bigip + listeners: + - name: listenerx + hostname: "*.api" + port: 80 + protocol: HTTP + allowedRoutes: + namespaces: + from: All + addresses: + - value: 10.250.17.143 + diff --git a/tests/systest/templates/multiple/gatewayclass.yaml b/tests/systest/templates/multiple/gatewayclass.yaml new file mode 100644 index 0000000..6b53c3b --- /dev/null +++ b/tests/systest/templates/multiple/gatewayclass.yaml @@ -0,0 +1,8 @@ +--- + +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: GatewayClass +metadata: + name: bigip +spec: + controllerName: f5.io/gateway-controller-name diff --git a/tests/systest/templates/multiple/httproute.yaml b/tests/systest/templates/multiple/httproute.yaml new file mode 100644 index 0000000..b989256 --- /dev/null +++ b/tests/systest/templates/multiple/httproute.yaml @@ -0,0 +1,37 @@ + +--- + +apiVersion: v1 +kind: Namespace +metadata: + name: abcd + labels: + resource.zone: allowed-namespaces + +--- + +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: myroute + namespace: abcd +spec: + parentRefs: + - name: mygateway + sectionName: listenerx + namespace: default + hostnames: + - gateway.api + rules: + - matches: + - path: + type: PathPrefix + value: /path-test + backendRefs: + - namespace: default + name: test-service + port: 80 + - backendRefs: + - namespace: default + name: dev-service + port: 80 diff --git a/tests/systest/templates/multiple/referencegrant.yaml b/tests/systest/templates/multiple/referencegrant.yaml new file mode 100644 index 0000000..71da4cf --- /dev/null +++ b/tests/systest/templates/multiple/referencegrant.yaml @@ -0,0 +1,15 @@ +--- + +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: ReferenceGrant +metadata: + name: myreferencegrant +spec: + from: + - group: gateway.networking.k8s.io + kind: HTTPRoute + namespace: abcd + to: + - group: "" + kind: Service + # name: test-service \ No newline at end of file diff --git a/tests/systest/templates/multiple/service.yaml b/tests/systest/templates/multiple/service.yaml new file mode 100644 index 0000000..c69c52d --- /dev/null +++ b/tests/systest/templates/multiple/service.yaml @@ -0,0 +1,144 @@ +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dev-service +spec: + replicas: 2 + selector: + matchLabels: + app: dev-service + template: + metadata: + labels: + app: dev-service + spec: + containers: + - name: dev-service + image: nginx:latest + ports: + - containerPort: 80 + volumeMounts: + - name: config-volume + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + - name: config-volume + mountPath: /etc/nginx/njs/dumps.js + subPath: dumps.js + volumes: + - name: config-volume + configMap: + name: nginx-config-test + +--- + +apiVersion: v1 +kind: Service +metadata: + name: dev-service +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + selector: + app: dev-service + +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-config-test +data: + nginx.conf: | + user nginx; + worker_processes 1; + + load_module modules/ngx_http_js_module.so; + + events { + worker_connections 1024; + } + + http { + js_import njs/dumps.js; + server { + listen 80; + server_name localhost; + + location / { + js_content dumps.hello; + } + } + } + dumps.js: | + function hello(r) { + let d = { + 'queries': r.args, + 'headers': r.headersIn, + 'version': r.httpVersion, + 'method': r.method, + 'remote-address': r.remoteAddress, + 'body': r.requestText, + 'uri': r.uri, + 'server_name': process.env['HOSTNAME'] + } + + r.return(200, JSON.stringify(d)+"\n"); + } + + export default {hello}; + +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: test-service +spec: + replicas: 2 + selector: + matchLabels: + app: test-service + template: + metadata: + labels: + app: test-service + spec: + containers: + - name: test-service + image: nginx:latest + ports: + - containerPort: 80 + volumeMounts: + - name: config-volume + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + - name: config-volume + mountPath: /etc/nginx/njs/dumps.js + subPath: dumps.js + volumes: + - name: config-volume + configMap: + name: nginx-config-test + +--- + +apiVersion: v1 +kind: Service +metadata: + name: test-service +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + selector: + app: test-service + diff --git a/tests/systest/tls_test.go b/tests/systest/tls_test.go index 6dfe159..91fc1e7 100644 --- a/tests/systest/tls_test.go +++ b/tests/systest/tls_test.go @@ -125,7 +125,7 @@ var _ = Describe("TLS TEST", Label("tls"), Ordered, func() { It("Check virtual server has been created on BigIP", func() { kind, partition, subfolder := "ltm/virtual", partition, "" - name := fmt.Sprintf("gw.default.%s.https", tlsGatewayName) + name := fmt.Sprintf("gw.default.%s.https.0", tlsGatewayName) Eventually(checkExist).WithContext(ctx).WithArguments(kind, name, partition, subfolder, bip.Exist). WithTimeout(time.Second * 10).ProbeEvery(time.Millisecond * 500). Should(BeTrue()) @@ -152,7 +152,7 @@ var _ = Describe("TLS TEST", Label("tls"), Ordered, func() { When("TLS Gateway has been deleted from K8S", func() { It("Check virtual server has been deleted from BigIP", func() { kind, partition, subfolder := "ltm/virtual", partition, "" - name := fmt.Sprintf("gw.default.%s.https", tlsGatewayName) + name := fmt.Sprintf("gw.default.%s.https.0", tlsGatewayName) Eventually(checkExist).WithContext(ctx).WithArguments(kind, name, partition, subfolder, bip.Exist). WithTimeout(time.Second * 10).ProbeEvery(time.Millisecond * 500). Should(BeFalse())