Skip to content
This repository was archived by the owner on Aug 22, 2025. It is now read-only.
Prev Previous commit
Next Next commit
Add TCP Border Client
  • Loading branch information
ciroque committed Mar 31, 2023
commit bb2656c5b1532115e43c4aef8ad081eaa0bd2df3
51 changes: 51 additions & 0 deletions internal/application/application_common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2023 F5 Inc. All rights reserved.
* Use of this source code is governed by the Apache License that can be found in the LICENSE file.
*/

package application

import (
"errors"
"github.com/nginxinc/kubernetes-nginx-ingress/internal/core"
"github.com/nginxinc/kubernetes-nginx-ingress/test/mocks"
nginxClient2 "github.com/nginxinc/nginx-plus-go-client/client"
)

const (
clientTypeTcp = "tcp"
clientTypeHttp = "http"
deletedEventType = core.Deleted
createEventType = core.Created
upstreamName = "upstreamName"
server = "server"
)

func buildTerrorizingBorderClient(clientType string) (Interface, *mocks.MockNginxClient, error) {
nginxClient := mocks.NewErroringMockClient(errors.New(`something went horribly horribly wrong`))
bc, err := NewBorderClient(clientType, nginxClient)

return bc, nginxClient, err
}

func buildBorderClient(clientType string) (Interface, *mocks.MockNginxClient, error) {
nginxClient := mocks.NewMockNginxClient()
bc, err := NewBorderClient(clientType, nginxClient)

return bc, nginxClient, err
}

func buildServerUpdateEvent(eventType core.EventType) core.ServerUpdateEvent {
httpServers := []nginxClient2.UpstreamServer{
{
Server: server,
},
}

tcpServers := []nginxClient2.StreamUpstreamServer{
{
Server: server,
},
}
return *core.NewServerUpdateEvent(eventType, upstreamName, tcpServers, httpServers)
}
5 changes: 2 additions & 3 deletions internal/application/border_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ func NewBorderClient(whichType string, borderClient interface{}) (Interface, err

switch whichType {
case "tcp":
return &TcpBorderClient{
BorderClient: BorderClient{},
}, nil
return NewTcpBorderClient(borderClient)

case "http":
return NewHttpBorderClient(borderClient)

Expand Down
7 changes: 5 additions & 2 deletions internal/application/border_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ func TestBorderClient_CreatesHttpBorderClient(t *testing.T) {
}

func TestBorderClient_CreatesTcpBorderClient(t *testing.T) {
client, err := NewBorderClient("tcp", nil)
borderClient := mocks.MockNginxClient{}
client, err := NewBorderClient("tcp", borderClient)
if err != nil {
t.Errorf(`error creating border client: %v`, err)
}
Expand All @@ -34,7 +35,9 @@ func TestBorderClient_CreatesTcpBorderClient(t *testing.T) {
}

func TestBorderClient_UnknownClientType(t *testing.T) {
_, err := NewBorderClient("unknown", nil)
unknownClientType := "unknown"
borderClient := mocks.MockNginxClient{}
_, err := NewBorderClient(unknownClientType, borderClient)
if err == nil {
t.Errorf(`expected error creating border client`)
}
Expand Down
47 changes: 5 additions & 42 deletions internal/application/http_border_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,12 @@
package application

import (
"errors"
"github.com/nginxinc/kubernetes-nginx-ingress/internal/core"
"github.com/nginxinc/kubernetes-nginx-ingress/test/mocks"
nginxClient2 "github.com/nginxinc/nginx-plus-go-client/client"
"testing"
)

const (
clientType = "http"
deletedEventType = core.Deleted
createEventType = core.Created
upstreamName = "upstreamName"
server = "server"
)

var emptyStreamServers = []nginxClient2.StreamUpstreamServer{}

func TestHttpBorderClient_Delete(t *testing.T) {
event := buildServerUpdateEvent(deletedEventType)
borderClient, nginxClient, err := buildBorderClient()
borderClient, nginxClient, err := buildBorderClient(clientTypeHttp)
if err != nil {
t.Fatalf(`error occurred creating a new border client: %v`, err)
}
Expand All @@ -42,7 +28,7 @@ func TestHttpBorderClient_Delete(t *testing.T) {

func TestHttpBorderClient_Update(t *testing.T) {
event := buildServerUpdateEvent(createEventType)
borderClient, nginxClient, err := buildBorderClient()
borderClient, nginxClient, err := buildBorderClient(clientTypeHttp)
if err != nil {
t.Fatalf(`error occurred creating a new border client: %v`, err)
}
Expand All @@ -59,15 +45,15 @@ func TestHttpBorderClient_Update(t *testing.T) {

func TestHttpBorderClient_BadNginxClient(t *testing.T) {
var emptyInterface interface{}
_, err := NewBorderClient(clientType, emptyInterface)
_, err := NewBorderClient(clientTypeHttp, emptyInterface)
if err == nil {
t.Fatalf(`expected an error to occur when creating a new border client`)
}
}

func TestHttpBorderClient_DeleteReturnsError(t *testing.T) {
event := buildServerUpdateEvent(deletedEventType)
borderClient, _, err := buildTerrorizingBorderClient()
borderClient, _, err := buildTerrorizingBorderClient(clientTypeHttp)
if err != nil {
t.Fatalf(`error occurred creating a new border client: %v`, err)
}
Expand All @@ -81,7 +67,7 @@ func TestHttpBorderClient_DeleteReturnsError(t *testing.T) {

func TestHttpBorderClient_UpdateReturnsError(t *testing.T) {
event := buildServerUpdateEvent(createEventType)
borderClient, _, err := buildTerrorizingBorderClient()
borderClient, _, err := buildTerrorizingBorderClient(clientTypeHttp)
if err != nil {
t.Fatalf(`error occurred creating a new border client: %v`, err)
}
Expand All @@ -92,26 +78,3 @@ func TestHttpBorderClient_UpdateReturnsError(t *testing.T) {
t.Fatalf(`expected an error to occur when deleting the nginx+ upstream server`)
}
}

func buildTerrorizingBorderClient() (Interface, *mocks.MockNginxClient, error) {
nginxClient := mocks.NewErroringMockClient(errors.New(`something went horribly horribly wrong`))
bc, err := NewBorderClient(clientType, nginxClient)

return bc, nginxClient, err
}

func buildBorderClient() (Interface, *mocks.MockNginxClient, error) {
nginxClient := mocks.NewMockNginxClient()
bc, err := NewBorderClient(clientType, nginxClient)

return bc, nginxClient, err
}

func buildServerUpdateEvent(eventType core.EventType) core.ServerUpdateEvent {
servers := []nginxClient2.UpstreamServer{
{
Server: server,
},
}
return *core.NewServerUpdateEvent(eventType, upstreamName, emptyStreamServers, servers)
}
31 changes: 28 additions & 3 deletions internal/application/tcp_border_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,41 @@

package application

import "github.com/nginxinc/kubernetes-nginx-ingress/internal/core"
import (
"fmt"
"github.com/nginxinc/kubernetes-nginx-ingress/internal/core"
)

type TcpBorderClient struct {
BorderClient
nginxClient NginxClientInterface
}

func (client *TcpBorderClient) Update(_ core.ServerUpdateEvent) error {
func NewTcpBorderClient(client interface{}) (Interface, error) {
nginxClient, ok := client.(NginxClientInterface)
if !ok {
return nil, fmt.Errorf(`expected a NginxClientInterface, got a %v`, client)
}

return &TcpBorderClient{
nginxClient: nginxClient,
}, nil
}

func (tbc *TcpBorderClient) Update(event core.ServerUpdateEvent) error {
_, _, _, err := tbc.nginxClient.UpdateHTTPServers(event.NginxHost, nil)
if err != nil {
return fmt.Errorf(`error occurred updating the nginx+ upstream server: %w`, err)
}

return nil
}

func (client *TcpBorderClient) Delete(_ core.ServerUpdateEvent) error {
func (tbc *TcpBorderClient) Delete(event core.ServerUpdateEvent) error {
err := tbc.nginxClient.DeleteStreamServer(event.NginxHost, event.TcpServers[0].Server)
if err != nil {
return fmt.Errorf(`error occurred deleting the nginx+ upstream server: %w`, err)
}

return nil
}
74 changes: 74 additions & 0 deletions internal/application/tcp_border_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,77 @@
*/

package application

import (
"testing"
)

func TestTcpBorderClient_Delete(t *testing.T) {
event := buildServerUpdateEvent(deletedEventType)
borderClient, nginxClient, err := buildBorderClient(clientTypeTcp)
if err != nil {
t.Fatalf(`error occurred creating a new border client: %v`, err)
}

err = borderClient.Delete(event)
if err != nil {
t.Fatalf(`error occurred deleting the nginx+ upstream server: %v`, err)
}

if !nginxClient.CalledFunctions["DeleteStreamServer"] {
t.Fatalf(`expected DeleteStreamServer to be called`)
}
}

func TestTcpBorderClient_Update(t *testing.T) {
event := buildServerUpdateEvent(createEventType)
borderClient, nginxClient, err := buildBorderClient(clientTypeTcp)
if err != nil {
t.Fatalf(`error occurred creating a new border client: %v`, err)
}

err = borderClient.Update(event)
if err != nil {
t.Fatalf(`error occurred deleting the nginx+ upstream server: %v`, err)
}

if !nginxClient.CalledFunctions["UpdateHTTPServers"] {
t.Fatalf(`expected UpdateHTTPServers to be called`)
}
}

func TestTcpBorderClient_BadNginxClient(t *testing.T) {
var emptyInterface interface{}
_, err := NewBorderClient(clientTypeTcp, emptyInterface)
if err == nil {
t.Fatalf(`expected an error to occur when creating a new border client`)
}
}

func TestTcpBorderClient_DeleteReturnsError(t *testing.T) {
event := buildServerUpdateEvent(deletedEventType)
borderClient, _, err := buildTerrorizingBorderClient(clientTypeTcp)
if err != nil {
t.Fatalf(`error occurred creating a new border client: %v`, err)
}

err = borderClient.Delete(event)

if err == nil {
t.Fatalf(`expected an error to occur when deleting the nginx+ upstream server`)
}
}

func TestTcpBorderClient_UpdateReturnsError(t *testing.T) {
event := buildServerUpdateEvent(createEventType)
borderClient, _, err := buildTerrorizingBorderClient(clientTypeTcp)
if err != nil {
t.Fatalf(`error occurred creating a new border client: %v`, err)
}

err = borderClient.Update(event)

if err == nil {
t.Fatalf(`expected an error to occur when deleting the nginx+ upstream server`)
}
}