Repository: kubernetes/kompose
Pull request #1438 (2021-10-02 19:55:21)

Refactor

k8s-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes/kompose/pull/1438#" title="Author self-approved">hangyan</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes%2Fkompose).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubernetes/kompose/blob/master/OWNERS)~~ [hangyan]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->

Patch:
diff --git a/pkg/loader/compose/utils.go b/pkg/loader/compose/utils.go
index 7a800ab0..d9be422f 100644
--- a/pkg/loader/compose/utils.go
+++ b/pkg/loader/compose/utils.go
@@ -156,7 +156,7 @@ func normalizeVolumes(svcName string) string {
 
 func normalizeNetworkNames(netName string) (string, error) {
 	netval := strings.ToLower(strings.Replace(netName, "_", "-", -1))
-	regString := ("[^A-Za-z0-9.-]+")
+	regString := "[^A-Za-z0-9.-]+"
 	reg, err := regexp.Compile(regString)
 	if err != nil {
 		return "", err
diff --git a/pkg/loader/compose/v1v2.go b/pkg/loader/compose/v1v2.go
index a61ae1e0..5d800e55 100644
--- a/pkg/loader/compose/v1v2.go
+++ b/pkg/loader/compose/v1v2.go
@@ -231,7 +231,7 @@ func libComposeToKomposeMapping(composeObject *project.Project) (kobject.Kompose
 		}
 
 		// convert compose labels to annotations
-		serviceConfig.Annotations = map[string]string(composeServiceConfig.Labels)
+		serviceConfig.Annotations = composeServiceConfig.Labels
 		serviceConfig.CPUQuota = int64(composeServiceConfig.CPUQuota)
 		serviceConfig.CapAdd = composeServiceConfig.CapAdd
 		serviceConfig.CapDrop = composeServiceConfig.CapDrop
diff --git a/pkg/loader/compose/v3.go b/pkg/loader/compose/v3.go
index 8ba96add..fc6e36e9 100644
--- a/pkg/loader/compose/v3.go
+++ b/pkg/loader/compose/v3.go
@@ -382,7 +382,7 @@ func dockerComposeToKomposeMapping(composeObject *types.Config) (kobject.Kompose
 		serviceConfig.Name = name
 		serviceConfig.Image = composeServiceConfig.Image
 		serviceConfig.WorkingDir = composeServiceConfig.WorkingDir
-		serviceConfig.Annotations = map[string]string(composeServiceConfig.Labels)
+		serviceConfig.Annotations = composeServiceConfig.Labels
 		serviceConfig.CapAdd = composeServiceConfig.CapAdd
 		serviceConfig.CapDrop = composeServiceConfig.CapDrop
 		serviceConfig.Expose = composeServiceConfig.Expose
diff --git a/pkg/transformer/kubernetes/k8sutils.go b/pkg/transformer/kubernetes/k8sutils.go
index dc42f048..7ebc6291 100644
--- a/pkg/transformer/kubernetes/k8sutils.go
+++ b/pkg/transformer/kubernetes/k8sutils.go
@@ -199,7 +199,7 @@ func PrintList(objects []runtime.Object, opt kobject.ConvertOptions) error {
 		list := &api.List{}
 		// convert objects to versioned and add them to list
 		for _, object := range objects {
-			versionedObject, err := convertToVersion(object, metav1.GroupVersion{})
+			versionedObject, err := convertToVersion(object)
 			if err != nil {
 				return err
 			}
@@ -207,10 +207,9 @@ func PrintList(objects []runtime.Object, opt kobject.ConvertOptions) error {
 			list.Items = append(list.Items, objectToRaw(versionedObject))
 		}
 		// version list itself
-		listVersion := metav1.GroupVersion{Group: "", Version: "v1"}
 		list.Kind = "List"
 		list.APIVersion = "v1"
-		convertedList, err := convertToVersion(list, listVersion)
+		convertedList, err := convertToVersion(list)
 		if err != nil {
 			return err
 		}
@@ -236,7 +235,7 @@ func PrintList(objects []runtime.Object, opt kobject.ConvertOptions) error {
 		var file string
 		// create a separate file for each provider
 		for _, v := range objects {
-			versionedObject, err := convertToVersion(v, metav1.GroupVersion{})
+			versionedObject, err := convertToVersion(v)
 			if err != nil {
 				return err
 			}
@@ -340,7 +339,7 @@ func marshalWithIndent(o interface{}, indent int) ([]byte, error) {
 
 // Convert object to versioned object
 // if groupVersion is  empty (metav1.GroupVersion{}), use version from original object (obj)
-func convertToVersion(obj runtime.Object, groupVersion metav1.GroupVersion) (runtime.Object, error) {
+func convertToVersion(obj runtime.Object) (runtime.Object, error) {
 	// ignore unstruct object
 	if _, ok := obj.(*unstructured.Unstructured); ok {
 		return obj, nil
@@ -368,20 +367,6 @@ func (k *Kubernetes) PortsExist(service kobject.ServiceConfig) bool {
 	return len(service.Port) != 0
 }
 
-func (k *Kubernetes) CreateLBService(name string, service kobject.ServiceConfig, objects []runtime.Object) []*api.Service {
-	var svcs []*api.Service
-	tcpPorts, udpPorts := k.ConfigLBServicePorts(name, service)
-	if tcpPorts != nil {
-		svc := k.initSvcObject(name+"-tcp", service, tcpPorts)
-		svcs = append(svcs, svc)
-	}
-	if udpPorts != nil {
-		svc := k.initSvcObject(name+"-udp", service, udpPorts)
-		svcs = append(svcs, svc)
-	}
-	return svcs
-}
-
 func (k *Kubernetes) initSvcObject(name string, service kobject.ServiceConfig, ports []api.ServicePort) *api.Service {
 	svc := k.InitSvc(name, service)
 	svc.Spec.Ports = ports
@@ -395,12 +380,26 @@ func (k *Kubernetes) initSvcObject(name string, service kobject.ServiceConfig, p
 	return svc
 }
 
+func (k *Kubernetes) CreateLBService(name string, service kobject.ServiceConfig) []*api.Service {
+	var svcs []*api.Service
+	tcpPorts, udpPorts := k.ConfigLBServicePorts(service)
+	if tcpPorts != nil {
+		svc := k.initSvcObject(name+"-tcp", service, tcpPorts)
+		svcs = append(svcs, svc)
+	}
+	if udpPorts != nil {
+		svc := k.initSvcObject(name+"-udp", service, udpPorts)
+		svcs = append(svcs, svc)
+	}
+	return svcs
+}
+
 // CreateService creates a k8s service
-func (k *Kubernetes) CreateService(name string, service kobject.ServiceConfig, objects []runtime.Object) *api.Service {
+func (k *Kubernetes) CreateService(name string, service kobject.ServiceConfig) *api.Service {
 	svc := k.InitSvc(name, service)
 
 	// Configure the service ports.
-	servicePorts := k.ConfigServicePorts(name, service)
+	servicePorts := k.ConfigServicePorts(service)
 	svc.Spec.Ports = servicePorts
 
 	if service.ServiceType == "Headless" {
@@ -422,10 +421,10 @@ func (k *Kubernetes) CreateService(name string, service kobject.ServiceConfig, o
 // and without Service Pods can't find each other using DNS names.
 // Instead of regular Kubernetes Service we create Headless Service. DNS of such service points directly to Pod IP address.
 // You can find more about Headless Services in Kubernetes documentation https://kubernetes.io/docs/user-guide/services/#headless-services
-func (k *Kubernetes) CreateHeadlessService(name string, service kobject.ServiceConfig, objects []runtime.Object) *api.Service {
+func (k *Kubernetes) CreateHeadlessService(name string, service kobject.ServiceConfig) *api.Service {
 	svc := k.InitSvc(name, service)
 
-	servicePorts := []api.ServicePort{}
+	var servicePorts []api.ServicePort
 	// Configure a dummy port: https://github.com/kubernetes/kubernetes/issues/32766.
 	servicePorts = append(servicePorts, api.ServicePort{
 		Name: "headless",
@@ -441,7 +440,7 @@ func (k *Kubernetes) CreateHeadlessService(name string, service kobject.ServiceC
 
 	return svc
 }
-func (k *Kubernetes) UpdateKubernetesObjectsMultipleContainers(name string, service kobject.ServiceConfig, opt kobject.ConvertOptions, objects *[]runtime.Object, podSpec PodSpec) error {
+func (k *Kubernetes) UpdateKubernetesObjectsMultipleContainers(name string, service kobject.ServiceConfig, objects *[]runtime.Object, podSpec PodSpec) error {
 	// Configure annotations
 	annotations := transformer.ConfigAnnotations(service)
 
@@ -478,7 +477,7 @@ func (k *Kubernetes) UpdateKubernetesObjectsMultipleContainers(name string, serv
 // UpdateKubernetesObjects loads configurations to k8s objects
 func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.ServiceConfig, opt kobject.ConvertOptions, objects *[]runtime.Object) error {
 	// Configure the environment variables.
-	envs, err := ConfigEnvs(name, service, opt)
+	envs, err := ConfigEnvs(service, opt)
 	if err != nil {
 		return errors.Wrap(err, "Unable to load env variables")
 	}
@@ -491,9 +490,7 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
 	// Configure Tmpfs
 	if len(service.TmpFs) > 0 {
 		TmpVolumesMount, TmpVolumes := k.ConfigTmpfs(name, service)
-
 		volumes = append(volumes, TmpVolumes...)
-
 		volumesMount = append(volumesMount, TmpVolumesMount...)
 	}
 
@@ -513,7 +510,7 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
 	}
 
 	// Configure the container ports.
-	ports := ConfigPorts(name, service)
+	ports := ConfigPorts(service)
 
 	// Configure capabilities
 	capabilities := ConfigCapabilities(service)
@@ -798,7 +795,7 @@ func (k *Kubernetes) SortServicesFirst(objs *[]runtime.Object) {
 }
 
 // RemoveDupObjects remove objects that are dups...eg. configmaps from env.
-// since we know for sure that the duplication can only happens on ConfigMap, so
+// since we know for sure that the duplication can only happen on ConfigMap, so
 // this code will looks like this for now.
 // + NetworkPolicy
 func (k *Kubernetes) RemoveDupObjects(objs *[]runtime.Object) {
diff --git a/pkg/transformer/kubernetes/kubernetes.go b/pkg/transformer/kubernetes/kubernetes.go
index 3fcc83cf..6efd558c 100644
--- a/pkg/transformer/kubernetes/kubernetes.go
+++ b/pkg/transformer/kubernetes/kubernetes.go
@@ -55,10 +55,6 @@ type Kubernetes struct {
 	Opt kobject.ConvertOptions
 }
 
-// TIMEOUT is how long we'll wait for the termination of kubernetes resource to be successful
-// used when undeploying resources from kubernetes
-const TIMEOUT = 300
-
 // PVCRequestSize (Persistent Volume Claim) has default size
 const PVCRequestSize = "100Mi"
 
@@ -67,8 +63,6 @@ const (
 	DeploymentController = "deployment"
 	// DaemonSetController is controller type for DaemonSet
 	DaemonSetController = "daemonset"
-	// ReplicationController is controller type for  ReplicationController
-	ReplicationController = "replicationcontroller"
 )
 
 // CheckUnsupportedKey checks if given komposeObject contains
@@ -218,7 +212,7 @@ func (k *Kubernetes) InitSvc(name string, service kobject.ServiceConfig) *api.Se
 }
 
 // InitConfigMapForEnv initializes a ConfigMap object
-func (k *Kubernetes) InitConfigMapForEnv(name string, service kobject.ServiceConfig, opt kobject.ConvertOptions, envFile string) *api.ConfigMap {
+func (k *Kubernetes) InitConfigMapForEnv(name string, opt kobject.ConvertOptions, envFile string) *api.ConfigMap {
 	envs, err := GetEnvsFromFile(envFile, opt)
 	if err != nil {
 		log.Fatalf("Unable to retrieve env file: %s", err)
@@ -575,7 +569,7 @@ func (k *Kubernetes) CreatePVC(name string, mode string, size string, selectorVa
 }
 
 // ConfigPorts configures the container ports.
-func ConfigPorts(name string, service kobject.ServiceConfig) []api.ContainerPort {
+func ConfigPorts(service kobject.ServiceConfig) []api.ContainerPort {
 	ports := []api.ContainerPort{}
 	exist := map[string]bool{}
 	for _, port := range service.Port {
@@ -598,7 +592,7 @@ func ConfigPorts(name string, service kobject.ServiceConfig) []api.ContainerPort
 	return ports
 }
 
-func (k *Kubernetes) ConfigLBServicePorts(name string, service kobject.ServiceConfig) ([]api.ServicePort, []api.ServicePort) {
+func (k *Kubernetes) ConfigLBServicePorts(service kobject.ServiceConfig) ([]api.ServicePort, []api.ServicePort) {
 	var tcpPorts []api.ServicePort
 	var udpPorts []api.ServicePort
 	for _, port := range service.Port {
@@ -627,7 +621,7 @@ func (k *Kubernetes) ConfigLBServicePorts(name string, service kobject.ServiceCo
 }
 
 // ConfigServicePorts configure the container service ports.
-func (k *Kubernetes) ConfigServicePorts(name string, service kobject.ServiceConfig) []api.ServicePort {
+func (k *Kubernetes) ConfigServicePorts(service kobject.ServiceConfig) []api.ServicePort {
 	servicePorts := []api.ServicePort{}
 	seenPorts := make(map[int]struct{}, len(service.Port))
 
@@ -987,7 +981,7 @@ func (k *Kubernetes) ConfigPVCVolumeSource(name string, readonly bool) *api.Volu
 }
 
 // ConfigEnvs configures the environment variables.
-func ConfigEnvs(name string, service kobject.ServiceConfig, opt kobject.ConvertOptions) ([]api.EnvVar, error) {
+func ConfigEnvs(service kobject.ServiceConfig, opt kobject.ConvertOptions) ([]api.EnvVar, error) {
 	envs := transformer.EnvSort{}
 
 	keysFromEnvFile := make(map[string]bool)
@@ -1078,8 +1072,8 @@ func configConstrains(constrains map[string]string, operator api.NodeSelectorOpe
 	return rs
 }
 
-// CreateKubernetesObjects generates a Kubernetes artifact for each input type service
-func (k *Kubernetes) CreateKubernetesObjects(name string, service kobject.ServiceConfig, opt kobject.ConvertOptions) []runtime.Object {
+// CreateWorkloadAndConfigMapObjects generates a Kubernetes artifact for each input type service
+func (k *Kubernetes) CreateWorkloadAndConfigMapObjects(name string, service kobject.ServiceConfig, opt kobject.ConvertOptions) []runtime.Object {
 	var objects []runtime.Object
 	var replica int
 
@@ -1112,7 +1106,7 @@ func (k *Kubernetes) CreateKubernetesObjects(name string, service kobject.Servic
 	}
 
 	if len(service.Configs) > 0 {
-		objects = k.createConfigMapFromComposeConfig(name, opt, service, objects)
+		objects = k.createConfigMapFromComposeConfig(name, service, objects)
 	}
 
 	if opt.CreateD || opt.Controller == DeploymentController {
@@ -1125,7 +1119,7 @@ func (k *Kubernetes) CreateKubernetesObjects(name string, service kobject.Servic
 
 	if len(service.EnvFile) > 0 {
 		for _, envFile := range service.EnvFile {
-			configMap := k.InitConfigMapForEnv(name, service, opt, envFile)
+			configMap := k.InitConfigMapForEnv(name, opt, envFile)
 			objects = append(objects, configMap)
 		}
 	}
@@ -1133,7 +1127,7 @@ func (k *Kubernetes) CreateKubernetesObjects(name string, service kobject.Servic
 	return objects
 }
 
-func (k *Kubernetes) createConfigMapFromComposeConfig(name string, opt kobject.ConvertOptions, service kobject.ServiceConfig, objects []runtime.Object) []runtime.Object {
+func (k *Kubernetes) createConfigMapFromComposeConfig(name string, service kobject.ServiceConfig, objects []runtime.Object) []runtime.Object {
 	for _, config := range service.Configs {
 		currentConfigName := config.Source
 		currentConfigObj := service.ConfigsMetaData[currentConfigName]
@@ -1165,7 +1159,7 @@ func (k *Kubernetes) InitPod(name string, service kobject.ServiceConfig) *api.Po
 }
 
 // CreateNetworkPolicy initializes Network policy
-func (k *Kubernetes) CreateNetworkPolicy(name string, networkName string) (*networkingv1.NetworkPolicy, error) {
+func (k *Kubernetes) CreateNetworkPolicy(networkName string) (*networkingv1.NetworkPolicy, error) {
 	str := "true"
 	np := &networkingv1.NetworkPolicy{
 		TypeMeta: metav1.TypeMeta{
@@ -1193,6 +1187,81 @@ func (k *Kubernetes) CreateNetworkPolicy(name string, networkName string) (*netw
 	return np, nil
 }
 
+func buildServiceImage(opt kobject.ConvertOptions, service kobject.ServiceConfig, name string) error {
+	// Must build the images before conversion (got to add service.Image in case 'image' key isn't provided
+	// Check that --build is set to true
+	// Check to see if there is an InputFile (required!) before we build the container
+	// Check that there's actually a Build key
+	// Lastly, we must have an Image name to continue
+	if opt.Build == "local" && opt.InputFiles != nil && service.Build != "" {
+		// If there's no "image" key, use the name of the container that's built
+		if service.Image == "" {
+			service.Image = name
+		}
+
+		if service.Image == "" {
+			return fmt.Errorf("image key required within build parameters in order to build and push service '%s'", name)
+		}
+
+		log.Infof("Build key detected. Attempting to build image '%s'", service.Image)
+
+		// Build the image!
+		err := transformer.BuildDockerImage(service, name)
+		if err != nil {
+			return errors.Wrapf(err, "Unable to build Docker image for service %v", name)
+		}
+
+		// Push the built image to the repo!
+		err = transformer.PushDockerImageWithOpt(service, name, opt)
+		if err != nil {
+			return errors.Wrapf(err, "Unable to push Docker image for service %v", name)
+		}
+	}
+	return nil
+}
+
+func (k *Kubernetes) configKubeServiceAndIngressForService(service kobject.ServiceConfig, name string, objects *[]runtime.Object) {
+	if k.PortsExist(service) {
+		if service.ServiceType == "LoadBalancer" {
+			svcs := k.CreateLBService(name, service)
+			for _, svc := range svcs {
+				*objects = append(*objects, svc)
+			}
+			if len(svcs) > 1 {
+				log.Warningf("Create multiple service to avoid using mixed protocol in the same service when it's loadbalander type")
+			}
+		} else {
+			svc := k.CreateService(name, service)
+			*objects = append(*objects, svc)
+			if service.ExposeService != "" {
+				*objects = append(*objects, k.initIngress(name, service, svc.Spec.Ports[0].Port))
+			}
+		}
+	} else {
+		if service.ServiceType == "Headless" {
+			svc := k.CreateHeadlessService(name, service)
+			*objects = append(*objects, svc)
+		} else {
+			log.Warnf("Service %q won't be created because 'ports' is not specified", name)
+		}
+	}
+}
+
+func (k *Kubernetes) configNetworkPolicyForService(service kobject.ServiceConfig, name string, objects *[]runtime.Object) error {
+	if len(service.Network) > 0 {
+		for _, net := range service.Network {
+			log.Infof("Network %s is detected at Source, shall be converted to equivalent NetworkPolicy at Destination", net)
+			np, err := k.CreateNetworkPolicy(net)
+
+			if err != nil {
+				return errors.Wrapf(err, "Unable to create Network Policy for network %v for service %v", net, name)
+			}
+			*objects = append(*objects, np)
+		}
+	}
+	return nil
+}
+
 // Transform maps komposeObject to k8s objects
 // returns object that are already sorted in the way that Services are first
 func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.ConvertOptions) ([]runtime.Object, error) {
@@ -1212,80 +1281,28 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
 	if opt.MultipleContainerMode {
 		komposeObjectToServiceConfigGroupMapping := KomposeObjectToServiceConfigGroupMapping(komposeObject)
 		for name, group := range komposeObjectToServiceConfigGroupMapping {
-			service := komposeObject.ServiceConfigs[name]
 			var objects []runtime.Object
-
-			service.WithKomposeAnnotation = opt.WithKomposeAnnotation
-
-			// Must build the images before conversion (got to add service.Image in case 'image' key isn't provided
-			// Check that --build is set to true
-			// Check to see if there is an InputFile (required!) before we build the container
-			// Check that there's actually a Build key
-			// Lastly, we must have an Image name to continue
-			if opt.Build == "local" && opt.InputFiles != nil && service.Build != "" {
-				// If there's no "image" key, use the name of the container that's built
-				if service.Image == "" {
-					service.Image = name
-				}
-
-				if service.Image == "" {
-					return nil, fmt.Errorf("image key required within build parameters in order to build and push service '%s'", name)
-				}
-
-				log.Infof("Build key detected. Attempting to build image '%s'", service.Image)
-
-				// Build the image!
-				err := transformer.BuildDockerImage(service, name)
-				if err != nil {
-					return nil, errors.Wrapf(err, "Unable to build Docker image for service %v", name)
-				}
-
-				// Push the built image to the repo!
-				err = transformer.PushDockerImageWithOpt(service, name, opt)
-				if err != nil {
-					return nil, errors.Wrapf(err, "Unable to push Docker image for service %v", name)
-				}
-			}
-
 			podSpec := PodSpec{}
 
 			// added a container
 			for _, service := range group {
+				service.WithKomposeAnnotation = opt.WithKomposeAnnotation
 				podSpec.Append(AddContainer(service, opt))
 
+				if err := buildServiceImage(opt, service, service.Name); err != nil {
+					return nil, err
+				}
+
 				// Generate pod only and nothing more
 				if (service.Restart == "no" || service.Restart == "on-failure") && !opt.IsPodController() {
 					log.Infof("Create kubernetes pod instead of pod controller due to restart policy: %s", service.Restart)
 					pod := k.InitPod(name, service)
 					objects = append(objects, pod)
 				} else {
-					objects = k.CreateKubernetesObjects(name, service, opt)
+					objects = k.CreateWorkloadAndConfigMapObjects(name, service, opt)
 				}
 
-				if k.PortsExist(service) {
-					if service.ServiceType == "LoadBalancer" {
-						svcs := k.CreateLBService(name, service, objects)
-						for _, svc := range svcs {
-							objects = append(objects, svc)
-						}
-						if len(svcs) > 1 {
-							log.Warningf("Create multiple service to avoid using mixed protocol in the same service when it's loadbalander type")
-						}
-					} else {
-						svc := k.CreateService(name, service, objects)
-						objects = append(objects, svc)
-						if service.ExposeService != "" {
-							objects = append(objects, k.initIngress(name, service, svc.Spec.Ports[0].Port))
-						}
-					}
-				} else {
-					if service.ServiceType == "Headless" {
-						svc := k.CreateHeadlessService(name, service, objects)
-						objects = append(objects, svc)
-					} else {
-						log.Warnf("Service %q won't be created because 'ports' is not specified", name)
-					}
-				}
+				k.configKubeServiceAndIngressForService(service, name, &objects)
 
 				// Configure the container volumes.
 				volumesMount, volumes, pvc, cms, err := k.ConfigVolumes(name, service)
@@ -1322,7 +1339,7 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
 				}
 
 				podSpec.Append(
-					SetPorts(name, service),
+					SetPorts(service),
 					ImagePullPolicy(name, service),
 					RestartPolicy(name, service),
 					SecurityContext(name, service),
@@ -1339,21 +1356,13 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
 					podSpec.Append(ServiceAccountName(serviceAccountName))
 				}
 
-				err = k.UpdateKubernetesObjectsMultipleContainers(name, service, opt, &objects, podSpec)
+				err = k.UpdateKubernetesObjectsMultipleContainers(name, service, &objects, podSpec)
 				if err != nil {
 					return nil, errors.Wrap(err, "Error transforming Kubernetes objects")
 				}
-			}
-
-			if len(service.Network) > 0 {
-				for _, net := range service.Network {
-					log.Infof("Network %s is detected at Source, shall be converted to equivalent NetworkPolicy at Destination", net)
-					np, err := k.CreateNetworkPolicy(name, net)
 
-					if err != nil {
-						return nil, errors.Wrapf(err, "Unable to create Network Policy for network %v for service %v", net, name)
-					}
-					objects = append(objects, np)
+				if err = k.configNetworkPolicyForService(service, service.Name, &objects); err != nil {
+					return nil, err
 				}
 			}
 
@@ -1367,34 +1376,8 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
 
 			service.WithKomposeAnnotation = opt.WithKomposeAnnotation
 
-			// Must build the images before conversion (got to add service.Image in case 'image' key isn't provided
-			// Check that --build is set to true
-			// Check to see if there is an InputFile (required!) before we build the container
-			// Check that there's actually a Build key
-			// Lastly, we must have an Image name to continue
-			if opt.Build == "local" && opt.InputFiles != nil && service.Build != "" {
-				// If there's no "image" key, use the name of the container that's built
-				if service.Image == "" {
-					service.Image = name
-				}
-
-				if service.Image == "" {
-					return nil, fmt.Errorf("image key required within build parameters in order to build and push service '%s'", name)
-				}
-
-				log.Infof("Build key detected. Attempting to build image '%s'", service.Image)
-
-				// Build the image!
-				err := transformer.BuildDockerImage(service, name)
-				if err != nil {
-					return nil, errors.Wrapf(err, "Unable to build Docker image for service %v", name)
-				}
-
-				// Push the built image to the repo!
-				err = transformer.PushDockerImageWithOpt(service, name, opt)
-				if err != nil {
-					return nil, errors.Wrapf(err, "Unable to push Docker image for service %v", name)
-				}
+			if err := buildServiceImage(opt, service, name); err != nil {
+				return nil, err
 			}
 
 			// Generate pod only and nothing more
@@ -1403,51 +1386,19 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
 				pod := k.InitPod(name, service)
 				objects = append(objects, pod)
 			} else {
-				objects = k.CreateKubernetesObjects(name, service, opt)
+				objects = k.CreateWorkloadAndConfigMapObjects(name, service, opt)
 			}
 
-			if k.PortsExist(service) {
-				if service.ServiceType == "LoadBalancer" {
-					svcs := k.CreateLBService(name, service, objects)
-					for _, svc := range svcs {
-						objects = append(objects, svc)
-					}
-					if len(svcs) > 1 {
-						log.Warningf("Create multiple service to avoid using mixed protocol in the same service when it's loadbalander type")
-					}
-				} else {
-					svc := k.CreateService(name, service, objects)
-					objects = append(objects, svc)
-					if service.ExposeService != "" {
-						objects = append(objects, k.initIngress(name, service, svc.Spec.Ports[0].Port))
-					}
-				}
-			} else {
-				if service.ServiceType == "Headless" {
-					svc := k.CreateHeadlessService(name, service, objects)
-					objects = append(objects, svc)
-				} else {
-					log.Warnf("Service %q won't be created because 'ports' is not specified", name)
-				}
-			}
+			k.configKubeServiceAndIngressForService(service, name, &objects)
 
 			err := k.UpdateKubernetesObjects(name, service, opt, &objects)
 			if err != nil {
 				return nil, errors.Wrap(err, "Error transforming Kubernetes objects")
 			}
 
-			if len(service.Network) > 0 {
-				for _, net := range service.Network {
-					log.Infof("Network %s is detected at Source, shall be converted to equivalent NetworkPolicy at Destination", net)
-					np, err := k.CreateNetworkPolicy(name, net)
-
-					if err != nil {
-						return nil, errors.Wrapf(err, "Unable to create Network Policy for network %v for service %v", net, name)
-					}
-					objects = append(objects, np)
-				}
+			if err := k.configNetworkPolicyForService(service, name, &objects); err != nil {
+				return nil, err
 			}
-
 			allobjects = append(allobjects, objects...)
 		}
 	}
diff --git a/pkg/transformer/kubernetes/podspec.go b/pkg/transformer/kubernetes/podspec.go
index 00f7b0e0..3dbc5de8 100644
--- a/pkg/transformer/kubernetes/podspec.go
+++ b/pkg/transformer/kubernetes/podspec.go
@@ -33,7 +33,7 @@ func AddContainer(service kobject.ServiceConfig, opt kobject.ConvertOptions) Pod
 			name = FormatContainerName(service.ContainerName)
 		}
 
-		envs, err := ConfigEnvs(name, service, opt)
+		envs, err := ConfigEnvs(service, opt)
 		if err != nil {
 			panic("Unable to load env variables")
 		}
@@ -53,16 +53,6 @@ func AddContainer(service kobject.ServiceConfig, opt kobject.ConvertOptions) Pod
 	}
 }
 
-func ImagePullSecrets(pullSecret string) PodSpecOption {
-	return func(podSpec *PodSpec) {
-		podSpec.ImagePullSecrets = append(podSpec.ImagePullSecrets,
-			api.LocalObjectReference{
-				Name: pullSecret,
-			},
-		)
-	}
-}
-
 func TerminationGracePeriodSeconds(name string, service kobject.ServiceConfig) PodSpecOption {
 	return func(podSpec *PodSpec) {
 		var err error
@@ -75,7 +65,7 @@ func TerminationGracePeriodSeconds(name string, service kobject.ServiceConfig) P
 	}
 }
 
-// Configure the resource limits
+// ResourcesLimits Configure the resource limits
 func ResourcesLimits(service kobject.ServiceConfig) PodSpecOption {
 	return func(podSpec *PodSpec) {
 		if service.MemLimit != 0 || service.CPULimit != 0 {
@@ -96,7 +86,7 @@ func ResourcesLimits(service kobject.ServiceConfig) PodSpecOption {
 	}
 }
 
-// Configure the resource requests
+// ResourcesRequests Configure the resource requests
 func ResourcesRequests(service kobject.ServiceConfig) PodSpecOption {
 	return func(podSpec *PodSpec) {
 		if service.MemReservation != 0 || service.CPUReservation != 0 {
@@ -117,7 +107,7 @@ func ResourcesRequests(service kobject.ServiceConfig) PodSpecOption {
 	}
 }
 
-// Configure SecurityContext
+// SecurityContext Configure SecurityContext
 func SecurityContext(name string, service kobject.ServiceConfig) PodSpecOption {
 	return func(podSpec *PodSpec) {
 		// Configure resource reservations
@@ -217,11 +207,11 @@ func SetVolumeMounts(volumesMount []api.VolumeMount) PodSpecOption {
 	}
 }
 
-// Configure ports
-func SetPorts(name string, service kobject.ServiceConfig) PodSpecOption {
+// SetPorts Configure ports
+func SetPorts(service kobject.ServiceConfig) PodSpecOption {
 	return func(podSpec *PodSpec) {
 		// Configure the container ports.
-		ports := ConfigPorts(name, service)
+		ports := ConfigPorts(service)
 
 		for i := range podSpec.Containers {
 			podSpec.Containers[i].Ports = ports
@@ -229,7 +219,7 @@ func SetPorts(name string, service kobject.ServiceConfig) PodSpecOption {
 	}
 }
 
-// Configure the image pull policy
+// ImagePullPolicy Configure the image pull policy
 func ImagePullPolicy(name string, service kobject.ServiceConfig) PodSpecOption {
 	return func(podSpec *PodSpec) {
 		if policy, err := GetImagePullPolicy(name, service.ImagePullPolicy); err != nil {
@@ -242,7 +232,7 @@ func ImagePullPolicy(name string, service kobject.ServiceConfig) PodSpecOption {
 	}
 }
 
-// Configure the container restart policy.
+// RestartPolicy Configure the container restart policy.
 func RestartPolicy(name string, service kobject.ServiceConfig) PodSpecOption {
 	return func(podSpec *PodSpec) {
 		if restart, err := GetRestartPolicy(name, service.Restart); err != nil {
diff --git a/pkg/transformer/openshift/openshift.go b/pkg/transformer/openshift/openshift.go
index 172d2350..87e0d10a 100644
--- a/pkg/transformer/openshift/openshift.go
+++ b/pkg/transformer/openshift/openshift.go
@@ -44,10 +44,6 @@ type OpenShift struct {
 	kubernetes.Kubernetes
 }
 
-// TIMEOUT is how long we'll wait for the termination of OpenShift resource to be successful
-// used when undeploying resources from OpenShift
-const TIMEOUT = 300
-
 // list of all unsupported keys for this transformer
 // Keys are names of variables in kobject struct.
 // this is map to make searching for keys easier
@@ -333,7 +329,7 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
 			pod := o.InitPod(name, service)
 			objects = append(objects, pod)
 		} else {
-			objects = o.CreateKubernetesObjects(name, service, opt)
+			objects = o.CreateWorkloadAndConfigMapObjects(name, service, opt)
 
 			if opt.CreateDeploymentConfig {
 				objects = append(objects, o.initDeploymentConfig(name, service, replica)) // OpenShift DeploymentConfigs
@@ -389,7 +385,7 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
 
 		if o.PortsExist(service) {
 			if service.ServiceType == "LoadBalancer" {
-				svcs := o.CreateLBService(name, service, objects)
+				svcs := o.CreateLBService(name, service)
 				for _, svc := range svcs {
 					objects = append(objects, svc)
 				}
@@ -397,7 +393,7 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
 					log.Warningf("Create multiple service to avoid using mixed protocol in the same service when it's loadbalander type")
 				}
 			} else {
-				svc := o.CreateService(name, service, objects)
+				svc := o.CreateService(name, service)
 				objects = append(objects, svc)
 
 				if service.ExposeService != "" {
@@ -405,7 +401,7 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
 				}
 			}
 		} else if service.ServiceType == "Headless" {
-			svc := o.CreateHeadlessService(name, service, objects)
+			svc := o.CreateHeadlessService(name, service)
 			objects = append(objects, svc)
 		}
 
diff --git a/pkg/transformer/utils.go b/pkg/transformer/utils.go
index 731715ec..ae464fdc 100644
--- a/pkg/transformer/utils.go
+++ b/pkg/transformer/utils.go
@@ -322,7 +322,7 @@ func (env EnvSort) Less(i, j int) bool {
 	return env[i].Name < env[j].Name
 }
 
-// swaps the elements with indexes i and j.
+// Swap swaps the elements with indexes i and j.
 func (env EnvSort) Swap(i, j int) {
 	env[i], env[j] = env[j], env[i]
 }


Test patch:
diff --git a/pkg/transformer/kubernetes/k8sutils_test.go b/pkg/transformer/kubernetes/k8sutils_test.go
index 799c7699..293f3b62 100644
--- a/pkg/transformer/kubernetes/k8sutils_test.go
+++ b/pkg/transformer/kubernetes/k8sutils_test.go
@@ -61,13 +61,13 @@ func TestCreateService(t *testing.T) {
 		ServiceConfigs: map[string]kobject.ServiceConfig{"app": service},
 	}
 	k := Kubernetes{}
-	objects, err := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 3})
+	_, err := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 3})
 	if err != nil {
 		t.Error(errors.Wrap(err, "k.Transform failed"))
 	}
 
 	// Test the creation of the service
-	svc := k.CreateService("foo", service, objects)
+	svc := k.CreateService("foo", service)
 
 	if svc.Spec.Ports[0].Port != 123 {
 		t.Errorf("Expected port 123 upon conversion, actual %d", svc.Spec.Ports[0].Port)
diff --git a/pkg/transformer/kubernetes/kubernetes_test.go b/pkg/transformer/kubernetes/kubernetes_test.go
index e60995af..0237d6a6 100644
--- a/pkg/transformer/kubernetes/kubernetes_test.go
+++ b/pkg/transformer/kubernetes/kubernetes_test.go
@@ -606,6 +606,7 @@ func TestMultipleContainersInPod(t *testing.T) {
 
 	createConfig := func(name string, containerName *string) kobject.ServiceConfig {
 		config := newServiceConfig()
+		config.Network = nil
 		config.Labels = map[string]string{compose.LabelServiceGroup: groupName}
 		config.Name = name
 		if containerName != nil {