From 792976da1f61db3972d6b701e80da7368aa3c4a0 Mon Sep 17 00:00:00 2001 From: Tomas Kral Date: Thu, 27 Apr 2017 13:27:49 +0200 Subject: [PATCH 1/3] some of created objects were missing io.kompose.service label label added to BuildConfig, DaemonSet, ReplicationController, Deployment and Pod --- pkg/transformer/kubernetes/kubernetes.go | 12 ++-- pkg/transformer/kubernetes/kubernetes_test.go | 8 +-- pkg/transformer/openshift/openshift.go | 4 +- .../buildargs/output-os-template.json | 10 ++- .../test/fixtures/bundles/dab/output-k8s.json | 10 ++- .../test/fixtures/bundles/dsb/output-k8s.json | 21 +++++- .../entrypoint-command/output-k8s.json | 5 +- .../envvars-separators/output-k8s.json | 65 +++++++++++++++---- script/test/fixtures/etherpad/output-k8s.json | 10 ++- ...rnetes-expose-hostname-multiple-ports.json | 8 ++- .../kubernetes-expose-hostname.json | 8 ++- ...kubernetes-expose-true-multiple-ports.json | 8 ++- .../kubernetes-expose-true.json | 8 ++- script/test/fixtures/gitlab/output-k8s.json | 15 ++++- .../fixtures/keyonly-envs/output-k8s.json | 15 ++++- .../test/fixtures/mem-limit/output-k8s.json | 5 +- .../fixtures/mem-limit/output-mb-k8s.json | 5 +- .../multiple-compose-files/output-k8s.json | 10 ++- .../fixtures/nginx-node-redis/output-k8s.json | 25 +++++-- .../nginx-node-redis/output-os-template.json | 22 +++++-- .../fixtures/ports-with-ip/output-k8s.json | 10 ++- .../fixtures/ports-with-proto/output-k8s.json | 10 ++- .../service-name-change/output-k8s.json | 10 ++- .../test/fixtures/stdin-true/output-k8s.json | 5 +- script/test/fixtures/tty-true/output-k8s.json | 5 +- .../simple-vol-mounts/output-k8s.json | 5 +- .../volumes-from/output-k8s.json | 10 ++- .../fixtures/yaml-and-yml/output-k8s.json | 10 ++- .../fixtures/yaml-and-yml/yml/output-k8s.json | 10 ++- 29 files changed, 278 insertions(+), 71 deletions(-) diff --git a/pkg/transformer/kubernetes/kubernetes.go b/pkg/transformer/kubernetes/kubernetes.go index e1b55ae6..15c6a9cc 100644 --- a/pkg/transformer/kubernetes/kubernetes.go +++ b/pkg/transformer/kubernetes/kubernetes.go @@ -130,7 +130,8 @@ func (k *Kubernetes) InitRC(name string, service kobject.ServiceConfig, replicas APIVersion: "v1", }, ObjectMeta: api.ObjectMeta{ - Name: name, + Name: name, + Labels: transformer.ConfigLabels(name), }, Spec: api.ReplicationControllerSpec{ Replicas: int32(replicas), @@ -171,7 +172,8 @@ func (k *Kubernetes) InitD(name string, service kobject.ServiceConfig, replicas APIVersion: "extensions/v1beta1", }, ObjectMeta: api.ObjectMeta{ - Name: name, + Name: name, + Labels: transformer.ConfigLabels(name), }, Spec: extensions.DeploymentSpec{ Replicas: int32(replicas), @@ -191,7 +193,8 @@ func (k *Kubernetes) InitDS(name string, service kobject.ServiceConfig) *extensi APIVersion: "extensions/v1beta1", }, ObjectMeta: api.ObjectMeta{ - Name: name, + Name: name, + Labels: transformer.ConfigLabels(name), }, Spec: extensions.DaemonSetSpec{ Template: api.PodTemplateSpec{ @@ -513,7 +516,8 @@ func (k *Kubernetes) InitPod(name string, service kobject.ServiceConfig) *api.Po APIVersion: "v1", }, ObjectMeta: api.ObjectMeta{ - Name: name, + Name: name, + Labels: transformer.ConfigLabels(name), }, Spec: k.InitPodSpec(name, service.Image), } diff --git a/pkg/transformer/kubernetes/kubernetes_test.go b/pkg/transformer/kubernetes/kubernetes_test.go index 19e8fc77..9489c033 100644 --- a/pkg/transformer/kubernetes/kubernetes_test.go +++ b/pkg/transformer/kubernetes/kubernetes_test.go @@ -311,7 +311,7 @@ func TestKomposeConvert(t *testing.T) { if err := checkPodTemplate(config, d.Spec.Template, labels); err != nil { t.Errorf("%v", err) } - if err := checkMeta(config, d.ObjectMeta, name, false); err != nil { + if err := checkMeta(config, d.ObjectMeta, name, true); err != nil { t.Errorf("%v", err) } if (int)(d.Spec.Replicas) != replicas { @@ -328,7 +328,7 @@ func TestKomposeConvert(t *testing.T) { if err := checkPodTemplate(config, ds.Spec.Template, labels); err != nil { t.Errorf("%v", err) } - if err := checkMeta(config, ds.ObjectMeta, name, false); err != nil { + if err := checkMeta(config, ds.ObjectMeta, name, true); err != nil { t.Errorf("%v", err) } if ds.Spec.Selector != nil && len(ds.Spec.Selector.MatchLabels) > 0 { @@ -342,7 +342,7 @@ func TestKomposeConvert(t *testing.T) { if err := checkPodTemplate(config, *rc.Spec.Template, labels); err != nil { t.Errorf("%v", err) } - if err := checkMeta(config, rc.ObjectMeta, name, false); err != nil { + if err := checkMeta(config, rc.ObjectMeta, name, true); err != nil { t.Errorf("%v", err) } if (int)(rc.Spec.Replicas) != replicas { @@ -360,7 +360,7 @@ func TestKomposeConvert(t *testing.T) { if err := checkPodTemplate(config, *dc.Spec.Template, labels); err != nil { t.Errorf("%v", err) } - if err := checkMeta(config, dc.ObjectMeta, name, false); err != nil { + if err := checkMeta(config, dc.ObjectMeta, name, true); err != nil { t.Errorf("%v", err) } if (int)(dc.Spec.Replicas) != replicas { diff --git a/pkg/transformer/openshift/openshift.go b/pkg/transformer/openshift/openshift.go index 975fe8c4..93709bc7 100644 --- a/pkg/transformer/openshift/openshift.go +++ b/pkg/transformer/openshift/openshift.go @@ -216,8 +216,10 @@ func initBuildConfig(name string, service kobject.ServiceConfig, repo string, br Kind: "BuildConfig", APIVersion: "v1", }, + ObjectMeta: kapi.ObjectMeta{ - Name: name, + Name: name, + Labels: transformer.ConfigLabels(name), }, Spec: buildapi.BuildConfigSpec{ Triggers: []buildapi.BuildTriggerPolicy{ diff --git a/script/test/fixtures/buildargs/output-os-template.json b/script/test/fixtures/buildargs/output-os-template.json index 04ce1e9c..4150b830 100644 --- a/script/test/fixtures/buildargs/output-os-template.json +++ b/script/test/fixtures/buildargs/output-os-template.json @@ -139,7 +139,10 @@ "apiVersion": "v1", "metadata": { "name": "foo1", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "foo1" + } }, "spec": { "triggers": [ @@ -270,7 +273,10 @@ "apiVersion": "v1", "metadata": { "name": "foo", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "foo" + } }, "spec": { "triggers": [ diff --git a/script/test/fixtures/bundles/dab/output-k8s.json b/script/test/fixtures/bundles/dab/output-k8s.json index bccaf809..f0a75e36 100644 --- a/script/test/fixtures/bundles/dab/output-k8s.json +++ b/script/test/fixtures/bundles/dab/output-k8s.json @@ -60,7 +60,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "redis", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "redis" + } }, "spec": { "replicas": 1, @@ -96,7 +99,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "web", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "web" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/bundles/dsb/output-k8s.json b/script/test/fixtures/bundles/dsb/output-k8s.json index 32a20ce8..499b1659 100644 --- a/script/test/fixtures/bundles/dsb/output-k8s.json +++ b/script/test/fixtures/bundles/dsb/output-k8s.json @@ -146,6 +146,9 @@ "metadata": { "name": "db", "creationTimestamp": null, + "labels": { + "io.kompose.service": "db" + }, "annotations": { "com.example.description": "Postgres Database" } @@ -184,7 +187,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "redis", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "redis" + } }, "spec": { "replicas": 1, @@ -220,7 +226,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "result", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "result" + } }, "spec": { "replicas": 1, @@ -257,6 +266,9 @@ "metadata": { "name": "vote", "creationTimestamp": null, + "labels": { + "io.kompose.service": "vote" + }, "annotations": { "com.example.description": "Vote" } @@ -295,7 +307,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "worker", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "worker" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/entrypoint-command/output-k8s.json b/script/test/fixtures/entrypoint-command/output-k8s.json index 0faa005d..d26d5707 100644 --- a/script/test/fixtures/entrypoint-command/output-k8s.json +++ b/script/test/fixtures/entrypoint-command/output-k8s.json @@ -35,7 +35,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "base", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "base" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/envvars-separators/output-k8s.json b/script/test/fixtures/envvars-separators/output-k8s.json index 1b02cbaa..727b6dd8 100644 --- a/script/test/fixtures/envvars-separators/output-k8s.json +++ b/script/test/fixtures/envvars-separators/output-k8s.json @@ -356,7 +356,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "hygieia-api", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "hygieia-api" + } }, "spec": { "replicas": 1, @@ -430,7 +433,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "hygieia-bitbucket-scm-collector", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "hygieia-bitbucket-scm-collector" + } }, "spec": { "replicas": 1, @@ -499,7 +505,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "hygieia-chat-ops-collector", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "hygieia-chat-ops-collector" + } }, "spec": { "replicas": 1, @@ -568,7 +577,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "hygieia-github-scm-collector", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "hygieia-github-scm-collector" + } }, "spec": { "replicas": 1, @@ -637,7 +649,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "hygieia-jenkins-build-collector", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "hygieia-jenkins-build-collector" + } }, "spec": { "replicas": 1, @@ -706,7 +721,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "hygieia-jenkins-cucumber-test-collector", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "hygieia-jenkins-cucumber-test-collector" + } }, "spec": { "replicas": 1, @@ -775,7 +793,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "hygieia-jira-feature-collector", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "hygieia-jira-feature-collector" + } }, "spec": { "replicas": 1, @@ -854,7 +875,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "hygieia-sonar-codequality-collector", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "hygieia-sonar-codequality-collector" + } }, "spec": { "replicas": 1, @@ -923,7 +947,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "hygieia-subversion-scm-collector", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "hygieia-subversion-scm-collector" + } }, "spec": { "replicas": 1, @@ -992,7 +1019,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "hygieia-udeploy-collector", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "hygieia-udeploy-collector" + } }, "spec": { "replicas": 1, @@ -1075,7 +1105,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "hygieia-ui", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "hygieia-ui" + } }, "spec": { "replicas": 1, @@ -1111,7 +1144,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "hygieia-versionone-collector", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "hygieia-versionone-collector" + } }, "spec": { "replicas": 1, @@ -1180,7 +1216,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "mongodb", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "mongodb" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/etherpad/output-k8s.json b/script/test/fixtures/etherpad/output-k8s.json index 20fdd6e7..8af68c9a 100644 --- a/script/test/fixtures/etherpad/output-k8s.json +++ b/script/test/fixtures/etherpad/output-k8s.json @@ -60,7 +60,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "etherpad", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "etherpad" + } }, "spec": { "replicas": 1, @@ -118,7 +121,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "mariadb", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "mariadb" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/expose-service/provider-files/kubernetes-expose-hostname-multiple-ports.json b/script/test/fixtures/expose-service/provider-files/kubernetes-expose-hostname-multiple-ports.json index d2dc9ce4..9e0bbc0e 100644 --- a/script/test/fixtures/expose-service/provider-files/kubernetes-expose-hostname-multiple-ports.json +++ b/script/test/fixtures/expose-service/provider-files/kubernetes-expose-hostname-multiple-ports.json @@ -68,7 +68,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "redis", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "redis" + } }, "spec": { "replicas": 1, @@ -105,6 +108,9 @@ "metadata": { "name": "web", "creationTimestamp": null, + "labels": { + "io.kompose.service": "web" + }, "annotations": { "kompose.service.expose": "batman.example.com" } diff --git a/script/test/fixtures/expose-service/provider-files/kubernetes-expose-hostname.json b/script/test/fixtures/expose-service/provider-files/kubernetes-expose-hostname.json index 902be11a..98d604e3 100644 --- a/script/test/fixtures/expose-service/provider-files/kubernetes-expose-hostname.json +++ b/script/test/fixtures/expose-service/provider-files/kubernetes-expose-hostname.json @@ -63,7 +63,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "redis", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "redis" + } }, "spec": { "replicas": 1, @@ -100,6 +103,9 @@ "metadata": { "name": "web", "creationTimestamp": null, + "labels": { + "io.kompose.service": "web" + }, "annotations": { "kompose.service.expose": "batman.example.com" } diff --git a/script/test/fixtures/expose-service/provider-files/kubernetes-expose-true-multiple-ports.json b/script/test/fixtures/expose-service/provider-files/kubernetes-expose-true-multiple-ports.json index b6842d7b..e378ef9c 100644 --- a/script/test/fixtures/expose-service/provider-files/kubernetes-expose-true-multiple-ports.json +++ b/script/test/fixtures/expose-service/provider-files/kubernetes-expose-true-multiple-ports.json @@ -68,7 +68,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "redis", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "redis" + } }, "spec": { "replicas": 1, @@ -105,6 +108,9 @@ "metadata": { "name": "web", "creationTimestamp": null, + "labels": { + "io.kompose.service": "web" + }, "annotations": { "kompose.service.expose": "True" } diff --git a/script/test/fixtures/expose-service/provider-files/kubernetes-expose-true.json b/script/test/fixtures/expose-service/provider-files/kubernetes-expose-true.json index ab77b2a4..4a96c0bd 100644 --- a/script/test/fixtures/expose-service/provider-files/kubernetes-expose-true.json +++ b/script/test/fixtures/expose-service/provider-files/kubernetes-expose-true.json @@ -63,7 +63,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "redis", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "redis" + } }, "spec": { "replicas": 1, @@ -100,6 +103,9 @@ "metadata": { "name": "web", "creationTimestamp": null, + "labels": { + "io.kompose.service": "web" + }, "annotations": { "kompose.service.expose": "True" } diff --git a/script/test/fixtures/gitlab/output-k8s.json b/script/test/fixtures/gitlab/output-k8s.json index d09e8015..386875c0 100644 --- a/script/test/fixtures/gitlab/output-k8s.json +++ b/script/test/fixtures/gitlab/output-k8s.json @@ -96,7 +96,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "gitlab", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "gitlab" + } }, "spec": { "replicas": 1, @@ -172,7 +175,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "postgresql", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "postgresql" + } }, "spec": { "replicas": 1, @@ -222,7 +228,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "redis", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "redis" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/keyonly-envs/output-k8s.json b/script/test/fixtures/keyonly-envs/output-k8s.json index 5605984a..9b60c84e 100644 --- a/script/test/fixtures/keyonly-envs/output-k8s.json +++ b/script/test/fixtures/keyonly-envs/output-k8s.json @@ -86,7 +86,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "frontend", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "frontend" + } }, "spec": { "replicas": 1, @@ -140,7 +143,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "redis-master", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "redis-master" + } }, "spec": { "replicas": 1, @@ -176,7 +182,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "redis-slave", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "redis-slave" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/mem-limit/output-k8s.json b/script/test/fixtures/mem-limit/output-k8s.json index dd7828d3..02ba1b5b 100644 --- a/script/test/fixtures/mem-limit/output-k8s.json +++ b/script/test/fixtures/mem-limit/output-k8s.json @@ -40,7 +40,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "redis", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "redis" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/mem-limit/output-mb-k8s.json b/script/test/fixtures/mem-limit/output-mb-k8s.json index 868a3681..466de9c5 100644 --- a/script/test/fixtures/mem-limit/output-mb-k8s.json +++ b/script/test/fixtures/mem-limit/output-mb-k8s.json @@ -40,7 +40,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "redis", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "redis" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/multiple-compose-files/output-k8s.json b/script/test/fixtures/multiple-compose-files/output-k8s.json index 18c834d3..af03e694 100644 --- a/script/test/fixtures/multiple-compose-files/output-k8s.json +++ b/script/test/fixtures/multiple-compose-files/output-k8s.json @@ -70,7 +70,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "etherpad", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "etherpad" + } }, "spec": { "replicas": 1, @@ -131,7 +134,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "mariadb", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "mariadb" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/nginx-node-redis/output-k8s.json b/script/test/fixtures/nginx-node-redis/output-k8s.json index 707ab180..2e7fb750 100644 --- a/script/test/fixtures/nginx-node-redis/output-k8s.json +++ b/script/test/fixtures/nginx-node-redis/output-k8s.json @@ -138,7 +138,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "nginx", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "nginx" + } }, "spec": { "replicas": 1, @@ -173,7 +176,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "node1", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "node1" + } }, "spec": { "replicas": 1, @@ -208,7 +214,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "node2", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "node2" + } }, "spec": { "replicas": 1, @@ -243,7 +252,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "node3", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "node3" + } }, "spec": { "replicas": 1, @@ -278,7 +290,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "redis", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "redis" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/nginx-node-redis/output-os-template.json b/script/test/fixtures/nginx-node-redis/output-os-template.json index 202cbb81..384e0a0a 100644 --- a/script/test/fixtures/nginx-node-redis/output-os-template.json +++ b/script/test/fixtures/nginx-node-redis/output-os-template.json @@ -216,7 +216,10 @@ "apiVersion": "v1", "metadata": { "name": "nginx", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "nginx" + } }, "spec": { "triggers": [ @@ -337,7 +340,10 @@ "apiVersion": "v1", "metadata": { "name": "node1", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "node1" + } }, "spec": { "triggers": [ @@ -458,7 +464,10 @@ "apiVersion": "v1", "metadata": { "name": "node2", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "node2" + } }, "spec": { "triggers": [ @@ -579,7 +588,10 @@ "apiVersion": "v1", "metadata": { "name": "node3", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "node3" + } }, "spec": { "triggers": [ @@ -709,4 +721,4 @@ } } ] -} +} \ No newline at end of file diff --git a/script/test/fixtures/ports-with-ip/output-k8s.json b/script/test/fixtures/ports-with-ip/output-k8s.json index 07de3f8b..0a24eef9 100644 --- a/script/test/fixtures/ports-with-ip/output-k8s.json +++ b/script/test/fixtures/ports-with-ip/output-k8s.json @@ -66,7 +66,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "redis", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "redis" + } }, "spec": { "replicas": 1, @@ -106,7 +109,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "web", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "web" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/ports-with-proto/output-k8s.json b/script/test/fixtures/ports-with-proto/output-k8s.json index c62891b8..41aeb491 100644 --- a/script/test/fixtures/ports-with-proto/output-k8s.json +++ b/script/test/fixtures/ports-with-proto/output-k8s.json @@ -66,7 +66,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "redis", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "redis" + } }, "spec": { "replicas": 1, @@ -106,7 +109,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "web", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "web" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/service-name-change/output-k8s.json b/script/test/fixtures/service-name-change/output-k8s.json index 04443310..bd4699b1 100644 --- a/script/test/fixtures/service-name-change/output-k8s.json +++ b/script/test/fixtures/service-name-change/output-k8s.json @@ -66,7 +66,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "mariadb", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "mariadb" + } }, "spec": { "replicas": 1, @@ -149,7 +152,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "wordpress", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "wordpress" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/stdin-true/output-k8s.json b/script/test/fixtures/stdin-true/output-k8s.json index d200cdcf..9173c74b 100644 --- a/script/test/fixtures/stdin-true/output-k8s.json +++ b/script/test/fixtures/stdin-true/output-k8s.json @@ -34,7 +34,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "client", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "client" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/tty-true/output-k8s.json b/script/test/fixtures/tty-true/output-k8s.json index 07bef7f2..7d363af8 100644 --- a/script/test/fixtures/tty-true/output-k8s.json +++ b/script/test/fixtures/tty-true/output-k8s.json @@ -34,7 +34,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "client", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "client" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/volume-mounts/simple-vol-mounts/output-k8s.json b/script/test/fixtures/volume-mounts/simple-vol-mounts/output-k8s.json index 9d4bd7cc..4968cf09 100644 --- a/script/test/fixtures/volume-mounts/simple-vol-mounts/output-k8s.json +++ b/script/test/fixtures/volume-mounts/simple-vol-mounts/output-k8s.json @@ -34,7 +34,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "httpd", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "httpd" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/volume-mounts/volumes-from/output-k8s.json b/script/test/fixtures/volume-mounts/volumes-from/output-k8s.json index cd1fd90c..3fa7a774 100644 --- a/script/test/fixtures/volume-mounts/volumes-from/output-k8s.json +++ b/script/test/fixtures/volume-mounts/volumes-from/output-k8s.json @@ -60,7 +60,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "nginx", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "nginx" + } }, "spec": { "replicas": 1, @@ -144,7 +147,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "web", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "web" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/yaml-and-yml/output-k8s.json b/script/test/fixtures/yaml-and-yml/output-k8s.json index 167b0c19..fce4a9f3 100644 --- a/script/test/fixtures/yaml-and-yml/output-k8s.json +++ b/script/test/fixtures/yaml-and-yml/output-k8s.json @@ -60,7 +60,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "redis", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "redis" + } }, "spec": { "replicas": 1, @@ -96,7 +99,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "web", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "web" + } }, "spec": { "replicas": 1, diff --git a/script/test/fixtures/yaml-and-yml/yml/output-k8s.json b/script/test/fixtures/yaml-and-yml/yml/output-k8s.json index 167b0c19..fce4a9f3 100644 --- a/script/test/fixtures/yaml-and-yml/yml/output-k8s.json +++ b/script/test/fixtures/yaml-and-yml/yml/output-k8s.json @@ -60,7 +60,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "redis", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "redis" + } }, "spec": { "replicas": 1, @@ -96,7 +99,10 @@ "apiVersion": "extensions/v1beta1", "metadata": { "name": "web", - "creationTimestamp": null + "creationTimestamp": null, + "labels": { + "io.kompose.service": "web" + } }, "spec": { "replicas": 1, From bee784faf6052f753ad078be7392798475ca51f9 Mon Sep 17 00:00:00 2001 From: Tomas Kral Date: Thu, 27 Apr 2017 15:36:20 +0200 Subject: [PATCH 2/3] Use BuildConfig reaper to delete BuildConfig with all related pods --- pkg/transformer/openshift/openshift.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/transformer/openshift/openshift.go b/pkg/transformer/openshift/openshift.go index 93709bc7..d5a2326c 100644 --- a/pkg/transformer/openshift/openshift.go +++ b/pkg/transformer/openshift/openshift.go @@ -42,6 +42,7 @@ import ( "github.com/kubernetes-incubator/kompose/pkg/transformer" buildapi "github.com/openshift/origin/pkg/build/api" + buildconfigreaper "github.com/openshift/origin/pkg/build/cmd" deployapi "github.com/openshift/origin/pkg/deploy/api" deploymentconfigreaper "github.com/openshift/origin/pkg/deploy/cmd" imageapi "github.com/openshift/origin/pkg/image/api" @@ -593,7 +594,8 @@ func (o *OpenShift) Undeploy(komposeObject kobject.KomposeObject, opt kobject.Co } for _, l := range buildConfig.Items { if reflect.DeepEqual(l.Labels, komposeLabel) { - err := oclient.BuildConfigs(namespace).Delete(t.Name) + bcreaper := buildconfigreaper.NewBuildConfigReaper(oclient) + err := bcreaper.Stop(namespace, t.Name, TIMEOUT*time.Second, nil) if err != nil { errorList = append(errorList, err) break From 166eedfc1c309e663d4e2d98e4da8e07d56a3bd8 Mon Sep 17 00:00:00 2001 From: Tomas Kral Date: Thu, 27 Apr 2017 15:40:39 +0200 Subject: [PATCH 3/3] update vendor added files required by BuildConfig reaper --- .../openshift/origin/pkg/build/cmd/doc.go | 2 + .../openshift/origin/pkg/build/cmd/reaper.go | 150 +++++++++ .../openshift/origin/pkg/util/doc.go | 4 + .../openshift/origin/pkg/util/etcd.go | 21 ++ .../openshift/origin/pkg/util/labels.go | 286 ++++++++++++++++++ .../openshift/origin/pkg/util/strings.go | 21 ++ 6 files changed, 484 insertions(+) create mode 100644 vendor/github.com/openshift/origin/pkg/build/cmd/doc.go create mode 100644 vendor/github.com/openshift/origin/pkg/build/cmd/reaper.go create mode 100644 vendor/github.com/openshift/origin/pkg/util/doc.go create mode 100644 vendor/github.com/openshift/origin/pkg/util/etcd.go create mode 100644 vendor/github.com/openshift/origin/pkg/util/labels.go create mode 100644 vendor/github.com/openshift/origin/pkg/util/strings.go diff --git a/vendor/github.com/openshift/origin/pkg/build/cmd/doc.go b/vendor/github.com/openshift/origin/pkg/build/cmd/doc.go new file mode 100644 index 00000000..e9cc603a --- /dev/null +++ b/vendor/github.com/openshift/origin/pkg/build/cmd/doc.go @@ -0,0 +1,2 @@ +// Package cmd provides command helpers for builds +package cmd diff --git a/vendor/github.com/openshift/origin/pkg/build/cmd/reaper.go b/vendor/github.com/openshift/origin/pkg/build/cmd/reaper.go new file mode 100644 index 00000000..11fb11a5 --- /dev/null +++ b/vendor/github.com/openshift/origin/pkg/build/cmd/reaper.go @@ -0,0 +1,150 @@ +package cmd + +import ( + "sort" + "strings" + "time" + + "github.com/golang/glog" + kapi "k8s.io/kubernetes/pkg/api" + kerrors "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/kubectl" + ktypes "k8s.io/kubernetes/pkg/types" + kutilerrors "k8s.io/kubernetes/pkg/util/errors" + + buildapi "github.com/openshift/origin/pkg/build/api" + buildutil "github.com/openshift/origin/pkg/build/util" + "github.com/openshift/origin/pkg/client" + "github.com/openshift/origin/pkg/util" +) + +// NewBuildConfigReaper returns a new reaper for buildConfigs +func NewBuildConfigReaper(oc *client.Client) kubectl.Reaper { + return &BuildConfigReaper{oc: oc, pollInterval: kubectl.Interval, timeout: kubectl.Timeout} +} + +// BuildConfigReaper implements the Reaper interface for buildConfigs +type BuildConfigReaper struct { + oc client.Interface + pollInterval, timeout time.Duration +} + +// Stop deletes the build configuration and all of the associated builds. +func (reaper *BuildConfigReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *kapi.DeleteOptions) error { + _, err := reaper.oc.BuildConfigs(namespace).Get(name) + + if err != nil { + return err + } + + var bcPotentialBuilds []buildapi.Build + + // Collect builds related to the config. + builds, err := reaper.oc.Builds(namespace).List(kapi.ListOptions{LabelSelector: buildutil.BuildConfigSelector(name)}) + if err != nil { + return err + } + + bcPotentialBuilds = append(bcPotentialBuilds, builds.Items...) + + // Collect deprecated builds related to the config. + // TODO: Delete this block after BuildConfigLabelDeprecated is removed. + builds, err = reaper.oc.Builds(namespace).List(kapi.ListOptions{LabelSelector: buildutil.BuildConfigSelectorDeprecated(name)}) + if err != nil { + return err + } + + bcPotentialBuilds = append(bcPotentialBuilds, builds.Items...) + + // A map of builds associated with this build configuration + bcBuilds := make(map[ktypes.UID]buildapi.Build) + + // Because of name length limits in the BuildConfigSelector, annotations are used to ensure + // reliable selection of associated builds. + for _, build := range bcPotentialBuilds { + if build.Annotations != nil { + if bcName, ok := build.Annotations[buildapi.BuildConfigAnnotation]; ok { + // The annotation, if present, has the full build config name. + if bcName != name { + // If the name does not match exactly, the build is not truly associated with the build configuration + continue + } + } + } + // Note that if there is no annotation, this is a deprecated build spec + // and we choose to include it in the deletion having matched only the BuildConfigSelectorDeprecated + + // Use a map to union the lists returned by the contemporary & deprecated build queries + // (there will be overlap between the lists, and we only want to try to delete each build once) + bcBuilds[build.UID] = build + } + + // If there are builds associated with this build configuration, pause it before attempting the deletion + if len(bcBuilds) > 0 { + + // Add paused annotation to the build config pending the deletion + err = unversioned.RetryOnConflict(unversioned.DefaultRetry, func() error { + + bc, err := reaper.oc.BuildConfigs(namespace).Get(name) + if err != nil { + return err + } + + // Ignore if the annotation already exists + if strings.ToLower(bc.Annotations[buildapi.BuildConfigPausedAnnotation]) == "true" { + return nil + } + + // Set the annotation and update + if err := util.AddObjectAnnotations(bc, map[string]string{buildapi.BuildConfigPausedAnnotation: "true"}); err != nil { + return err + } + _, err = reaper.oc.BuildConfigs(namespace).Update(bc) + return err + }) + + if err != nil { + return err + } + + } + + // Warn the user if the BuildConfig won't get deleted after this point. + bcDeleted := false + defer func() { + if !bcDeleted { + glog.Warningf("BuildConfig %s/%s will not be deleted because not all associated builds could be deleted. You can try re-running the command or removing them manually", namespace, name) + } + }() + + // For the benefit of test cases, sort the UIDs so that the deletion order is deterministic + buildUIDs := make([]string, 0, len(bcBuilds)) + for buildUID := range bcBuilds { + buildUIDs = append(buildUIDs, string(buildUID)) + } + sort.Strings(buildUIDs) + + errList := []error{} + for _, buildUID := range buildUIDs { + build := bcBuilds[ktypes.UID(buildUID)] + if err := reaper.oc.Builds(namespace).Delete(build.Name); err != nil { + glog.Warningf("Cannot delete Build %s/%s: %v", build.Namespace, build.Name, err) + if !kerrors.IsNotFound(err) { + errList = append(errList, err) + } + } + } + + // Aggregate all errors + if len(errList) > 0 { + return kutilerrors.NewAggregate(errList) + } + + if err := reaper.oc.BuildConfigs(namespace).Delete(name); err != nil { + return err + } + + bcDeleted = true + return nil +} diff --git a/vendor/github.com/openshift/origin/pkg/util/doc.go b/vendor/github.com/openshift/origin/pkg/util/doc.go new file mode 100644 index 00000000..3ce2be72 --- /dev/null +++ b/vendor/github.com/openshift/origin/pkg/util/doc.go @@ -0,0 +1,4 @@ +// Package util implements various utility functions used in both testing and +// implementation of OpenShift. Package util may not depend on any other +// package in the OpenShift package tree. +package util diff --git a/vendor/github.com/openshift/origin/pkg/util/etcd.go b/vendor/github.com/openshift/origin/pkg/util/etcd.go new file mode 100644 index 00000000..754f49d9 --- /dev/null +++ b/vendor/github.com/openshift/origin/pkg/util/etcd.go @@ -0,0 +1,21 @@ +package util + +import ( + "path" + + kapi "k8s.io/kubernetes/pkg/api" + kerrors "k8s.io/kubernetes/pkg/api/errors" +) + +// NoNamespaceKeyFunc is the default function for constructing etcd paths to a resource relative to prefix enforcing +// If a namespace is on context, it errors. +func NoNamespaceKeyFunc(ctx kapi.Context, prefix string, name string) (string, error) { + ns, ok := kapi.NamespaceFrom(ctx) + if ok && len(ns) > 0 { + return "", kerrors.NewBadRequest("Namespace parameter is not allowed.") + } + if len(name) == 0 { + return "", kerrors.NewBadRequest("Name parameter required.") + } + return path.Join(prefix, name), nil +} diff --git a/vendor/github.com/openshift/origin/pkg/util/labels.go b/vendor/github.com/openshift/origin/pkg/util/labels.go new file mode 100644 index 00000000..eba90666 --- /dev/null +++ b/vendor/github.com/openshift/origin/pkg/util/labels.go @@ -0,0 +1,286 @@ +package util + +import ( + "fmt" + "reflect" + + kmeta "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/runtime" + + deployapi "github.com/openshift/origin/pkg/deploy/api" +) + +// MergeInto flags +const ( + OverwriteExistingDstKey = 1 << iota + ErrorOnExistingDstKey + ErrorOnDifferentDstKeyValue +) + +// AddObjectLabelsWithFlags will set labels on the target object. Label overwrite behavior +// is controlled by the flags argument. +func AddObjectLabelsWithFlags(obj runtime.Object, labels labels.Set, flags int) error { + if labels == nil { + return nil + } + + accessor, err := kmeta.Accessor(obj) + + if err != nil { + if _, ok := obj.(*runtime.Unstructured); !ok { + // error out if it's not possible to get an accessor and it's also not an unstructured object + return err + } + } else { + metaLabels := accessor.GetLabels() + if metaLabels == nil { + metaLabels = make(map[string]string) + } + + switch objType := obj.(type) { + case *deployapi.DeploymentConfig: + if err := addDeploymentConfigNestedLabels(objType, labels, flags); err != nil { + return fmt.Errorf("unable to add nested labels to %s/%s: %v", obj.GetObjectKind().GroupVersionKind(), accessor.GetName(), err) + } + } + + if err := MergeInto(metaLabels, labels, flags); err != nil { + return fmt.Errorf("unable to add labels to %s/%s: %v", obj.GetObjectKind().GroupVersionKind(), accessor.GetName(), err) + } + + accessor.SetLabels(metaLabels) + + return nil + } + + // handle unstructured object + // TODO: allow meta.Accessor to handle runtime.Unstructured + if unstruct, ok := obj.(*runtime.Unstructured); ok && unstruct.Object != nil { + // the presence of "metadata" is sufficient for us to apply the rules for Kube-like + // objects. + // TODO: add swagger detection to allow this to happen more effectively + if obj, ok := unstruct.Object["metadata"]; ok { + if m, ok := obj.(map[string]interface{}); ok { + + existing := make(map[string]string) + if l, ok := m["labels"]; ok { + if found, ok := interfaceToStringMap(l); ok { + existing = found + } + } + if err := MergeInto(existing, labels, flags); err != nil { + return err + } + m["labels"] = mapToGeneric(existing) + } + return nil + } + + // only attempt to set root labels if a root object called labels exists + // TODO: add swagger detection to allow this to happen more effectively + if obj, ok := unstruct.Object["labels"]; ok { + existing := make(map[string]string) + if found, ok := interfaceToStringMap(obj); ok { + existing = found + } + if err := MergeInto(existing, labels, flags); err != nil { + return err + } + unstruct.Object["labels"] = mapToGeneric(existing) + return nil + } + } + + return nil + +} + +// AddObjectLabels adds new label(s) to a single runtime.Object, overwriting +// existing labels that have the same key. +func AddObjectLabels(obj runtime.Object, labels labels.Set) error { + return AddObjectLabelsWithFlags(obj, labels, OverwriteExistingDstKey) +} + +// AddObjectAnnotations adds new annotation(s) to a single runtime.Object +func AddObjectAnnotations(obj runtime.Object, annotations map[string]string) error { + if len(annotations) == 0 { + return nil + } + + accessor, err := kmeta.Accessor(obj) + + if err != nil { + if _, ok := obj.(*runtime.Unstructured); !ok { + // error out if it's not possible to get an accessor and it's also not an unstructured object + return err + } + } else { + metaAnnotations := accessor.GetAnnotations() + if metaAnnotations == nil { + metaAnnotations = make(map[string]string) + } + + switch objType := obj.(type) { + case *deployapi.DeploymentConfig: + if err := addDeploymentConfigNestedAnnotations(objType, annotations); err != nil { + return fmt.Errorf("unable to add nested annotations to %s/%s: %v", obj.GetObjectKind().GroupVersionKind(), accessor.GetName(), err) + } + } + + MergeInto(metaAnnotations, annotations, OverwriteExistingDstKey) + accessor.SetAnnotations(metaAnnotations) + + return nil + } + + // handle unstructured object + // TODO: allow meta.Accessor to handle runtime.Unstructured + if unstruct, ok := obj.(*runtime.Unstructured); ok && unstruct.Object != nil { + // the presence of "metadata" is sufficient for us to apply the rules for Kube-like + // objects. + // TODO: add swagger detection to allow this to happen more effectively + if obj, ok := unstruct.Object["metadata"]; ok { + if m, ok := obj.(map[string]interface{}); ok { + + existing := make(map[string]string) + if l, ok := m["annotations"]; ok { + if found, ok := interfaceToStringMap(l); ok { + existing = found + } + } + if err := MergeInto(existing, annotations, OverwriteExistingDstKey); err != nil { + return err + } + m["annotations"] = mapToGeneric(existing) + } + return nil + } + + // only attempt to set root annotations if a root object called annotations exists + // TODO: add swagger detection to allow this to happen more effectively + if obj, ok := unstruct.Object["annotations"]; ok { + existing := make(map[string]string) + if found, ok := interfaceToStringMap(obj); ok { + existing = found + } + if err := MergeInto(existing, annotations, OverwriteExistingDstKey); err != nil { + return err + } + unstruct.Object["annotations"] = mapToGeneric(existing) + return nil + } + } + + return nil +} + +// addDeploymentConfigNestedLabels adds new label(s) to a nested labels of a single DeploymentConfig object +func addDeploymentConfigNestedLabels(obj *deployapi.DeploymentConfig, labels labels.Set, flags int) error { + if obj.Spec.Template.Labels == nil { + obj.Spec.Template.Labels = make(map[string]string) + } + if err := MergeInto(obj.Spec.Template.Labels, labels, flags); err != nil { + return fmt.Errorf("unable to add labels to Template.DeploymentConfig.Template.ControllerTemplate.Template: %v", err) + } + return nil +} + +func addDeploymentConfigNestedAnnotations(obj *deployapi.DeploymentConfig, annotations map[string]string) error { + if obj.Spec.Template == nil { + return nil + } + + if obj.Spec.Template.Annotations == nil { + obj.Spec.Template.Annotations = make(map[string]string) + } + + if err := MergeInto(obj.Spec.Template.Annotations, annotations, OverwriteExistingDstKey); err != nil { + return fmt.Errorf("unable to add annotations to Template.DeploymentConfig.Template.ControllerTemplate.Template: %v", err) + } + return nil +} + +// interfaceToStringMap extracts a map[string]string from a map[string]interface{} +func interfaceToStringMap(obj interface{}) (map[string]string, bool) { + if obj == nil { + return nil, false + } + lm, ok := obj.(map[string]interface{}) + if !ok { + return nil, false + } + existing := make(map[string]string) + for k, v := range lm { + switch t := v.(type) { + case string: + existing[k] = t + } + } + return existing, true +} + +// mapToGeneric converts a map[string]string into a map[string]interface{} +func mapToGeneric(obj map[string]string) map[string]interface{} { + if obj == nil { + return nil + } + res := make(map[string]interface{}) + for k, v := range obj { + res[k] = v + } + return res +} + +// MergeInto merges items from a src map into a dst map. +// Returns an error when the maps are not of the same type. +// Flags: +// - ErrorOnExistingDstKey +// When set: Return an error if any of the dst keys is already set. +// - ErrorOnDifferentDstKeyValue +// When set: Return an error if any of the dst keys is already set +// to a different value than src key. +// - OverwriteDstKey +// When set: Overwrite existing dst key value with src key value. +func MergeInto(dst, src interface{}, flags int) error { + dstVal := reflect.ValueOf(dst) + srcVal := reflect.ValueOf(src) + + if dstVal.Kind() != reflect.Map { + return fmt.Errorf("dst is not a valid map: %v", dstVal.Kind()) + } + if srcVal.Kind() != reflect.Map { + return fmt.Errorf("src is not a valid map: %v", srcVal.Kind()) + } + if dstTyp, srcTyp := dstVal.Type(), srcVal.Type(); !dstTyp.AssignableTo(srcTyp) { + return fmt.Errorf("type mismatch, can't assign '%v' to '%v'", srcTyp, dstTyp) + } + + if dstVal.IsNil() { + return fmt.Errorf("dst value is nil") + } + if srcVal.IsNil() { + // Nothing to merge + return nil + } + + for _, k := range srcVal.MapKeys() { + if dstVal.MapIndex(k).IsValid() { + if flags&ErrorOnExistingDstKey != 0 { + return fmt.Errorf("dst key already set (ErrorOnExistingDstKey=1), '%v'='%v'", k, dstVal.MapIndex(k)) + } + if dstVal.MapIndex(k).String() != srcVal.MapIndex(k).String() { + if flags&ErrorOnDifferentDstKeyValue != 0 { + return fmt.Errorf("dst key already set to a different value (ErrorOnDifferentDstKeyValue=1), '%v'='%v'", k, dstVal.MapIndex(k)) + } + if flags&OverwriteExistingDstKey != 0 { + dstVal.SetMapIndex(k, srcVal.MapIndex(k)) + } + } + } else { + dstVal.SetMapIndex(k, srcVal.MapIndex(k)) + } + } + + return nil +} diff --git a/vendor/github.com/openshift/origin/pkg/util/strings.go b/vendor/github.com/openshift/origin/pkg/util/strings.go new file mode 100644 index 00000000..cf1b4804 --- /dev/null +++ b/vendor/github.com/openshift/origin/pkg/util/strings.go @@ -0,0 +1,21 @@ +package util + +import "sort" + +// UniqueStrings returns a sorted, uniquified slice of the specified strings +func UniqueStrings(strings []string) []string { + m := make(map[string]bool, len(strings)) + for _, s := range strings { + m[s] = true + } + + i := 0 + strings = make([]string, len(m), len(m)) + for s := range m { + strings[i] = s + i++ + } + + sort.Strings(strings) + return strings +}