feat: support external traffic policy
Signed-off-by: AhmedGrati <ahmedgrati1999@gmail.com>
This commit is contained in:
@@ -126,6 +126,7 @@ type ServiceConfig struct {
|
||||
User string `compose:"user"`
|
||||
VolumesFrom []string `compose:"volumes_from"`
|
||||
ServiceType string `compose:"kompose.service.type"`
|
||||
ServiceExternalTrafficPolicy string `compose:"kompose.service.external-traffic-policy"`
|
||||
NodePortPort int32 `compose:"kompose.service.nodeport.port"`
|
||||
StopGracePeriod string `compose:"stop_grace_period"`
|
||||
Build string `compose:"build"`
|
||||
|
||||
@@ -698,6 +698,13 @@ func parseKomposeLabels(labels map[string]string, serviceConfig *kobject.Service
|
||||
}
|
||||
|
||||
serviceConfig.ServiceType = serviceType
|
||||
case LabelServiceExternalTrafficPolicy:
|
||||
serviceExternalTypeTrafficPolicy, err := handleServiceExternalTrafficPolicy(value)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "handleServiceExternalTrafficPolicy failed")
|
||||
}
|
||||
|
||||
serviceConfig.ServiceExternalTrafficPolicy = serviceExternalTypeTrafficPolicy
|
||||
case LabelServiceExpose:
|
||||
serviceConfig.ExposeService = strings.Trim(strings.ToLower(value), " ,")
|
||||
case LabelNodePortPort:
|
||||
|
||||
@@ -32,6 +32,8 @@ import (
|
||||
const (
|
||||
// LabelServiceType defines the type of service to be created
|
||||
LabelServiceType = "kompose.service.type"
|
||||
// LabelServiceExternalTrafficPolicy defines the external policy traffic of service to be created
|
||||
LabelServiceExternalTrafficPolicy = "kompose.service.external-traffic-policy"
|
||||
// LabelServiceGroup defines the group of services in a single pod
|
||||
LabelServiceGroup = "kompose.service.group"
|
||||
// LabelNodePortPort defines the port value for NodePort service
|
||||
@@ -151,6 +153,17 @@ func handleServiceType(ServiceType string) (string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func handleServiceExternalTrafficPolicy(ServiceExternalTrafficPolicyType string) (string, error) {
|
||||
switch strings.ToLower(ServiceExternalTrafficPolicyType) {
|
||||
case "", "cluster":
|
||||
return string(api.ServiceExternalTrafficPolicyTypeCluster), nil
|
||||
case "local":
|
||||
return string(api.ServiceExternalTrafficPolicyTypeLocal), nil
|
||||
default:
|
||||
return "", errors.New("Unknown value " + ServiceExternalTrafficPolicyType + " , supported values are 'local, cluster'")
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeContainerNames(svcName string) string {
|
||||
return strings.ToLower(svcName)
|
||||
}
|
||||
|
||||
@@ -1357,6 +1357,7 @@ func (k *Kubernetes) configKubeServiceAndIngressForService(service kobject.Servi
|
||||
if service.ServiceType == "LoadBalancer" {
|
||||
svcs := k.CreateLBService(name, service)
|
||||
for _, svc := range svcs {
|
||||
svc.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyType(service.ServiceExternalTrafficPolicy)
|
||||
*objects = append(*objects, svc)
|
||||
}
|
||||
if len(svcs) > 1 {
|
||||
@@ -1368,11 +1369,17 @@ func (k *Kubernetes) configKubeServiceAndIngressForService(service kobject.Servi
|
||||
if service.ExposeService != "" {
|
||||
*objects = append(*objects, k.initIngress(name, service, svc.Spec.Ports[0].Port))
|
||||
}
|
||||
if service.ServiceExternalTrafficPolicy != "" && svc.Spec.Type != api.ServiceTypeNodePort {
|
||||
log.Warningf("External Traffic Policy is ignored for the service %v of type %v", name, service.ServiceType)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if service.ServiceType == "Headless" {
|
||||
svc := k.CreateHeadlessService(name, service)
|
||||
*objects = append(*objects, svc)
|
||||
if service.ServiceExternalTrafficPolicy != "" {
|
||||
log.Warningf("External Traffic Policy is ignored for the service %v of type Headless", name)
|
||||
}
|
||||
} else {
|
||||
log.Warnf("Service %q won't be created because 'ports' is not specified", service.Name)
|
||||
}
|
||||
|
||||
@@ -93,6 +93,16 @@ func newKomposeObjectHostPortProtocolConfig() kobject.ServiceConfig {
|
||||
}
|
||||
}
|
||||
|
||||
func newServiceConfigWithExternalTrafficPolicy() kobject.ServiceConfig {
|
||||
loadBalancerServiceType := string(api.ServiceTypeLoadBalancer)
|
||||
return kobject.ServiceConfig{
|
||||
Name: "app",
|
||||
Port: []kobject.Ports{{HostPort: 123, ContainerPort: 456}},
|
||||
ServiceType: loadBalancerServiceType,
|
||||
ServiceExternalTrafficPolicy: "local",
|
||||
}
|
||||
}
|
||||
|
||||
func equalStringSlice(s1, s2 []string) bool {
|
||||
if len(s1) != len(s2) {
|
||||
return false
|
||||
@@ -985,3 +995,27 @@ func TestCreateHostPortAndProtocol(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestServiceExternalTrafficPolicy(t *testing.T) {
|
||||
groupName := "pod_group"
|
||||
komposeObject := kobject.KomposeObject{
|
||||
ServiceConfigs: map[string]kobject.ServiceConfig{"app": newServiceConfigWithExternalTrafficPolicy()},
|
||||
}
|
||||
k := Kubernetes{}
|
||||
objs, err := k.Transform(komposeObject, kobject.ConvertOptions{ServiceGroupMode: groupName})
|
||||
if err != nil {
|
||||
t.Error(errors.Wrap(err, "k.Transform failed"))
|
||||
}
|
||||
for _, obj := range objs {
|
||||
if service, ok := obj.(*api.Service); ok {
|
||||
serviceExternalTrafficPolicy := string(service.Spec.ExternalTrafficPolicy)
|
||||
if serviceExternalTrafficPolicy != strings.ToLower(string(api.ServiceExternalTrafficPolicyTypeLocal)) {
|
||||
t.Errorf("Expected Local as external lifecycle policy, got %v", serviceExternalTrafficPolicy)
|
||||
}
|
||||
serviceType := service.Spec.Type
|
||||
if serviceType != api.ServiceTypeLoadBalancer {
|
||||
t.Errorf("Expected LoadBalancer as service type, got %v", serviceType)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,6 +386,7 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
|
||||
if service.ServiceType == "LoadBalancer" {
|
||||
svcs := o.CreateLBService(name, service)
|
||||
for _, svc := range svcs {
|
||||
svc.Spec.ExternalTrafficPolicy = corev1.ServiceExternalTrafficPolicyType(service.ServiceExternalTrafficPolicy)
|
||||
objects = append(objects, svc)
|
||||
}
|
||||
if len(svcs) > 1 {
|
||||
@@ -398,10 +399,16 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
|
||||
if service.ExposeService != "" {
|
||||
objects = append(objects, o.initRoute(name, service, svc.Spec.Ports[0].Port))
|
||||
}
|
||||
if service.ServiceExternalTrafficPolicy != "" && svc.Spec.Type != corev1.ServiceTypeNodePort {
|
||||
log.Warningf("External Traffic Policy is ignored for the service %v of type %v", name, service.ServiceType)
|
||||
}
|
||||
}
|
||||
} else if service.ServiceType == "Headless" {
|
||||
svc := o.CreateHeadlessService(name, service)
|
||||
objects = append(objects, svc)
|
||||
if service.ServiceExternalTrafficPolicy != "" {
|
||||
log.Warningf("External Traffic Policy is ignored for the service %v of type Headless", name)
|
||||
}
|
||||
}
|
||||
|
||||
err := o.UpdateKubernetesObjects(name, service, opt, &objects)
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/kubernetes/kompose/pkg/kobject"
|
||||
@@ -56,6 +57,16 @@ func newServiceConfig() kobject.ServiceConfig {
|
||||
}
|
||||
}
|
||||
|
||||
func newServiceConfigWithExternalTrafficPolicy() kobject.ServiceConfig {
|
||||
loadBalancerServiceType := string(corev1.ServiceTypeLoadBalancer)
|
||||
return kobject.ServiceConfig{
|
||||
Name: "app",
|
||||
Port: []kobject.Ports{{HostPort: 123, ContainerPort: 456}},
|
||||
ServiceType: loadBalancerServiceType,
|
||||
ServiceExternalTrafficPolicy: "local",
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenShiftUpdateKubernetesObjects(t *testing.T) {
|
||||
t.Log("Test case: Testing o.UpdateKubernetesObjects()")
|
||||
var object []runtime.Object
|
||||
@@ -425,3 +436,27 @@ func TestRecreateStrategyWithVolumesPresent(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestServiceExternalTrafficPolicy(t *testing.T) {
|
||||
groupName := "pod_group"
|
||||
komposeObject := kobject.KomposeObject{
|
||||
ServiceConfigs: map[string]kobject.ServiceConfig{"app": newServiceConfigWithExternalTrafficPolicy()},
|
||||
}
|
||||
o := OpenShift{}
|
||||
objs, err := o.Transform(komposeObject, kobject.ConvertOptions{ServiceGroupMode: groupName})
|
||||
if err != nil {
|
||||
t.Error(errors.Wrap(err, "k.Transform failed"))
|
||||
}
|
||||
for _, obj := range objs {
|
||||
if service, ok := obj.(*corev1.Service); ok {
|
||||
serviceExternalTrafficPolicy := string(service.Spec.ExternalTrafficPolicy)
|
||||
if serviceExternalTrafficPolicy != strings.ToLower(string(corev1.ServiceExternalTrafficPolicyTypeLocal)) {
|
||||
t.Errorf("Expected Local as external lifecycle policy, got %v", serviceExternalTrafficPolicy)
|
||||
}
|
||||
serviceType := service.Spec.Type
|
||||
if serviceType != corev1.ServiceTypeLoadBalancer {
|
||||
t.Errorf("Expected LoadBalancer as service type, got %v", serviceType)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user