Skip to content

Commit c2013e7

Browse files
author
wujideng
committed
fix: fix set service type to nodeport or loadbalancer, but get default type
1 parent fb0539e commit c2013e7

File tree

5 files changed

+180
-11
lines changed

5 files changed

+180
-11
lines changed

pkg/kobject/kobject.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package kobject
1919
import (
2020
"path/filepath"
2121
"strconv"
22+
"strings"
2223
"time"
2324

2425
"github.com/compose-spec/compose-go/v2/types"
@@ -27,6 +28,7 @@ import (
2728
"github.com/spf13/cast"
2829
v1 "k8s.io/api/apps/v1"
2930
batchv1 "k8s.io/api/batch/v1"
31+
api "k8s.io/api/core/v1"
3032
"k8s.io/apimachinery/pkg/util/intstr"
3133
)
3234

@@ -349,3 +351,62 @@ func (s *ServiceConfig) GetOSUpdateStrategy() *deployapi.RollingDeploymentStrate
349351

350352
return nil
351353
}
354+
355+
func (s *ServiceConfig) CheckServiceType() error {
356+
svcType := s.ServiceType
357+
typeFromLabel := s.DeployLabels["kompose.service.type"]
358+
if len(svcType) != 0 {
359+
return nil
360+
} else if len(typeFromLabel) != 0 {
361+
_, err := handleServiceType(typeFromLabel)
362+
if err != nil {
363+
return err
364+
}
365+
return nil
366+
}
367+
return nil
368+
}
369+
370+
func (s *ServiceConfig) GetServiceType() string {
371+
svcType := s.ServiceType
372+
typeFromLabel := s.DeployLabels["kompose.service.type"]
373+
if len(svcType) != 0 {
374+
return svcType
375+
} else if len(typeFromLabel) != 0 {
376+
res, err := handleServiceType(typeFromLabel)
377+
if err != nil {
378+
return ""
379+
}
380+
return res
381+
}
382+
return ""
383+
}
384+
385+
func (s *ServiceConfig) GetServiceNodePort() int32 {
386+
port := s.NodePortPort
387+
var portFromLabel int32
388+
if labelPort, ok := s.DeployLabels["kompose.service.nodeport.port"]; ok {
389+
portFromLabel = cast.ToInt32(labelPort)
390+
}
391+
if port != 0 {
392+
return port
393+
} else if portFromLabel != 0 {
394+
return portFromLabel
395+
}
396+
return 0
397+
}
398+
399+
func handleServiceType(ServiceType string) (string, error) {
400+
switch strings.ToLower(ServiceType) {
401+
case "", "clusterip":
402+
return string(api.ServiceTypeClusterIP), nil
403+
case "nodeport":
404+
return string(api.ServiceTypeNodePort), nil
405+
case "loadbalancer":
406+
return string(api.ServiceTypeLoadBalancer), nil
407+
case "headless":
408+
return "Headless", nil
409+
default:
410+
return "", errors.New("Unknown value " + ServiceType + " , supported values are 'nodeport, clusterip, headless or loadbalancer'")
411+
}
412+
}

pkg/transformer/kubernetes/k8sutils.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ func (k *Kubernetes) initSvcObject(name string, service kobject.ServiceConfig, p
432432
svc.Spec.Selector = transformer.ConfigLabels(service.Name)
433433

434434
svc.Spec.Ports = ports
435-
svc.Spec.Type = api.ServiceType(service.ServiceType)
435+
svc.Spec.Type = api.ServiceType(service.GetServiceType())
436436

437437
// Configure annotations
438438
annotations := transformer.ConfigAnnotations(service)
@@ -458,17 +458,18 @@ func (k *Kubernetes) CreateLBService(name string, service kobject.ServiceConfig)
458458

459459
// CreateService creates a k8s service
460460
func (k *Kubernetes) CreateService(name string, service kobject.ServiceConfig) *api.Service {
461+
serviceType := service.GetServiceType()
461462
svc := k.InitSvc(name, service)
462463

463464
// Configure the service ports.
464465
servicePorts := k.ConfigServicePorts(service)
465466
svc.Spec.Ports = servicePorts
466467

467-
if service.ServiceType == "Headless" {
468+
if serviceType == "Headless" {
468469
svc.Spec.Type = api.ServiceTypeClusterIP
469470
svc.Spec.ClusterIP = "None"
470471
} else {
471-
svc.Spec.Type = api.ServiceType(service.ServiceType)
472+
svc.Spec.Type = api.ServiceType(serviceType)
472473
}
473474

474475
// Configure annotations

pkg/transformer/kubernetes/k8sutils_test.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,98 @@ func TestCreateServiceWithServiceUser(t *testing.T) {
329329
}
330330
}
331331

332+
/*
333+
Test the creation of a service with service type NodePort.
334+
The expected result is that Kompose will set user in PodSpec
335+
*/
336+
func TestCreateServiceWithServiceTypeNodePort(t *testing.T) {
337+
// An example service
338+
service := kobject.ServiceConfig{
339+
ContainerName: "name",
340+
Image: "image",
341+
Environment: []kobject.EnvVar{{Name: "env", Value: "value"}},
342+
Port: []kobject.Ports{{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
343+
Command: []string{"cmd"},
344+
WorkingDir: "dir",
345+
Args: []string{"arg1", "arg2"},
346+
VolList: []string{"/tmp/volume"},
347+
Network: []string{"network1", "network2"}, // not supported
348+
DeployLabels: map[string]string{"kompose.service.type": "nodeport", "kompose.service": "my-service"},
349+
Annotations: map[string]string{"kompose.service.type": "nodeport"},
350+
CPUQuota: 1, // not supported
351+
CapAdd: []string{"cap_add"}, // not supported
352+
CapDrop: []string{"cap_drop"}, // not supported
353+
Expose: []string{"expose"}, // not supported
354+
Privileged: true,
355+
Restart: "always",
356+
User: "1234:5678",
357+
}
358+
359+
komposeObject := kobject.KomposeObject{
360+
ServiceConfigs: map[string]kobject.ServiceConfig{"app": service},
361+
}
362+
k := Kubernetes{}
363+
364+
objects, err := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 1})
365+
if err != nil {
366+
t.Error(errors.Wrap(err, "k.Transform failed"))
367+
}
368+
369+
for _, obj := range objects {
370+
if svc, ok := obj.(*corev1.Service); ok {
371+
if svc.Spec.Type != corev1.ServiceTypeNodePort {
372+
t.Errorf("Service type is not NodePort")
373+
}
374+
}
375+
}
376+
}
377+
378+
/*
379+
Test the creation of a service with service type LoadBalancer.
380+
The expected result is that Kompose will set user in PodSpec
381+
*/
382+
func TestCreateServiceWithServiceTypeLoadBalancer(t *testing.T) {
383+
// An example service
384+
service := kobject.ServiceConfig{
385+
ContainerName: "name",
386+
Image: "image",
387+
Environment: []kobject.EnvVar{{Name: "env", Value: "value"}},
388+
Port: []kobject.Ports{{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
389+
Command: []string{"cmd"},
390+
WorkingDir: "dir",
391+
Args: []string{"arg1", "arg2"},
392+
VolList: []string{"/tmp/volume"},
393+
Network: []string{"network1", "network2"}, // not supported
394+
DeployLabels: map[string]string{"kompose.service.type": "loadbalancer", "kompose.service": "my-service"},
395+
Annotations: map[string]string{"kompose.service.type": "loadbalancer"},
396+
CPUQuota: 1, // not supported
397+
CapAdd: []string{"cap_add"}, // not supported
398+
CapDrop: []string{"cap_drop"}, // not supported
399+
Expose: []string{"expose"}, // not supported
400+
Privileged: true,
401+
Restart: "always",
402+
User: "1234:5678",
403+
}
404+
405+
komposeObject := kobject.KomposeObject{
406+
ServiceConfigs: map[string]kobject.ServiceConfig{"app": service},
407+
}
408+
k := Kubernetes{}
409+
410+
objects, err := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 1})
411+
if err != nil {
412+
t.Error(errors.Wrap(err, "k.Transform failed"))
413+
}
414+
415+
for _, obj := range objects {
416+
if svc, ok := obj.(*corev1.Service); ok {
417+
if svc.Spec.Type != corev1.ServiceTypeLoadBalancer {
418+
t.Errorf("Service type is not NodePort")
419+
}
420+
}
421+
}
422+
}
423+
332424
func TestCreateServiceWithConfigLongSyntax(t *testing.T) {
333425
content := "setting: true"
334426
target := "/etc/config.yaml"

pkg/transformer/kubernetes/kubernetes.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,7 @@ func (k *Kubernetes) ConfigServicePorts(service kobject.ServiceConfig) []api.Ser
752752
servicePorts := []api.ServicePort{}
753753
seenPorts := make(map[int]struct{}, len(service.Port))
754754

755+
serviceType := service.GetServiceType()
755756
var servicePort api.ServicePort
756757
for _, port := range service.Port {
757758
if port.HostPort == 0 {
@@ -766,7 +767,7 @@ func (k *Kubernetes) ConfigServicePorts(service kobject.ServiceConfig) []api.Ser
766767
name := strconv.Itoa(int(port.HostPort))
767768
if _, ok := seenPorts[int(port.HostPort)]; ok {
768769
// https://github.com/kubernetes/kubernetes/issues/2995
769-
if service.ServiceType == string(api.ServiceTypeLoadBalancer) {
770+
if serviceType == string(api.ServiceTypeLoadBalancer) {
770771
log.Fatalf("Service %s of type LoadBalancer cannot use TCP and UDP for the same port", name)
771772
}
772773
name = fmt.Sprintf("%s-%s", name, strings.ToLower(port.Protocol))
@@ -778,8 +779,9 @@ func (k *Kubernetes) ConfigServicePorts(service kobject.ServiceConfig) []api.Ser
778779
TargetPort: targetPort,
779780
}
780781

781-
if service.ServiceType == string(api.ServiceTypeNodePort) && service.NodePortPort != 0 {
782-
servicePort.NodePort = service.NodePortPort
782+
nodePortPort := service.GetServiceNodePort()
783+
if serviceType == string(api.ServiceTypeNodePort) && nodePortPort != 0 {
784+
servicePort.NodePort = nodePortPort
783785
}
784786

785787
// If the default is already TCP, no need to include protocol.
@@ -1491,9 +1493,14 @@ func buildServiceImage(opt kobject.ConvertOptions, service kobject.ServiceConfig
14911493
return nil
14921494
}
14931495

1494-
func (k *Kubernetes) configKubeServiceAndIngressForService(service kobject.ServiceConfig, name string, objects *[]runtime.Object) {
1496+
func (k *Kubernetes) configKubeServiceAndIngressForService(service kobject.ServiceConfig, name string, objects *[]runtime.Object) error {
1497+
err := service.CheckServiceType()
1498+
if err != nil {
1499+
return err
1500+
}
1501+
svcType := service.GetServiceType()
14951502
if k.PortsExist(service) {
1496-
if service.ServiceType == "LoadBalancer" {
1503+
if svcType == "LoadBalancer" {
14971504
svcs := k.CreateLBService(name, service)
14981505
for _, svc := range svcs {
14991506
svc.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyType(service.ServiceExternalTrafficPolicy)
@@ -1513,7 +1520,7 @@ func (k *Kubernetes) configKubeServiceAndIngressForService(service kobject.Servi
15131520
}
15141521
}
15151522
} else {
1516-
if service.ServiceType == "Headless" {
1523+
if svcType == "Headless" {
15171524
svc := k.CreateHeadlessService(name, service)
15181525
*objects = append(*objects, svc)
15191526
if service.ServiceExternalTrafficPolicy != "" {
@@ -1523,6 +1530,7 @@ func (k *Kubernetes) configKubeServiceAndIngressForService(service kobject.Servi
15231530
log.Warnf("Service %q won't be created because 'ports' is not specified", service.Name)
15241531
}
15251532
}
1533+
return nil
15261534
}
15271535

15281536
func (k *Kubernetes) configNetworkPolicyForService(service kobject.ServiceConfig, name string, objects *[]runtime.Object) error {
@@ -1610,7 +1618,9 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
16101618
}
16111619
// override..
16121620
objects = append(objects, k.CreateWorkloadAndConfigMapObjects(groupName, service, opt)...)
1613-
k.configKubeServiceAndIngressForService(service, groupName, &objects)
1621+
if err := k.configKubeServiceAndIngressForService(service, groupName, &objects); err != nil {
1622+
return nil, err
1623+
}
16141624

16151625
// Configure the container volumes.
16161626
volumesMount, volumes, pvc, cms, err := k.ConfigVolumes(groupName, service)
@@ -1706,7 +1716,9 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
17061716
if opt.Controller == StatefulStateController {
17071717
service.ServiceType = "Headless"
17081718
}
1709-
k.configKubeServiceAndIngressForService(service, name, &objects)
1719+
if err := k.configKubeServiceAndIngressForService(service, name, &objects); err != nil {
1720+
return nil, err
1721+
}
17101722
err := k.UpdateKubernetesObjects(name, service, opt, &objects)
17111723
if err != nil {
17121724
return nil, errors.Wrap(err, "Error transforming Kubernetes objects")

pkg/transformer/openshift/openshift.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,9 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
408408
log.Warningf("Create multiple service to avoid using mixed protocol in the same service when it's loadbalancer type")
409409
}
410410
} else {
411+
if err = service.CheckServiceType(); err != nil {
412+
return nil, errors.Wrap(err, "CheckServiceType failed")
413+
}
411414
svc := o.CreateService(name, service)
412415
objects = append(objects, svc)
413416

0 commit comments

Comments
 (0)