* Use go mod instead of glide
* Add `--with-kompose-annotation` flag to allow us to switch it off for tests
* Remove hostpid support (since the newest sdk does not support it)
* Create new test script and fixtures
* Remove replicationcontroller support
This commit is contained in:
Hang Yan
2020-08-07 17:25:52 +08:00
committed by GitHub
parent d780067bf9
commit 525b68f027
2680 changed files with 457661 additions and 730294 deletions
-10
View File
@@ -22,16 +22,6 @@ import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
// install kubernetes api
_ "k8s.io/kubernetes/pkg/api/install"
_ "k8s.io/kubernetes/pkg/apis/extensions/install"
// install OpenShift api
_ "github.com/openshift/origin/pkg/build/api/install"
_ "github.com/openshift/origin/pkg/deploy/api/install"
_ "github.com/openshift/origin/pkg/image/api/install"
_ "github.com/openshift/origin/pkg/route/api/install"
"os"
"github.com/kubernetes/kompose/pkg/kobject"
+28 -15
View File
@@ -19,12 +19,12 @@ package kobject
import (
dockerCliTypes "github.com/docker/cli/cli/compose/types"
"github.com/docker/libcompose/yaml"
deployapi "github.com/openshift/origin/pkg/deploy/api"
deployapi "github.com/openshift/api/apps/v1"
"github.com/pkg/errors"
"github.com/spf13/cast"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/util/intstr"
v1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"path/filepath"
"time"
)
@@ -74,6 +74,8 @@ type ConvertOptions struct {
Server string
YAMLIndent int
WithKomposeAnnotation bool
}
// ServiceConfig holds the basic struct of a container
@@ -136,6 +138,8 @@ type ServiceConfig struct {
Configs []dockerCliTypes.ServiceConfigObjConfig `compose:""`
//This is for SHORT SYNTAX link(https://docs.docker.com/compose/compose-file/#configs)
ConfigsMetaData map[string]dockerCliTypes.ConfigObjConfig `compose:""`
WithKomposeAnnotation bool `compose:""`
}
// HealthCheck the healthcheck configuration for a service
@@ -161,7 +165,7 @@ type Ports struct {
HostPort int32
ContainerPort int32
HostIP string
Protocol api.Protocol
Protocol corev1.Protocol
}
// Volumes holds the volume struct of container
@@ -202,23 +206,28 @@ func (s *ServiceConfig) GetConfigMapKeyFromMeta(name string) (string, error) {
// 1. only apply to Deployment, but the check is not happened here
// 2. only support `parallelism` and `order`
// return nil if not support
func (s *ServiceConfig) GetKubernetesUpdateStrategy() *extensions.RollingUpdateDeployment {
func (s *ServiceConfig) GetKubernetesUpdateStrategy() *v1.RollingUpdateDeployment {
config := s.DeployUpdateConfig
r := extensions.RollingUpdateDeployment{}
r := v1.RollingUpdateDeployment{}
if config.Order == "stop-first" {
if config.Parallelism != nil {
r.MaxUnavailable = intstr.FromInt(cast.ToInt(*config.Parallelism))
v := intstr.FromInt(cast.ToInt(*config.Parallelism))
r.MaxUnavailable = &v
}
r.MaxSurge = intstr.FromInt(0)
v := intstr.FromInt(0)
r.MaxSurge = &v
return &r
}
if config.Order == "start-first" {
if config.Parallelism != nil {
r.MaxSurge = intstr.FromInt(cast.ToInt(*config.Parallelism))
v := intstr.FromInt(cast.ToInt(*config.Parallelism))
r.MaxSurge = &v
}
r.MaxUnavailable = intstr.FromInt(0)
v := intstr.FromInt(0)
r.MaxUnavailable = &v
return &r
}
return nil
@@ -239,18 +248,22 @@ func (s *ServiceConfig) GetOSUpdateStrategy() *deployapi.RollingDeploymentStrate
if config.Order == "stop-first" {
if config.Parallelism != nil {
r.MaxUnavailable = intstr.FromInt(cast.ToInt(*config.Parallelism))
v := intstr.FromInt(cast.ToInt(*config.Parallelism))
r.MaxUnavailable = &v
}
r.MaxSurge = intstr.FromInt(0)
*r.MaxSurge = intstr.FromInt(0)
r.UpdatePeriodSeconds = &interval
return &r
}
if config.Order == "start-first" {
if config.Parallelism != nil {
r.MaxSurge = intstr.FromInt(cast.ToInt(*config.Parallelism))
v := intstr.FromInt(cast.ToInt(*config.Parallelism))
r.MaxSurge = &v
}
r.MaxUnavailable = intstr.FromInt(0)
v := intstr.FromInt(0)
r.MaxUnavailable = &v
r.UpdatePeriodSeconds = &interval
return &r
}
+1 -1
View File
@@ -24,7 +24,7 @@ import (
"reflect"
"strings"
"k8s.io/kubernetes/pkg/api"
api "k8s.io/api/core/v1"
"github.com/fatih/structs"
"github.com/kubernetes/kompose/pkg/kobject"
+1 -2
View File
@@ -23,8 +23,7 @@ import (
"testing"
"github.com/kubernetes/kompose/pkg/kobject"
"k8s.io/kubernetes/pkg/api"
api "k8s.io/api/core/v1"
"time"
"github.com/docker/cli/cli/compose/types"
+2 -1
View File
@@ -25,7 +25,8 @@ import (
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/pkg/errors"
"k8s.io/kubernetes/pkg/api"
api "k8s.io/api/core/v1"
)
const (
+2 -1
View File
@@ -32,7 +32,8 @@ import (
"github.com/kubernetes/kompose/pkg/transformer"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"k8s.io/kubernetes/pkg/api"
api "k8s.io/api/core/v1"
)
// Parse Docker Compose with libcompose (only supports v1 and v2). Eventually we will
+1 -1
View File
@@ -25,7 +25,7 @@ import (
libcomposeyaml "github.com/docker/libcompose/yaml"
"k8s.io/kubernetes/pkg/api"
api "k8s.io/api/core/v1"
"github.com/docker/cli/cli/compose/loader"
"github.com/docker/cli/cli/compose/types"
+3 -4
View File
@@ -2,9 +2,8 @@ package testutils
import (
"errors"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/runtime"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
)
// CheckForHeadless is helper function for tests.
@@ -12,7 +11,7 @@ import (
func CheckForHeadless(objects []runtime.Object) error {
serviceCreated := false
for _, obj := range objects {
if svc, ok := obj.(*api.Service); ok {
if svc, ok := obj.(*v1.Service); ok {
serviceCreated = true
// Check if it is a headless services
if svc.Spec.ClusterIP != "None" {
+56 -73
View File
@@ -21,7 +21,12 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"k8s.io/kubernetes/pkg/api/meta"
api "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"os"
"path"
"path/filepath"
@@ -37,16 +42,11 @@ import (
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v3"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/runtime"
appsv1 "k8s.io/api/apps/v1"
"sort"
deployapi "github.com/openshift/origin/pkg/deploy/api"
deployapi "github.com/openshift/api/apps/v1"
"github.com/pkg/errors"
"k8s.io/kubernetes/pkg/api/resource"
)
/**
@@ -150,6 +150,18 @@ func getDirName(opt kobject.ConvertOptions) string {
return dirName
}
func objectToRaw(object runtime.Object) runtime.RawExtension {
r := runtime.RawExtension{
Object: object,
}
bytes, _ := json.Marshal(object)
r.Raw = bytes
return r
}
// PrintList will take the data converted and decide on the commandline attributes given
func PrintList(objects []runtime.Object, opt kobject.ConvertOptions) error {
@@ -181,16 +193,18 @@ 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, unversioned.GroupVersion{})
versionedObject, err := convertToVersion(object, metav1.GroupVersion{})
if err != nil {
return err
}
list.Items = append(list.Items, versionedObject)
list.Items = append(list.Items, objectToRaw(versionedObject))
}
// version list itself
listVersion := unversioned.GroupVersion{Group: "", Version: "v1"}
listVersion := metav1.GroupVersion{Group: "", Version: "v1"}
list.Kind = "List"
list.APIVersion = "v1"
convertedList, err := convertToVersion(list, listVersion)
if err != nil {
return err
@@ -217,7 +231,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, unversioned.GroupVersion{})
versionedObject, err := convertToVersion(v, metav1.GroupVersion{})
if err != nil {
return err
}
@@ -226,26 +240,26 @@ func PrintList(objects []runtime.Object, opt kobject.ConvertOptions) error {
return err
}
var typeMeta unversioned.TypeMeta
var objectMeta api.ObjectMeta
var typeMeta metav1.TypeMeta
var objectMeta metav1.ObjectMeta
if us, ok := v.(*runtime.Unstructured); ok {
typeMeta = unversioned.TypeMeta{
if us, ok := v.(*unstructured.Unstructured); ok {
typeMeta = metav1.TypeMeta{
Kind: us.GetKind(),
APIVersion: us.GetAPIVersion(),
}
objectMeta = api.ObjectMeta{
objectMeta = metav1.ObjectMeta{
Name: us.GetName(),
}
} else {
val := reflect.ValueOf(v).Elem()
// Use reflect to access TypeMeta struct inside runtime.Object.
// cast it to correct type - unversioned.TypeMeta
typeMeta = val.FieldByName("TypeMeta").Interface().(unversioned.TypeMeta)
// cast it to correct type - metav1.TypeMeta
typeMeta = val.FieldByName("TypeMeta").Interface().(metav1.TypeMeta)
// Use reflect to access ObjectMeta struct inside runtime.Object.
// cast it to correct type - api.ObjectMeta
objectMeta = val.FieldByName("ObjectMeta").Interface().(api.ObjectMeta)
objectMeta = val.FieldByName("ObjectMeta").Interface().(metav1.ObjectMeta)
}
@@ -321,27 +335,29 @@ func marshalWithIndent(o interface{}, indent int) ([]byte, error) {
}
// Convert object to versioned object
// if groupVersion is empty (unversioned.GroupVersion{}), use version from original object (obj)
func convertToVersion(obj runtime.Object, groupVersion unversioned.GroupVersion) (runtime.Object, error) {
// if groupVersion is empty (metav1.GroupVersion{}), use version from original object (obj)
func convertToVersion(obj runtime.Object, groupVersion metav1.GroupVersion) (runtime.Object, error) {
// ignore unstruct object
if _, ok := obj.(*runtime.Unstructured); ok {
if _, ok := obj.(*unstructured.Unstructured); ok {
return obj, nil
}
var version unversioned.GroupVersion
return obj, nil
if groupVersion.Empty() {
objectVersion := obj.GetObjectKind().GroupVersionKind()
version = unversioned.GroupVersion{Group: objectVersion.Group, Version: objectVersion.Version}
} else {
version = groupVersion
}
convertedObject, err := api.Scheme.ConvertToVersion(obj, version)
if err != nil {
return nil, err
}
return convertedObject, nil
//var version metav1.GroupVersion
//
//if groupVersion.Empty() {
// objectVersion := obj.GetObjectKind().GroupVersionKind()
// version = metav1.GroupVersion{Group: objectVersion.Group, Version: objectVersion.Version}
//} else {
// version = groupVersion
//}
//convertedObject, err := api.Scheme.ConvertToVersion(obj, version)
//if err != nil {
// return nil, err
//}
//return convertedObject, nil
}
// PortsExist checks if service has ports defined
@@ -500,7 +516,7 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
//set pid namespace mode
if service.Pid != "" {
if service.Pid == "host" {
podSecurityContext.HostPID = true
// podSecurityContext.HostPID = true
} else {
log.Warningf("Ignoring PID key for service \"%v\". Invalid value \"%v\".", name, service.Pid)
}
@@ -567,7 +583,7 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
}
// fillObjectMeta fills the metadata with the value calculated from config
fillObjectMeta := func(meta *api.ObjectMeta) {
fillObjectMeta := func(meta *metav1.ObjectMeta) {
meta.Annotations = annotations
}
@@ -579,8 +595,8 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
}
if len(service.Volumes) > 0 {
switch objType := obj.(type) {
case *extensions.Deployment:
objType.Spec.Strategy.Type = extensions.RecreateDeploymentStrategyType
case *appsv1.Deployment:
objType.Spec.Strategy.Type = appsv1.RecreateDeploymentStrategyType
case *deployapi.DeploymentConfig:
objType.Spec.Strategy.Type = deployapi.DeploymentStrategyTypeRecreate
}
@@ -682,7 +698,7 @@ func (k *Kubernetes) RemoveDupObjects(objs *[]runtime.Object) {
var result []runtime.Object
exist := map[string]bool{}
for _, obj := range *objs {
if us, ok := obj.(meta.Object); ok {
if us, ok := obj.(metav1.Object); ok {
k := obj.GetObjectKind().GroupVersionKind().String() + us.GetNamespace() + us.GetName()
if exist[k] {
log.Debugf("Remove duplicate resource: %s/%s", obj.GetObjectKind().GroupVersionKind().Kind, us.GetName())
@@ -699,39 +715,6 @@ func (k *Kubernetes) RemoveDupObjects(objs *[]runtime.Object) {
*objs = result
}
func resetWorkloadAPIVersion(d runtime.Object) runtime.Object {
data, err := json.Marshal(d)
if err == nil {
var us runtime.Unstructured
if err := json.Unmarshal(data, &us); err == nil {
us.SetGroupVersionKind(unversioned.GroupVersionKind{
Group: "apps",
Version: "v1",
Kind: d.GetObjectKind().GroupVersionKind().Kind,
})
return &us
}
}
return d
}
// FixWorkloadVersion force reset deployment/daemonset's apiversion to apps/v1
func (k *Kubernetes) FixWorkloadVersion(objs *[]runtime.Object) {
var result []runtime.Object
for _, obj := range *objs {
if d, ok := obj.(*extensions.Deployment); ok {
nd := resetWorkloadAPIVersion(d)
result = append(result, nd)
} else if d, ok := obj.(*extensions.DaemonSet); ok {
nd := resetWorkloadAPIVersion(d)
result = append(result, nd)
} else {
result = append(result, obj)
}
}
*objs = result
}
// SortedKeys Ensure the kubernetes objects are in a consistent order
func SortedKeys(komposeObject kobject.KomposeObject) []string {
var sortedKeys []string
+34 -34
View File
@@ -17,6 +17,8 @@ limitations under the License.
package kubernetes
import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"strconv"
"testing"
@@ -29,8 +31,6 @@ import (
"reflect"
"github.com/pkg/errors"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
)
/*
@@ -43,7 +43,7 @@ func TestCreateService(t *testing.T) {
ContainerName: "name",
Image: "image",
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: api.ProtocolTCP}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: corev1.ProtocolTCP}},
Command: []string{"cmd"},
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
@@ -87,7 +87,7 @@ func TestCreateServiceWithMemLimit(t *testing.T) {
ContainerName: "name",
Image: "image",
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: api.ProtocolTCP}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: corev1.ProtocolTCP}},
Command: []string{"cmd"},
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
@@ -117,7 +117,7 @@ func TestCreateServiceWithMemLimit(t *testing.T) {
// Retrieve the deployment object and test that it matches the mem value
for _, obj := range objects {
if deploy, ok := obj.(*extensions.Deployment); ok {
if deploy, ok := obj.(*appsv1.Deployment); ok {
memLimit, _ := deploy.Spec.Template.Spec.Containers[0].Resources.Limits.Memory().AsInt64()
if memLimit != 1337 {
t.Errorf("Expected 1337 for memory limit check, got %v", memLimit)
@@ -140,7 +140,7 @@ func TestCreateServiceWithCPULimit(t *testing.T) {
ContainerName: "name",
Image: "image",
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: api.ProtocolTCP}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: corev1.ProtocolTCP}},
Command: []string{"cmd"},
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
@@ -170,7 +170,7 @@ func TestCreateServiceWithCPULimit(t *testing.T) {
// Retrieve the deployment object and test that it matches the cpu value
for _, obj := range objects {
if deploy, ok := obj.(*extensions.Deployment); ok {
if deploy, ok := obj.(*appsv1.Deployment); ok {
cpuLimit := deploy.Spec.Template.Spec.Containers[0].Resources.Limits.Cpu().MilliValue()
if cpuLimit != 10 {
t.Errorf("Expected 10 for cpu limit check, got %v", cpuLimit)
@@ -194,7 +194,7 @@ func TestCreateServiceWithServiceUser(t *testing.T) {
ContainerName: "name",
Image: "image",
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: api.ProtocolTCP}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: corev1.ProtocolTCP}},
Command: []string{"cmd"},
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
@@ -222,7 +222,7 @@ func TestCreateServiceWithServiceUser(t *testing.T) {
}
for _, obj := range objects {
if deploy, ok := obj.(*extensions.Deployment); ok {
if deploy, ok := obj.(*appsv1.Deployment); ok {
uid := *deploy.Spec.Template.Spec.Containers[0].SecurityContext.RunAsUser
if strconv.FormatInt(uid, 10) != service.User {
t.Errorf("User in ServiceConfig is not matching user in PodSpec")
@@ -238,7 +238,7 @@ func TestTransformWithPid(t *testing.T) {
ContainerName: "name",
Image: "image",
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: api.ProtocolTCP}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: corev1.ProtocolTCP}},
Command: []string{"cmd"},
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
@@ -253,19 +253,19 @@ func TestTransformWithPid(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"))
}
for _, obj := range objects {
if deploy, ok := obj.(*extensions.Deployment); ok {
hostPid := deploy.Spec.Template.Spec.SecurityContext.HostPID
if !hostPid {
t.Errorf("Pid in ServiceConfig is not matching HostPID in PodSpec")
}
}
}
//for _, obj := range objects {
// if deploy, ok := obj.(*appsv1.Deployment); ok {
// hostPid := deploy.Spec.Template.Spec.SecurityContext.HostPID
// if !hostPid {
// t.Errorf("Pid in ServiceConfig is not matching HostPID in PodSpec")
// }
// }
//}
}
func TestTransformWithInvalidPid(t *testing.T) {
@@ -274,7 +274,7 @@ func TestTransformWithInvalidPid(t *testing.T) {
ContainerName: "name",
Image: "image",
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: api.ProtocolTCP}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: corev1.ProtocolTCP}},
Command: []string{"cmd"},
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
@@ -289,21 +289,21 @@ func TestTransformWithInvalidPid(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"))
}
for _, obj := range objects {
if deploy, ok := obj.(*extensions.Deployment); ok {
if deploy.Spec.Template.Spec.SecurityContext != nil {
hostPid := deploy.Spec.Template.Spec.SecurityContext.HostPID
if hostPid {
t.Errorf("Pid in ServiceConfig is not matching HostPID in PodSpec")
}
}
}
}
//for _, obj := range objects {
// if deploy, ok := obj.(*appsv1.Deployment); ok {
// if deploy.Spec.Template.Spec.SecurityContext != nil {
// hostPid := deploy.Spec.Template.Spec.SecurityContext.HostPID
// if hostPid {
// t.Errorf("Pid in ServiceConfig is not matching HostPID in PodSpec")
// }
// }
// }
//}
}
func TestIsDir(t *testing.T) {
@@ -402,10 +402,10 @@ func TestRecreateStrategyWithVolumesPresent(t *testing.T) {
t.Error(errors.Wrap(err, "k.Transform failed"))
}
for _, obj := range objects {
if deployment, ok := obj.(*extensions.Deployment); ok {
if deployment.Spec.Strategy.Type != extensions.RecreateDeploymentStrategyType {
if deployment, ok := obj.(*appsv1.Deployment); ok {
if deployment.Spec.Strategy.Type != appsv1.RecreateDeploymentStrategyType {
t.Errorf("Expected %v as Strategy Type, got %v",
extensions.RecreateDeploymentStrategyType,
appsv1.RecreateDeploymentStrategyType,
deployment.Spec.Strategy.Type)
}
}
+72 -108
View File
@@ -21,29 +21,25 @@ import (
"github.com/fatih/structs"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/transformer"
buildapi "github.com/openshift/origin/pkg/build/api"
deployapi "github.com/openshift/origin/pkg/deploy/api"
deployapi "github.com/openshift/api/apps/v1"
log "github.com/sirupsen/logrus"
"io/ioutil"
api "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/intstr"
"os"
"path"
"reflect"
"regexp"
"strconv"
// install kubernetes api
_ "k8s.io/kubernetes/pkg/api/install"
_ "k8s.io/kubernetes/pkg/apis/extensions/install"
buildapi "github.com/openshift/api/build/v1"
appsv1 "k8s.io/api/apps/v1"
networkingv1 "k8s.io/api/networking/v1"
networkingv1beta1 "k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/intstr"
//"k8s.io/kubernetes/pkg/controller/daemon"
"sort"
"strings"
@@ -200,38 +196,14 @@ func (k *Kubernetes) InitPodSpecWithConfigMap(name string, image string, service
return pod
}
// InitRC initializes Kubernetes ReplicationController object
func (k *Kubernetes) InitRC(name string, service kobject.ServiceConfig, replicas int) *api.ReplicationController {
rc := &api.ReplicationController{
TypeMeta: unversioned.TypeMeta{
Kind: "ReplicationController",
APIVersion: "v1",
},
ObjectMeta: api.ObjectMeta{
Name: name,
Labels: transformer.ConfigLabels(name),
},
Spec: api.ReplicationControllerSpec{
Replicas: int32(replicas),
Template: &api.PodTemplateSpec{
ObjectMeta: api.ObjectMeta{
Labels: transformer.ConfigLabels(name),
},
Spec: k.InitPodSpec(name, service.Image, service.ImagePullSecret),
},
},
}
return rc
}
// InitSvc initializes Kubernetes Service object
func (k *Kubernetes) InitSvc(name string, service kobject.ServiceConfig) *api.Service {
svc := &api.Service{
TypeMeta: unversioned.TypeMeta{
TypeMeta: metav1.TypeMeta{
Kind: "Service",
APIVersion: "v1",
},
ObjectMeta: api.ObjectMeta{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: transformer.ConfigLabels(name),
},
@@ -256,11 +228,11 @@ func (k *Kubernetes) InitConfigMapForEnv(name string, service kobject.ServiceCon
// In order to differentiate files, we append to the name and remove '.env' if applicable from the file name
configMap := &api.ConfigMap{
TypeMeta: unversioned.TypeMeta{
TypeMeta: metav1.TypeMeta{
Kind: "ConfigMap",
APIVersion: "v1",
},
ObjectMeta: api.ObjectMeta{
ObjectMeta: metav1.ObjectMeta{
Name: envName,
Labels: transformer.ConfigLabels(name + "-" + envName),
},
@@ -275,11 +247,11 @@ func (k *Kubernetes) InitConfigMapForEnv(name string, service kobject.ServiceCon
// 1. volume
func (k *Kubernetes) IntiConfigMapFromFileOrDir(name, cmName, filePath string, service kobject.ServiceConfig) (*api.ConfigMap, error) {
configMap := &api.ConfigMap{
TypeMeta: unversioned.TypeMeta{
TypeMeta: metav1.TypeMeta{
Kind: "ConfigMap",
APIVersion: "v1",
},
ObjectMeta: api.ObjectMeta{
ObjectMeta: metav1.ObjectMeta{
Name: cmName,
Labels: transformer.ConfigLabels(name),
},
@@ -351,11 +323,11 @@ func (k *Kubernetes) InitConfigMapFromFile(name string, service kobject.ServiceC
}
}
configMap := &api.ConfigMap{
TypeMeta: unversioned.TypeMeta{
TypeMeta: metav1.TypeMeta{
Kind: "ConfigMap",
APIVersion: "v1",
},
ObjectMeta: api.ObjectMeta{
ObjectMeta: metav1.ObjectMeta{
Name: FormatFileName(configMapName),
Labels: transformer.ConfigLabels(name),
},
@@ -365,7 +337,7 @@ func (k *Kubernetes) InitConfigMapFromFile(name string, service kobject.ServiceC
}
// InitD initializes Kubernetes Deployment object
func (k *Kubernetes) InitD(name string, service kobject.ServiceConfig, replicas int) *extensions.Deployment {
func (k *Kubernetes) InitD(name string, service kobject.ServiceConfig, replicas int) *appsv1.Deployment {
var podSpec api.PodSpec
if len(service.Configs) > 0 {
@@ -374,22 +346,24 @@ func (k *Kubernetes) InitD(name string, service kobject.ServiceConfig, replicas
podSpec = k.InitPodSpec(name, service.Image, service.ImagePullSecret)
}
dc := &extensions.Deployment{
TypeMeta: unversioned.TypeMeta{
rp := int32(replicas)
dc := &appsv1.Deployment{
TypeMeta: metav1.TypeMeta{
Kind: "Deployment",
APIVersion: "extensions/v1beta1",
APIVersion: "apps/v1",
},
ObjectMeta: api.ObjectMeta{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: transformer.ConfigAllLabels(name, &service),
},
Spec: extensions.DeploymentSpec{
Replicas: int32(replicas),
Selector: &unversioned.LabelSelector{
Spec: appsv1.DeploymentSpec{
Replicas: &rp,
Selector: &metav1.LabelSelector{
MatchLabels: transformer.ConfigLabels(name),
},
Template: api.PodTemplateSpec{
ObjectMeta: api.ObjectMeta{
ObjectMeta: metav1.ObjectMeta{
//Labels: transformer.ConfigLabels(name),
Annotations: transformer.ConfigAnnotations(service),
},
@@ -401,8 +375,8 @@ func (k *Kubernetes) InitD(name string, service kobject.ServiceConfig, replicas
update := service.GetKubernetesUpdateStrategy()
if update != nil {
dc.Spec.Strategy = extensions.DeploymentStrategy{
Type: extensions.RollingUpdateDeploymentStrategyType,
dc.Spec.Strategy = appsv1.DeploymentStrategy{
Type: appsv1.RollingUpdateDeploymentStrategyType,
RollingUpdate: update,
}
log.Debugf("Set deployment '%s' rolling update: MaxSurge: %s, MaxUnavailable: %s", name, update.MaxSurge.String(), update.MaxUnavailable.String())
@@ -412,17 +386,17 @@ func (k *Kubernetes) InitD(name string, service kobject.ServiceConfig, replicas
}
// InitDS initializes Kubernetes DaemonSet object
func (k *Kubernetes) InitDS(name string, service kobject.ServiceConfig) *extensions.DaemonSet {
ds := &extensions.DaemonSet{
TypeMeta: unversioned.TypeMeta{
func (k *Kubernetes) InitDS(name string, service kobject.ServiceConfig) *appsv1.DaemonSet {
ds := &appsv1.DaemonSet{
TypeMeta: metav1.TypeMeta{
Kind: "DaemonSet",
APIVersion: "extensions/v1beta1",
APIVersion: "apps/v1",
},
ObjectMeta: api.ObjectMeta{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: transformer.ConfigAllLabels(name, &service),
},
Spec: extensions.DaemonSetSpec{
Spec: appsv1.DaemonSetSpec{
Template: api.PodTemplateSpec{
Spec: k.InitPodSpec(name, service.Image, service.ImagePullSecret),
},
@@ -431,34 +405,34 @@ func (k *Kubernetes) InitDS(name string, service kobject.ServiceConfig) *extensi
return ds
}
func (k *Kubernetes) initIngress(name string, service kobject.ServiceConfig, port int32) *extensions.Ingress {
func (k *Kubernetes) initIngress(name string, service kobject.ServiceConfig, port int32) *networkingv1beta1.Ingress {
hosts := regexp.MustCompile("[ ,]*,[ ,]*").Split(service.ExposeService, -1)
ingress := &extensions.Ingress{
TypeMeta: unversioned.TypeMeta{
ingress := &networkingv1beta1.Ingress{
TypeMeta: metav1.TypeMeta{
Kind: "Ingress",
APIVersion: "extensions/v1beta1",
},
ObjectMeta: api.ObjectMeta{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: transformer.ConfigLabels(name),
Annotations: transformer.ConfigAnnotations(service),
},
Spec: extensions.IngressSpec{
Rules: make([]extensions.IngressRule, len(hosts)),
Spec: networkingv1beta1.IngressSpec{
Rules: make([]networkingv1beta1.IngressRule, len(hosts)),
},
}
for i, host := range hosts {
host, p := transformer.ParseIngressPath(host)
ingress.Spec.Rules[i] = extensions.IngressRule{
IngressRuleValue: extensions.IngressRuleValue{
HTTP: &extensions.HTTPIngressRuleValue{
Paths: []extensions.HTTPIngressPath{
ingress.Spec.Rules[i] = networkingv1beta1.IngressRule{
IngressRuleValue: networkingv1beta1.IngressRuleValue{
HTTP: &networkingv1beta1.HTTPIngressRuleValue{
Paths: []networkingv1beta1.HTTPIngressPath{
{
Path: p,
Backend: extensions.IngressBackend{
Backend: networkingv1beta1.IngressBackend{
ServiceName: name,
ServicePort: intstr.IntOrString{
IntVal: port,
@@ -475,7 +449,7 @@ func (k *Kubernetes) initIngress(name string, service kobject.ServiceConfig, por
}
if service.ExposeServiceTLS != "" {
ingress.Spec.TLS = []extensions.IngressTLS{
ingress.Spec.TLS = []networkingv1beta1.IngressTLS{
{
Hosts: hosts,
SecretName: service.ExposeServiceTLS,
@@ -498,11 +472,11 @@ func (k *Kubernetes) CreateSecrets(komposeObject kobject.KomposeObject) ([]*api.
}
data := []byte(dataString)
secret := &api.Secret{
TypeMeta: unversioned.TypeMeta{
TypeMeta: metav1.TypeMeta{
Kind: "Secret",
APIVersion: "v1",
},
ObjectMeta: api.ObjectMeta{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: transformer.ConfigLabels(name),
},
@@ -526,11 +500,11 @@ func (k *Kubernetes) CreatePVC(name string, mode string, size string, selectorVa
}
pvc := &api.PersistentVolumeClaim{
TypeMeta: unversioned.TypeMeta{
TypeMeta: metav1.TypeMeta{
Kind: "PersistentVolumeClaim",
APIVersion: "v1",
},
ObjectMeta: api.ObjectMeta{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: transformer.ConfigLabels(name),
},
@@ -544,7 +518,7 @@ func (k *Kubernetes) CreatePVC(name string, mode string, size string, selectorVa
}
if len(selectorValue) > 0 {
pvc.Spec.Selector = &unversioned.LabelSelector{
pvc.Spec.Selector = &metav1.LabelSelector{
MatchLabels: transformer.ConfigLabels(selectorValue),
}
}
@@ -895,7 +869,7 @@ func (k *Kubernetes) ConfigEmptyVolumeSource(key string) *api.VolumeSource {
}
// ConfigHostPathVolumeSource config a configmap to use as volume source
// ConfigConfigMapVolumeSource config a configmap to use as volume source
func (k *Kubernetes) ConfigConfigMapVolumeSource(cmName string, targetPath string, cm *api.ConfigMap) *api.VolumeSource {
s := api.ConfigMapVolumeSource{}
s.Name = cmName
@@ -1049,9 +1023,6 @@ func (k *Kubernetes) CreateKubernetesObjects(name string, service kobject.Servic
if opt.CreateDS || opt.Controller == DaemonSetController {
objects = append(objects, k.InitDS(name, service))
}
if opt.CreateRC || opt.Controller == ReplicationController {
objects = append(objects, k.InitRC(name, service, replica))
}
if len(service.EnvFile) > 0 {
for _, envFile := range service.EnvFile {
@@ -1080,11 +1051,11 @@ func (k *Kubernetes) createConfigMapFromComposeConfig(name string, opt kobject.C
// InitPod initializes Kubernetes Pod object
func (k *Kubernetes) InitPod(name string, service kobject.ServiceConfig) *api.Pod {
pod := api.Pod{
TypeMeta: unversioned.TypeMeta{
TypeMeta: metav1.TypeMeta{
Kind: "Pod",
APIVersion: "v1",
},
ObjectMeta: api.ObjectMeta{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: transformer.ConfigLabels(name),
Annotations: transformer.ConfigAnnotations(service),
@@ -1095,25 +1066,25 @@ func (k *Kubernetes) InitPod(name string, service kobject.ServiceConfig) *api.Po
}
// CreateNetworkPolicy initializes Network policy
func (k *Kubernetes) CreateNetworkPolicy(name string, networkName string) (*extensions.NetworkPolicy, error) {
func (k *Kubernetes) CreateNetworkPolicy(name string, networkName string) (*networkingv1.NetworkPolicy, error) {
str := "true"
np := &extensions.NetworkPolicy{
TypeMeta: unversioned.TypeMeta{
np := &networkingv1.NetworkPolicy{
TypeMeta: metav1.TypeMeta{
Kind: "NetworkPolicy",
APIVersion: "extensions/v1beta1",
},
ObjectMeta: api.ObjectMeta{
ObjectMeta: metav1.ObjectMeta{
Name: networkName,
//Labels: transformer.ConfigLabels(name)(name),
},
Spec: extensions.NetworkPolicySpec{
PodSelector: unversioned.LabelSelector{
Spec: networkingv1.NetworkPolicySpec{
PodSelector: metav1.LabelSelector{
MatchLabels: map[string]string{"io.kompose.network/" + networkName: str},
},
Ingress: []extensions.NetworkPolicyIngressRule{{
From: []extensions.NetworkPolicyPeer{{
PodSelector: &unversioned.LabelSelector{
Ingress: []networkingv1.NetworkPolicyIngressRule{{
From: []networkingv1.NetworkPolicyPeer{{
PodSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{"io.kompose.network/" + networkName: str},
},
}},
@@ -1146,6 +1117,8 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
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
@@ -1234,30 +1207,21 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
// sort all object so Services are first
k.SortServicesFirst(&allobjects)
k.RemoveDupObjects(&allobjects)
k.FixWorkloadVersion(&allobjects)
// k.FixWorkloadVersion(&allobjects)
return allobjects, nil
}
// UpdateController updates the given object with the given pod template update function and ObjectMeta update function
func (k *Kubernetes) UpdateController(obj runtime.Object, updateTemplate func(*api.PodTemplateSpec) error, updateMeta func(meta *api.ObjectMeta)) (err error) {
func (k *Kubernetes) UpdateController(obj runtime.Object, updateTemplate func(*api.PodTemplateSpec) error, updateMeta func(meta *metav1.ObjectMeta)) (err error) {
switch t := obj.(type) {
case *api.ReplicationController:
if t.Spec.Template == nil {
t.Spec.Template = &api.PodTemplateSpec{}
}
err = updateTemplate(t.Spec.Template)
if err != nil {
return errors.Wrap(err, "updateTemplate failed")
}
updateMeta(&t.ObjectMeta)
case *extensions.Deployment:
case *appsv1.Deployment:
err = updateTemplate(&t.Spec.Template)
if err != nil {
return errors.Wrap(err, "updateTemplate failed")
}
updateMeta(&t.ObjectMeta)
case *extensions.DaemonSet:
case *appsv1.DaemonSet:
err = updateTemplate(&t.Spec.Template)
if err != nil {
return errors.Wrap(err, "updateTemplate failed")
+34 -64
View File
@@ -19,19 +19,22 @@ package kubernetes
import (
"encoding/json"
"fmt"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime"
appsv1 "k8s.io/api/apps/v1"
networkingv1beta1 "k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"reflect"
"testing"
deployapi "github.com/openshift/origin/pkg/deploy/api"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/transformer"
deployapi "github.com/openshift/api/apps/v1"
"github.com/pkg/errors"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
api "k8s.io/api/core/v1"
"strings"
)
@@ -204,7 +207,7 @@ func checkService(config kobject.ServiceConfig, svc *api.Service, expectedLabels
return nil
}
func checkMeta(config kobject.ServiceConfig, meta api.ObjectMeta, expectedName string, shouldSetLabels bool) error {
func checkMeta(config kobject.ServiceConfig, meta metav1.ObjectMeta, expectedName string, shouldSetLabels bool) error {
if expectedName != meta.Name {
return fmt.Errorf("Found unexpected name: %s vs. %s", expectedName, meta.Name)
}
@@ -255,7 +258,7 @@ func TestKomposeConvertIngress(t *testing.T) {
// Check results
for _, obj := range objs {
if ing, ok := obj.(*extensions.Ingress); ok {
if ing, ok := obj.(*networkingv1beta1.Ingress); ok {
if ing.ObjectMeta.Name != appName {
t.Errorf("Expected ObjectMeta.Name to be %s, got %s instead", appName, ing.ObjectMeta.Name)
}
@@ -282,14 +285,12 @@ func TestKomposeConvert(t *testing.T) {
expectedNumObjs int
}{
// objects generated are deployment, service nework policies (2) and pvc
"Convert to Deployments (D)": {newKomposeObject(), kobject.ConvertOptions{CreateD: true, Replicas: replicas, IsReplicaSetFlag: true}, 5},
"Convert to Deployments (D) with v3 replicas": {newKomposeObject(), kobject.ConvertOptions{CreateD: true}, 5},
"Convert to DaemonSets (DS)": {newKomposeObject(), kobject.ConvertOptions{CreateDS: true}, 5},
"Convert to ReplicationController(RC)": {newKomposeObject(), kobject.ConvertOptions{CreateRC: true, Replicas: replicas, IsReplicaSetFlag: true}, 5},
"Convert to ReplicationController(RC) with v3 replicas ": {newKomposeObject(), kobject.ConvertOptions{CreateRC: true}, 5},
"Convert to Deployments (D)": {newKomposeObject(), kobject.ConvertOptions{CreateD: true, Replicas: replicas, IsReplicaSetFlag: true}, 5},
"Convert to Deployments (D) with v3 replicas": {newKomposeObject(), kobject.ConvertOptions{CreateD: true}, 5},
"Convert to DaemonSets (DS)": {newKomposeObject(), kobject.ConvertOptions{CreateDS: true}, 5},
// objects generated are deployment, daemonset, ReplicationController, service and pvc
"Convert to D, DS, and RC": {newKomposeObject(), kobject.ConvertOptions{CreateD: true, CreateDS: true, CreateRC: true, Replicas: replicas, IsReplicaSetFlag: true}, 7},
"Convert to D, DS, and RC with v3 replicas": {newKomposeObject(), kobject.ConvertOptions{CreateD: true, CreateDS: true, CreateRC: true}, 7},
"Convert to D, DS, and RC": {newKomposeObject(), kobject.ConvertOptions{CreateD: true, CreateDS: true, CreateRC: true, Replicas: replicas, IsReplicaSetFlag: true}, 6},
"Convert to D, DS, and RC with v3 replicas": {newKomposeObject(), kobject.ConvertOptions{CreateD: true, CreateDS: true, CreateRC: true}, 6},
// TODO: add more tests
}
@@ -305,7 +306,7 @@ func TestKomposeConvert(t *testing.T) {
t.Errorf("Expected %d objects returned, got %d", test.expectedNumObjs, len(objs))
}
var foundSVC, foundD, foundDS, foundRC, foundDC bool
var foundSVC, foundD, foundDS, foundDC bool
name := "app"
labels := transformer.ConfigLabels(name)
config := test.komposeObject.ServiceConfigs[name]
@@ -322,7 +323,7 @@ func TestKomposeConvert(t *testing.T) {
foundSVC = true
}
if test.opt.CreateD {
if d, ok := obj.(*extensions.Deployment); ok {
if d, ok := obj.(*appsv1.Deployment); ok {
if err := checkPodTemplate(config, d.Spec.Template, labelsWithNetwork); err != nil {
t.Errorf("%v", err)
}
@@ -330,35 +331,31 @@ func TestKomposeConvert(t *testing.T) {
t.Errorf("%v", err)
}
if test.opt.IsReplicaSetFlag {
if (int)(d.Spec.Replicas) != replicas {
if (int)(*d.Spec.Replicas) != replicas {
t.Errorf("Expected %d replicas, got %d", replicas, d.Spec.Replicas)
}
} else {
if (int)(d.Spec.Replicas) != newServiceConfig().Replicas {
if (int)(*d.Spec.Replicas) != newServiceConfig().Replicas {
t.Errorf("Expected %d replicas, got %d", newServiceConfig().Replicas, d.Spec.Replicas)
}
}
if d.Spec.Selector != nil && len(d.Spec.Selector.MatchLabels) > 0 {
t.Errorf("Expect selector be unset, got: %#v", d.Spec.Selector)
}
foundD = true
}
if u, ok := obj.(*runtime.Unstructured); ok {
if u, ok := obj.(*unstructured.Unstructured); ok {
if u.GetKind() == "Deployment" {
u.SetGroupVersionKind(unversioned.GroupVersionKind{
Group: "extensions",
Version: "v1beta1",
u.SetGroupVersionKind(schema.GroupVersionKind{
Group: "apps",
Version: "v1",
Kind: "Deployment",
})
data, err := json.Marshal(u)
if err != nil {
t.Errorf("%v", err)
}
var d extensions.Deployment
var d appsv1.Deployment
if err := json.Unmarshal(data, &d); err == nil {
if err := checkPodTemplate(config, d.Spec.Template, labelsWithNetwork); err != nil {
t.Errorf("%v", err)
@@ -367,12 +364,12 @@ func TestKomposeConvert(t *testing.T) {
t.Errorf("%v", err)
}
if test.opt.IsReplicaSetFlag {
if (int)(d.Spec.Replicas) != replicas {
if (int)(*d.Spec.Replicas) != replicas {
t.Errorf("Expected %d replicas, got %d", replicas, d.Spec.Replicas)
}
} else {
if (int)(d.Spec.Replicas) != newServiceConfig().Replicas {
if (int)(*d.Spec.Replicas) != newServiceConfig().Replicas {
t.Errorf("Expected %d replicas, got %d", newServiceConfig().Replicas, d.Spec.Replicas)
}
@@ -385,7 +382,7 @@ func TestKomposeConvert(t *testing.T) {
}
if test.opt.CreateDS {
if ds, ok := obj.(*extensions.DaemonSet); ok {
if ds, ok := obj.(*appsv1.DaemonSet); ok {
if err := checkPodTemplate(config, ds.Spec.Template, labelsWithNetwork); err != nil {
t.Errorf("%v", err)
}
@@ -398,18 +395,18 @@ func TestKomposeConvert(t *testing.T) {
foundDS = true
}
if u, ok := obj.(*runtime.Unstructured); ok {
if u, ok := obj.(*unstructured.Unstructured); ok {
if u.GetKind() == "DaemonSet" {
u.SetGroupVersionKind(unversioned.GroupVersionKind{
Group: "extensions",
Version: "v1beta1",
u.SetGroupVersionKind(schema.GroupVersionKind{
Group: "apps",
Version: "v1",
Kind: "DaemonSet",
})
data, err := json.Marshal(u)
if err != nil {
t.Errorf("%v", err)
}
var ds extensions.DaemonSet
var ds appsv1.DaemonSet
if err := json.Unmarshal(data, &ds); err == nil {
if err := checkPodTemplate(config, ds.Spec.Template, labelsWithNetwork); err != nil {
t.Errorf("%v", err)
@@ -425,32 +422,7 @@ func TestKomposeConvert(t *testing.T) {
}
}
if test.opt.CreateRC {
if rc, ok := obj.(*api.ReplicationController); ok {
if err := checkPodTemplate(config, *rc.Spec.Template, labelsWithNetwork); err != nil {
t.Errorf("%v", err)
}
if err := checkMeta(config, rc.ObjectMeta, name, true); err != nil {
t.Errorf("%v", err)
}
if test.opt.IsReplicaSetFlag {
if (int)(rc.Spec.Replicas) != replicas {
t.Errorf("Expected %d replicas, got %d", replicas, rc.Spec.Replicas)
}
} else {
if (int)(rc.Spec.Replicas) != newServiceConfig().Replicas {
t.Errorf("Expected %d replicas, got %d", newServiceConfig().Replicas, rc.Spec.Replicas)
}
}
if len(rc.Spec.Selector) > 0 {
t.Errorf("Expect selector be unset, got: %#v", rc.Spec.Selector)
}
foundRC = true
}
}
// TODO: k8s & openshift transformer is now separated; either separate the test or combine the transformer
if test.opt.CreateDeploymentConfig {
if dc, ok := obj.(*deployapi.DeploymentConfig); ok {
@@ -479,9 +451,7 @@ func TestKomposeConvert(t *testing.T) {
if test.opt.CreateDS != foundDS {
t.Errorf("Expected create Daemon Set: %v, found Daemon Set: %v", test.opt.CreateDS, foundDS)
}
if test.opt.CreateRC != foundRC {
t.Errorf("Expected create Replication Controller: %v, found Replication Controller: %v", test.opt.CreateRC, foundRC)
}
if test.opt.CreateDeploymentConfig != foundDC {
t.Errorf("Expected create Deployment Config: %v, found Deployment Config: %v", test.opt.CreateDeploymentConfig, foundDC)
}
+25 -25
View File
@@ -18,6 +18,8 @@ package openshift
import (
"fmt"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/intstr"
"os"
"github.com/kubernetes/kompose/pkg/kobject"
@@ -25,19 +27,18 @@ import (
log "github.com/sirupsen/logrus"
kapi "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime"
deployapi "github.com/openshift/api/apps/v1"
buildapi "github.com/openshift/api/build/v1"
imageapi "github.com/openshift/api/image/v1"
routeapi "github.com/openshift/api/route/v1"
corev1 "k8s.io/api/core/v1"
kapi "k8s.io/apimachinery/pkg/apis/meta/v1"
"sort"
"github.com/kubernetes/kompose/pkg/transformer"
buildapi "github.com/openshift/origin/pkg/build/api"
deployapi "github.com/openshift/origin/pkg/deploy/api"
imageapi "github.com/openshift/origin/pkg/image/api"
routeapi "github.com/openshift/origin/pkg/route/api"
"github.com/pkg/errors"
"k8s.io/kubernetes/pkg/util/intstr"
)
// OpenShift implements Transformer interface and represents OpenShift transformer
@@ -66,29 +67,28 @@ func (o *OpenShift) initImageStream(name string, service kobject.ServiceConfig,
}
// Retrieve tags and image name for mapping
tag := GetImageTag(service.Image)
var importPolicy imageapi.TagImportPolicy
if opt.InsecureRepository {
importPolicy = imageapi.TagImportPolicy{Insecure: true}
}
var tags map[string]imageapi.TagReference
var tags []imageapi.TagReference
if service.Build != "" || opt.Build != "build-config" {
tags = map[string]imageapi.TagReference{
tag: imageapi.TagReference{
From: &kapi.ObjectReference{
tags = append(tags,
imageapi.TagReference{
From: &corev1.ObjectReference{
Kind: "DockerImage",
Name: service.Image,
},
ImportPolicy: importPolicy,
},
}
})
}
is := &imageapi.ImageStream{
TypeMeta: unversioned.TypeMeta{
TypeMeta: kapi.TypeMeta{
Kind: "ImageStream",
APIVersion: "v1",
},
@@ -110,7 +110,7 @@ func initBuildConfig(name string, service kobject.ServiceConfig, repo string, br
if *envValue == "\x00" {
*envValue = os.Getenv(envName)
}
envList = append(envList, kapi.EnvVar{Name: envName, Value: *envValue})
envList = append(envList, corev1.EnvVar{Name: envName, Value: *envValue})
}
// Stable sorts data while keeping the original order of equal elements
// we need this because envs are not populated in any random order
@@ -121,7 +121,7 @@ func initBuildConfig(name string, service kobject.ServiceConfig, repo string, br
}
bc := &buildapi.BuildConfig{
TypeMeta: unversioned.TypeMeta{
TypeMeta: kapi.TypeMeta{
Kind: "BuildConfig",
APIVersion: "v1",
},
@@ -150,7 +150,7 @@ func initBuildConfig(name string, service kobject.ServiceConfig, repo string, br
},
},
Output: buildapi.BuildOutput{
To: &kapi.ObjectReference{
To: &corev1.ObjectReference{
Kind: "ImageStreamTag",
Name: name + ":" + GetImageTag(service.Image),
},
@@ -173,7 +173,7 @@ func (o *OpenShift) initDeploymentConfig(name string, service kobject.ServiceCon
containerName = []string{service.ContainerName}
}
var podSpec kapi.PodSpec
var podSpec corev1.PodSpec
if len(service.Configs) > 0 {
podSpec = o.InitPodSpecWithConfigMap(name, " ", service)
} else {
@@ -181,7 +181,7 @@ func (o *OpenShift) initDeploymentConfig(name string, service kobject.ServiceCon
}
dc := &deployapi.DeploymentConfig{
TypeMeta: unversioned.TypeMeta{
TypeMeta: kapi.TypeMeta{
Kind: "DeploymentConfig",
APIVersion: "v1",
},
@@ -193,7 +193,7 @@ func (o *OpenShift) initDeploymentConfig(name string, service kobject.ServiceCon
Replicas: int32(replicas),
Selector: transformer.ConfigLabels(name),
//UniqueLabelKey: p.Name,
Template: &kapi.PodTemplateSpec{
Template: &corev1.PodTemplateSpec{
ObjectMeta: kapi.ObjectMeta{
Labels: transformer.ConfigLabels(name),
},
@@ -210,7 +210,7 @@ func (o *OpenShift) initDeploymentConfig(name string, service kobject.ServiceCon
//Automatic - if new tag is detected - update image update inside the pod template
Automatic: true,
ContainerNames: containerName,
From: kapi.ObjectReference{
From: corev1.ObjectReference{
Name: name + ":" + tag,
Kind: "ImageStreamTag",
},
@@ -234,7 +234,7 @@ func (o *OpenShift) initDeploymentConfig(name string, service kobject.ServiceCon
func (o *OpenShift) initRoute(name string, service kobject.ServiceConfig, port int32) *routeapi.Route {
route := &routeapi.Route{
TypeMeta: unversioned.TypeMeta{
TypeMeta: kapi.TypeMeta{
Kind: "Route",
APIVersion: "v1",
},
@@ -422,7 +422,7 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
// sort all object so Services are first
o.SortServicesFirst(&allobjects)
o.RemoveDupObjects(&allobjects)
o.FixWorkloadVersion(&allobjects)
// o.FixWorkloadVersion(&allobjects)
return allobjects, nil
}
+7 -6
View File
@@ -17,20 +17,21 @@ limitations under the License.
package openshift
import (
kapi "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/runtime"
deployapi "github.com/openshift/api/apps/v1"
"k8s.io/apimachinery/pkg/runtime"
"os"
"path/filepath"
"reflect"
"testing"
deployapi "github.com/openshift/origin/pkg/deploy/api"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/testutils"
"github.com/kubernetes/kompose/pkg/transformer"
"github.com/kubernetes/kompose/pkg/transformer/kubernetes"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
)
func newServiceConfig() kobject.ServiceConfig {
@@ -38,7 +39,7 @@ func newServiceConfig() kobject.ServiceConfig {
ContainerName: "myfoobarname",
Image: "image",
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: kapi.ProtocolTCP}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: corev1.ProtocolTCP}},
Command: []string{"cmd"},
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
@@ -286,7 +287,7 @@ func TestInitBuildConfig(t *testing.T) {
serviceName := "serviceA"
repo := "https://git.test.com/org/repo1"
branch := "somebranch"
buildArgs := []kapi.EnvVar{{Name: "name", Value: "value"}}
buildArgs := []corev1.EnvVar{{Name: "name", Value: "value"}}
value := "value"
testDir := "a/build"
+1 -1
View File
@@ -18,7 +18,7 @@ package transformer
import (
"github.com/kubernetes/kompose/pkg/kobject"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime"
)
// Transformer interface defines transformer that is converting kobject to other resources
+7 -1
View File
@@ -35,7 +35,8 @@ import (
"github.com/kubernetes/kompose/pkg/version"
"github.com/pkg/errors"
"k8s.io/kubernetes/pkg/api"
api "k8s.io/api/core/v1"
)
// Selector used as labels and selector
@@ -155,6 +156,11 @@ func ConfigAnnotations(service kobject.ServiceConfig) map[string]string {
for key, value := range service.Annotations {
annotations[key] = value
}
if !service.WithKomposeAnnotation {
return annotations
}
annotations["kompose.cmd"] = strings.Join(os.Args, " ")
versionCmd := exec.Command("kompose", "version")
out, err := versionCmd.Output()