Skip to content

Commit 8f166b4

Browse files
committed
fix: allow multiple namespace deploy
1 parent 7d3b745 commit 8f166b4

13 files changed

Lines changed: 205 additions & 28 deletions

File tree

e2e/tests/deploy/deploy.go

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@ package deploy
22

33
import (
44
"context"
5-
"github.com/loft-sh/devspace/pkg/devspace/kubectl"
6-
"os"
7-
"path/filepath"
8-
95
"github.com/loft-sh/devspace/cmd"
106
"github.com/loft-sh/devspace/cmd/flags"
117
"github.com/loft-sh/devspace/e2e/framework"
128
"github.com/loft-sh/devspace/e2e/kube"
9+
"github.com/loft-sh/devspace/pkg/devspace/kubectl"
1310
"github.com/loft-sh/devspace/pkg/util/factory"
1411
"github.com/onsi/ginkgo"
12+
"io/ioutil"
1513
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
14+
"os"
15+
"path/filepath"
16+
"strings"
1617
)
1718

1819
var _ = DevSpaceDescribe("deploy", func() {
@@ -38,6 +39,87 @@ var _ = DevSpaceDescribe("deploy", func() {
3839
// TODO
3940
})
4041

42+
ginkgo.It("should deploy multiple namespaces", func() {
43+
tempDir, err := framework.CopyToTempDir("tests/deploy/testdata/different_namespaces")
44+
framework.ExpectNoError(err)
45+
defer framework.CleanupTempDir(initialDir, tempDir)
46+
47+
ns, err := kubeClient.CreateNamespace("deploy")
48+
framework.ExpectNoError(err)
49+
defer func() {
50+
err := kubeClient.DeleteNamespace(ns)
51+
framework.ExpectNoError(err)
52+
}()
53+
54+
ns2, err := kubeClient.CreateNamespace("deploy")
55+
framework.ExpectNoError(err)
56+
defer func() {
57+
err := kubeClient.DeleteNamespace(ns2)
58+
framework.ExpectNoError(err)
59+
}()
60+
61+
// exchange kube manifests
62+
manifests := filepath.Join(tempDir, "kube", "service1.yaml")
63+
out, err := ioutil.ReadFile(manifests)
64+
framework.ExpectNoError(err)
65+
66+
data := strings.Replace(string(out), "###NAMESPACE1###", ns, -1)
67+
data = strings.Replace(data, "###NAMESPACE2###", ns2, -1)
68+
69+
err = ioutil.WriteFile(manifests, []byte(data), 0777)
70+
framework.ExpectNoError(err)
71+
72+
// create a new deploy command
73+
deployCmd := &cmd.RunPipelineCmd{
74+
GlobalFlags: &flags.GlobalFlags{
75+
NoWarn: true,
76+
Namespace: ns,
77+
Vars: []string{
78+
"NAMESPACE1=" + ns,
79+
"NAMESPACE2=" + ns2,
80+
},
81+
},
82+
Pipeline: "deploy",
83+
}
84+
85+
// run the command
86+
err = deployCmd.RunDefault(f)
87+
framework.ExpectNoError(err)
88+
89+
// check if services are there
90+
_, err = kubeClient.RawClient().CoreV1().Services(ns).Get(context.TODO(), "service1", metav1.GetOptions{})
91+
framework.ExpectNoError(err)
92+
_, err = kubeClient.RawClient().CoreV1().Services(ns).Get(context.TODO(), "service2", metav1.GetOptions{})
93+
framework.ExpectNoError(err)
94+
_, err = kubeClient.RawClient().CoreV1().Services(ns2).Get(context.TODO(), "service1", metav1.GetOptions{})
95+
framework.ExpectNoError(err)
96+
_, err = kubeClient.RawClient().CoreV1().Services(ns2).Get(context.TODO(), "service2", metav1.GetOptions{})
97+
framework.ExpectNoError(err)
98+
99+
// create a new purge command
100+
purgeCmd := &cmd.RunPipelineCmd{
101+
GlobalFlags: &flags.GlobalFlags{
102+
NoWarn: true,
103+
Namespace: ns,
104+
},
105+
Pipeline: "purge",
106+
}
107+
108+
// run the command
109+
err = purgeCmd.RunDefault(f)
110+
framework.ExpectNoError(err)
111+
112+
// check if services are there
113+
_, err = kubeClient.RawClient().CoreV1().Services(ns).Get(context.TODO(), "service1", metav1.GetOptions{})
114+
framework.ExpectError(err)
115+
_, err = kubeClient.RawClient().CoreV1().Services(ns).Get(context.TODO(), "service2", metav1.GetOptions{})
116+
framework.ExpectError(err)
117+
_, err = kubeClient.RawClient().CoreV1().Services(ns2).Get(context.TODO(), "service1", metav1.GetOptions{})
118+
framework.ExpectError(err)
119+
_, err = kubeClient.RawClient().CoreV1().Services(ns2).Get(context.TODO(), "service2", metav1.GetOptions{})
120+
framework.ExpectError(err)
121+
})
122+
41123
ginkgo.It("should deploy concurrent deployments", func() {
42124
tempDir, err := framework.CopyToTempDir("tests/deploy/testdata/helm_concurrent_new")
43125
framework.ExpectNoError(err)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
apiVersion: v2
2+
name: test
3+
description: Test Chart
4+
type: application
5+
version: 0.0.1
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: service1
5+
namespace: {{ .Values.namespace1 }}
6+
spec:
7+
type: ClusterIP
8+
ports:
9+
- name: https
10+
port: 443
11+
targetPort: 8443
12+
protocol: TCP
13+
selector:
14+
app: vcluster
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: service1
5+
namespace: {{ .Values.namespace2 }}
6+
spec:
7+
type: ClusterIP
8+
ports:
9+
- name: https
10+
port: 443
11+
targetPort: 8443
12+
protocol: TCP
13+
selector:
14+
app: vcluster2
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
version: v2beta1
2+
name: different-namespaces
3+
4+
vars:
5+
NAMESPACE1: namespace1
6+
NAMESPACE2: namespace2
7+
8+
deployments:
9+
helm:
10+
namespace: ""
11+
helm:
12+
chart:
13+
path: chart
14+
values:
15+
namespace1: ${NAMESPACE1}
16+
namespace2: ${NAMESPACE2}
17+
18+
kubectl:
19+
namespace: ""
20+
kubectl:
21+
manifests:
22+
- kube
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: service2
5+
namespace: ###NAMESPACE1###
6+
spec:
7+
type: ClusterIP
8+
ports:
9+
- name: https
10+
port: 443
11+
targetPort: 8443
12+
protocol: TCP
13+
selector:
14+
app: vcluster3
15+
---
16+
apiVersion: v1
17+
kind: Service
18+
metadata:
19+
name: service2
20+
namespace: ###NAMESPACE2###
21+
spec:
22+
type: ClusterIP
23+
ports:
24+
- name: https
25+
port: 443
26+
targetPort: 8443
27+
protocol: TCP
28+
selector:
29+
app: vcluster4

pkg/devspace/config/versions/latest/schema.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ type DeploymentConfig struct {
587587
// Name of the deployment
588588
Name string `yaml:"name,omitempty" json:"name,omitempty"`
589589
// Namespace where to deploy this deployment
590-
Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`
590+
Namespace *string `yaml:"namespace,omitempty" json:"namespace,omitempty"`
591591
// UpdateImageTags lets you define if DevSpace should update the tags of the images defined in the
592592
// images section with their most recent built tag.
593593
UpdateImageTags *bool `yaml:"updateImageTags,omitempty" json:"updateImageTags,omitempty"`

pkg/devspace/config/versions/v1beta11/upgrade.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,10 @@ func (c *Config) Upgrade(log log.Logger) (config.Config, error) {
415415

416416
name := encoding.Convert(deployment.Name)
417417
nextConfig.Deployments[name] = &next.DeploymentConfig{
418-
Name: name,
419-
Namespace: deployment.Namespace,
418+
Name: name,
419+
}
420+
if deployment.Namespace != "" {
421+
nextConfig.Deployments[name].Namespace = &deployment.Namespace
420422
}
421423
if deployment.Helm != nil {
422424
nextConfig.Deployments[name].Helm = &next.HelmConfig{

pkg/devspace/deploy/deploy.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ func (c *controller) deployOne(ctx devspacecontext.Context, deployConfig *latest
171171
method string
172172
)
173173

174-
if !options.Render && deployConfig.Namespace != "" {
175-
err = kubectlclient.EnsureNamespace(ctx.Context(), ctx.KubeClient(), deployConfig.Namespace, ctx.Log())
174+
if !options.Render && deployConfig.Namespace != nil && *deployConfig.Namespace != "" {
175+
err = kubectlclient.EnsureNamespace(ctx.Context(), ctx.KubeClient(), *deployConfig.Namespace, ctx.Log())
176176
if err != nil {
177177
return false, err
178178
}

pkg/devspace/deploy/deployer/helm/deploy.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ func (d *DeployConfig) Deploy(ctx devspacecontext.Context, forceDeploy bool) (bo
3232
hash = ""
3333
)
3434

35-
releaseNamespace := d.DeploymentConfig.Namespace
36-
if releaseNamespace == "" {
37-
releaseNamespace = ctx.KubeClient().Namespace()
35+
releaseNamespace := ctx.KubeClient().Namespace()
36+
if d.DeploymentConfig.Namespace != nil && *d.DeploymentConfig.Namespace != "" {
37+
releaseNamespace = *d.DeploymentConfig.Namespace
3838
}
3939

4040
// Hash the chart directory if there is any
@@ -152,9 +152,12 @@ func (d *DeployConfig) Deploy(ctx devspacecontext.Context, forceDeploy bool) (bo
152152

153153
func (d *DeployConfig) internalDeploy(ctx devspacecontext.Context, overwriteValues map[string]interface{}, out io.Writer) (*types.Release, error) {
154154
var (
155-
releaseName = d.DeploymentConfig.Name
156-
releaseNamespace = d.DeploymentConfig.Namespace
155+
releaseName = d.DeploymentConfig.Name
157156
)
157+
releaseNamespace := ctx.KubeClient().Namespace()
158+
if d.DeploymentConfig.Namespace != nil && *d.DeploymentConfig.Namespace != "" {
159+
releaseNamespace = *d.DeploymentConfig.Namespace
160+
}
158161

159162
if out != nil {
160163
str, err := d.Helm.Template(ctx, releaseName, releaseNamespace, overwriteValues, d.DeploymentConfig.Helm)

0 commit comments

Comments
 (0)