Skip to content

Commit

Permalink
MEDIUM: #530 add tcp services annotation capability
Browse files Browse the repository at this point in the history
  • Loading branch information
benm-stm committed Apr 5, 2023
1 parent 8f75a01 commit 5d2e48b
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 2 deletions.
20 changes: 18 additions & 2 deletions pkg/handler/tcp-services.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type tcpSvcParser struct {
service *store.Service
port int64
sslOffload bool
annList map[string]string
}

func (handler TCPServices) Update(k store.K8s, h haproxy.HAProxy, a annotations.Annotations) (reload bool, err error) {
Expand Down Expand Up @@ -65,18 +66,33 @@ func (handler TCPServices) parseTCPService(store store.K8s, input string) (p tcp
// parts[0]: Service Name
// parts[1]: Service Port
// parts[2]: SSL option
// parts[3]: Annotations separated by commas ex: annotation1=value,annotation2=value
parts := strings.Split(input, ":")
if len(parts) < 2 {
err = fmt.Errorf("incorrect format '%s', 'ServiceName:ServicePort' is required", input)
return
}
svcName := strings.Split(parts[0], "/")
svcPort := parts[1]
if len(parts) > 2 {
if len(parts) == 3 {
if parts[2] == "ssl" {
p.sslOffload = true
}
}
if len(parts) > 3 {
if parts[2] == "ssl" {
p.sslOffload = true
}
svcOpts := strings.Split(parts[3], ",")
annList := map[string]string{}
for _, v := range svcOpts {
ann := strings.Split(v, "=")
if len(ann) > 0 {
annList[ann[0]] = ann[1]
}
}
p.annList = annList
}
if len(svcName) != 2 {
err = fmt.Errorf("incorrect Service Name '%s'. Should be in 'ServiceNS/ServiceName' format", parts[0])
return
Expand Down Expand Up @@ -198,7 +214,7 @@ func (handler TCPServices) updateTCPFrontend(k store.K8s, h haproxy.HAProxy, fro
SvcPortInt: p.port,
IsDefaultBackend: true,
}
if svc, err = service.New(k, path, nil, true); err == nil {
if svc, err = service.New(k, path, nil, true, p.annList); err == nil {
r, err = svc.SetDefaultBackend(k, h, []string{frontend.Name}, a)
}
return reload || r, err
Expand Down
122 changes: 122 additions & 0 deletions pkg/handler/tcp-services_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package handler

import (
"reflect"
"testing"

"github.com/haproxytech/kubernetes-ingress/pkg/store"
)

var (
tcpServivesTest = TCPServices{}
k8sStoreTest = store.K8s{
Namespaces: map[string]*store.Namespace{},
}
)

func TestParseTCPService(t *testing.T) {
type ioTest struct {
input string
output tcpSvcParser
}
// initialize
k8sStoreTest.Namespaces["ns"] = &store.Namespace{
Name: "ns",
Relevant: false,
Ingresses: map[string]*store.Ingress{},
Endpoints: map[string]map[string]*store.Endpoints{},
Services: map[string]*store.Service{},
Secret: map[string]*store.Secret{},
HAProxyRuntime: map[string]map[string]*store.RuntimeBackend{},
CRs: &store.CustomResources{},
Gateways: map[string]*store.Gateway{},
TCPRoutes: map[string]*store.TCPRoute{},
ReferenceGrants: map[string]*store.ReferenceGrant{},
Labels: map[string]string{},
Status: "",
}
k8sStoreTest.Namespaces["ns"].Services["svc"] = &store.Service{
Namespace: "ns",
Name: "svc",
Ports: []store.ServicePort{},
Addresses: []string{},
DNS: "",
Annotations: map[string]string{},
Status: "",
}
ioParserTest := [...]ioTest{
{
"ns/svc:8888",
tcpSvcParser{
service: &store.Service{
Namespace: "ns",
Name: "svc",
},
port: 8888,
sslOffload: false,
annList: map[string]string{},
},
},
{
"ns/svc:8888:ssl",
tcpSvcParser{
service: &store.Service{
Namespace: "ns",
Name: "svc",
},
port: 8888,
sslOffload: true,
annList: map[string]string{},
},
},
{
"ns/svc:8888:ssl:load-balance=leastconn,default-server=check",
tcpSvcParser{
service: &store.Service{
Namespace: "ns",
Name: "svc",
},
port: 8888,
sslOffload: true,
annList: map[string]string{
"load-balance": "leastconn",
"default-server": "check",
},
},
},
{
"ns/svc:8888:ssl:load-balance=leastconn,default-server=check:todo",
tcpSvcParser{
service: &store.Service{
Namespace: "ns",
Name: "svc",
},
port: 8888,
sslOffload: true,
annList: map[string]string{
"load-balance": "leastconn",
"default-server": "check",
},
},
},
}

for _, v := range ioParserTest {
p, err := tcpServivesTest.parseTCPService(k8sStoreTest, v.input)
if err != nil {
t.Errorf("got error %v", err)
}
if !reflect.DeepEqual(p.annList, v.output.annList) && (len(p.annList) != 0 && len(v.output.annList) != 0) {
t.Errorf("got %v, wanted %v", p.annList, v.output.annList)
}
if p.port != v.output.port {
t.Errorf("got %v, wanted %v", p.port, v.output.port)
}
if p.service.Name != v.output.service.Name || p.service.Namespace != v.output.service.Namespace {
t.Errorf("got %v, wanted %v", p.port, v.output.service.Ports[0])
}
if p.sslOffload != v.output.sslOffload {
t.Errorf("got %v, wanted %v", p.sslOffload, v.output.sslOffload)
}
}
}

0 comments on commit 5d2e48b

Please sign in to comment.