fix: send service ports on lb allocate
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
@@ -163,10 +164,15 @@ func (c *Controller) sync(ctx context.Context, key string) error {
|
|||||||
if ingressIP(svc) != "" {
|
if ingressIP(svc) != "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
ports, err := servicePortsToAllocateRules(svc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
lb, err := c.lbClient.Allocate(ctx, provisioner.AllocateRequest{
|
lb, err := c.lbClient.Allocate(ctx, provisioner.AllocateRequest{
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
Ports: ports,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -217,6 +223,29 @@ func ingressIP(svc *corev1.Service) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func servicePortsToAllocateRules(svc *corev1.Service) ([]provisioner.AllocatePortRule, error) {
|
||||||
|
if svc == nil {
|
||||||
|
return nil, fmt.Errorf("service is required")
|
||||||
|
}
|
||||||
|
if len(svc.Spec.Ports) == 0 {
|
||||||
|
return nil, fmt.Errorf("service %s/%s has no ports", svc.Namespace, svc.Name)
|
||||||
|
}
|
||||||
|
out := make([]provisioner.AllocatePortRule, 0, len(svc.Spec.Ports))
|
||||||
|
for _, p := range svc.Spec.Ports {
|
||||||
|
protocol := string(p.Protocol)
|
||||||
|
if protocol == "" {
|
||||||
|
protocol = string(corev1.ProtocolTCP)
|
||||||
|
}
|
||||||
|
switch protocol {
|
||||||
|
case string(corev1.ProtocolTCP), string(corev1.ProtocolUDP):
|
||||||
|
out = append(out, provisioner.AllocatePortRule{Protocol: strings.ToLower(protocol), PortFrom: int(p.Port)})
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("service %s/%s has unsupported protocol %q for load balancer firewall", svc.Namespace, svc.Name, protocol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
func containsString(items []string, target string) bool {
|
func containsString(items []string, target string) bool {
|
||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
if item == target {
|
if item == target {
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestServicePortsToAllocateRules(t *testing.T) {
|
||||||
|
svc := &corev1.Service{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "web"},
|
||||||
|
Spec: corev1.ServiceSpec{Ports: []corev1.ServicePort{{Port: 80, Protocol: corev1.ProtocolTCP}, {Port: 53, Protocol: corev1.ProtocolUDP}}},
|
||||||
|
}
|
||||||
|
|
||||||
|
rules, err := servicePortsToAllocateRules(svc)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("servicePortsToAllocateRules: %v", err)
|
||||||
|
}
|
||||||
|
if len(rules) != 2 {
|
||||||
|
t.Fatalf("rules count = %d, want 2", len(rules))
|
||||||
|
}
|
||||||
|
if rules[0].Protocol != "tcp" || rules[0].PortFrom != 80 {
|
||||||
|
t.Fatalf("unexpected first rule: %+v", rules[0])
|
||||||
|
}
|
||||||
|
if rules[1].Protocol != "udp" || rules[1].PortFrom != 53 {
|
||||||
|
t.Fatalf("unexpected second rule: %+v", rules[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServicePortsToAllocateRulesRejectsUnsupportedProtocol(t *testing.T) {
|
||||||
|
svc := &corev1.Service{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "web"},
|
||||||
|
Spec: corev1.ServiceSpec{Ports: []corev1.ServicePort{{Port: 80, Protocol: corev1.ProtocolSCTP}}},
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := servicePortsToAllocateRules(svc); err == nil {
|
||||||
|
t.Fatal("expected error for unsupported protocol")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServicePortsToAllocateRulesRejectsNoPorts(t *testing.T) {
|
||||||
|
svc := &corev1.Service{ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "web"}}
|
||||||
|
if _, err := servicePortsToAllocateRules(svc); err == nil {
|
||||||
|
t.Fatal("expected error for empty ports")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,4 +10,11 @@ type LoadBalancer struct {
|
|||||||
type AllocateRequest struct {
|
type AllocateRequest struct {
|
||||||
Namespace string `json:"namespace"`
|
Namespace string `json:"namespace"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
Ports []AllocatePortRule `json:"ports,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AllocatePortRule struct {
|
||||||
|
Protocol string `json:"protocol"`
|
||||||
|
PortFrom int `json:"portFrom"`
|
||||||
|
PortTo *int `json:"portTo,omitempty"`
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user