Skip to content

Commit b13898a

Browse files
authored
Merge pull request #2500 from 89luca89/main
Feature: Add support for InlineManifest blocks in Kubectl deployments
2 parents ca6928a + 5b586c6 commit b13898a

12 files changed

Lines changed: 311 additions & 47 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
.DS_STORE
2020
.idea
2121
.devspace/
22+
tags
2223

2324
# VS Code
2425
.vscode/ipch

e2e/tests/deploy/deploy.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,37 @@ var _ = DevSpaceDescribe("deploy", func() {
312312
framework.ExpectNoError(err)
313313
})
314314

315+
ginkgo.It("should deploy kubectl application with inline manifest", func() {
316+
tempDir, err := framework.CopyToTempDir("tests/deploy/testdata/kubectl_inline_manifest")
317+
framework.ExpectNoError(err)
318+
defer framework.CleanupTempDir(initialDir, tempDir)
319+
320+
ns, err := kubeClient.CreateNamespace("deploy")
321+
framework.ExpectNoError(err)
322+
defer func() {
323+
err := kubeClient.DeleteNamespace(ns)
324+
framework.ExpectNoError(err)
325+
}()
326+
327+
// create a new dev command
328+
deployCmd := &cmd.RunPipelineCmd{
329+
GlobalFlags: &flags.GlobalFlags{
330+
NoWarn: true,
331+
Namespace: ns,
332+
},
333+
Pipeline: "deploy",
334+
}
335+
336+
// run the command
337+
err = deployCmd.RunDefault(f)
338+
framework.ExpectNoError(err)
339+
340+
// wait until nginx pod is reachable
341+
out, err := kubeClient.ExecByImageSelector("busybox", ns, []string{"echo", "-n", "test"})
342+
framework.ExpectNoError(err)
343+
framework.ExpectEqual(out, "test")
344+
})
345+
315346
ginkgo.It("should deploy helm chart from git repo", func() {
316347
tempDir, err := framework.CopyToTempDir("tests/deploy/testdata/helm_git")
317348
framework.ExpectNoError(err)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
version: v2beta1
2+
3+
deployments:
4+
test:
5+
kubectl:
6+
inlineManifest: |-
7+
apiVersion: v1
8+
kind: Pod
9+
metadata:
10+
name: pods-simple-pod-2
11+
spec:
12+
containers:
13+
- command:
14+
- sleep
15+
- "3600"
16+
image: busybox
17+
name: pods-simple-container-2
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Dockerfile
2+
.devspace/
3+
kube/
4+
node_modules/

examples/inlineManifest/.gitignore

Whitespace-only changes.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
version: v2beta1
2+
name: inline-manifest
3+
4+
deployments:
5+
quickstart:
6+
kubectl:
7+
inlineManifest: |-
8+
kind: Deployment
9+
apiVersion: apps/v1
10+
metadata:
11+
name: devspace
12+
spec:
13+
replicas: 1
14+
selector:
15+
matchLabels:
16+
app.kubernetes.io/component: default
17+
app.kubernetes.io/name: devspace-app
18+
template:
19+
metadata:
20+
labels:
21+
app.kubernetes.io/component: default
22+
app.kubernetes.io/name: devspace-app
23+
spec:
24+
containers:
25+
- name: default
26+
# The correct image tag will be inserted during devspace dev / devspace deploy
27+
image: mydockeruser/quickstart
28+
---
29+
apiVersion: v1
30+
kind: Service
31+
metadata:
32+
labels:
33+
app.kubernetes.io/name: devspace-app
34+
name: external
35+
spec:
36+
ports:
37+
- name: port-0
38+
port: 80
39+
protocol: TCP
40+
targetPort: 3000
41+
selector:
42+
app.kubernetes.io/component: default
43+
app.kubernetes.io/name: devspace-app
44+
type: ClusterIP
45+
46+
dev:
47+
my-dev:
48+
imageSelector: mydockeruser/quickstart
49+
# Use this image for development
50+
devImage: loftsh/javascript:latest
51+
# Start port forwarding
52+
ports:
53+
- port: 3000
54+
# Start file sync
55+
sync:
56+
- path: ./
57+
excludePaths:
58+
- node_modules
59+
# Open url as soon as ready
60+
open:
61+
- url: http://localhost:3000
62+
# Start terminal forwarding with script entrypoint
63+
terminal:
64+
command: ./devspace_start.sh
65+
# Start remote ssh server
66+
ssh: {}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/bin/bash
2+
set +e # Continue on errors
3+
4+
export NODE_ENV=development
5+
if [ -f "yarn.lock" ] && [ ! -d "node_modules" ]; then
6+
echo "Installing Yarn Dependencies"
7+
yarn
8+
else
9+
if [ -f "package.json" ] && [ ! -d "node_modules" ]; then
10+
echo "Installing NPM Dependencies"
11+
npm install
12+
fi
13+
fi
14+
15+
COLOR_CYAN="\033[0;36m"
16+
COLOR_RESET="\033[0m"
17+
18+
echo -e "${COLOR_CYAN}
19+
____ ____
20+
| _ \ _____ __/ ___| _ __ __ _ ___ ___
21+
| | | |/ _ \ \ / /\___ \| '_ \ / _\` |/ __/ _ \\
22+
| |_| | __/\ V / ___) | |_) | (_| | (_| __/
23+
|____/ \___| \_/ |____/| .__/ \__,_|\___\___|
24+
|_|
25+
${COLOR_RESET}
26+
Welcome to your development container!
27+
This is how you can work with it:
28+
- Run \`${COLOR_CYAN}npm start${COLOR_RESET}\` to start the application
29+
- ${COLOR_CYAN}Files will be synchronized${COLOR_RESET} between your local machine and this container
30+
- Use \`${COLOR_CYAN}ssh my-dev.quickstart.devspace${COLOR_RESET}\` to access the application via SSH
31+
- Some ports will be forwarded, so you can access this container on your local machine via ${COLOR_CYAN}http://localhost:3000${COLOR_RESET}
32+
"
33+
34+
bash

pkg/devspace/config/loader/loader_test.go

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,16 +1469,16 @@ vars:
14691469
version: v1beta7
14701470
deployments:
14711471
- name: test
1472-
kubectl:
1472+
kubectl:
14731473
manifests:
14741474
- test.yaml
14751475
- name: test2
1476-
kubectl:
1476+
kubectl:
14771477
manifests:
14781478
- test.yaml
14791479
profiles:
14801480
- name: parent
1481-
replace:
1481+
replace:
14821482
images:
14831483
test:
14841484
image: test
@@ -1542,6 +1542,50 @@ purge_deployments replaced2 test2 --sequential`,
15421542
},
15431543
},
15441544
},
1545+
{
1546+
name: "Inline manifest and normal manifest error",
1547+
in: &parseTestCaseInput{
1548+
config: `
1549+
version: v2beta1
1550+
name: inline-manifest
1551+
1552+
deployments:
1553+
test:
1554+
kubectl:
1555+
manifests:
1556+
- test.yaml
1557+
inlineManifest: |-
1558+
kind: Deployment
1559+
apiVersion: apps/v1
1560+
metadata:
1561+
name: test
1562+
spec:
1563+
replicas: 1
1564+
selector:
1565+
matchLabels:
1566+
app.kubernetes.io/component: default
1567+
app.kubernetes.io/name: test
1568+
template:
1569+
metadata:
1570+
labels:
1571+
app.kubernetes.io/component: default
1572+
app.kubernetes.io/name: test
1573+
spec:
1574+
containers:
1575+
- name: default
1576+
image: test
1577+
profiles:
1578+
- name: test
1579+
replace:
1580+
images:
1581+
test:
1582+
image: test`,
1583+
options: &ConfigOptions{Profiles: []string{"test"}},
1584+
generatedConfig: &localcache.LocalCache{Vars: map[string]string{}},
1585+
},
1586+
expectedErr: "deployments[test].kubectl.manifests and deployments[test].kubectl.inlineManifest cannot be used together",
1587+
},
1588+
15451589
{
15461590
name: "Profile loop error",
15471591
in: &parseTestCaseInput{
@@ -1553,7 +1597,7 @@ deployments:
15531597
profiles:
15541598
- name: parent
15551599
parent: test
1556-
replace:
1600+
replace:
15571601
images:
15581602
test:
15591603
image: test

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,8 @@ type KubectlConfig struct {
868868
// KubectlBinaryPath is the optional path where to find the kubectl binary
869869
KubectlBinaryPath string `yaml:"kubectlBinaryPath,omitempty" json:"kubectlBinaryPath,omitempty"`
870870

871+
// InlineManists is a block containing the manifest to deploy
872+
InlineManifest string `yaml:"inlineManifest,omitempty" json:"inlineManifest,omitempty"`
871873
// Kustomize can be used to enable kustomize instead of kubectl
872874
Kustomize *bool `yaml:"kustomize,omitempty" json:"kustomize,omitempty" jsonschema_extras:"group=kustomize,group_name=Kustomize"`
873875
// KustomizeArgs are extra arguments for `kustomize build` which will be run before `kubectl apply`

pkg/devspace/config/versions/validate.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,11 @@ func validateDeployments(config *latest.Config) error {
256256
if deployConfig.Helm == nil && deployConfig.Kubectl == nil {
257257
return errors.Errorf("Please specify either helm or kubectl as deployment type in deployment %s", deployConfig.Name)
258258
}
259-
if deployConfig.Kubectl != nil && deployConfig.Kubectl.Manifests == nil {
260-
return errors.Errorf("deployments[%s].kubectl.manifests is required", index)
259+
if deployConfig.Kubectl != nil && deployConfig.Kubectl.Manifests == nil && deployConfig.Kubectl.InlineManifest == "" {
260+
return errors.Errorf("deployments[%s].kubectl.manifests or deployments[%s].kubectl.InlineManifest is required", index, index)
261+
}
262+
if deployConfig.Kubectl != nil && deployConfig.Kubectl.Manifests != nil && deployConfig.Kubectl.InlineManifest != "" {
263+
return errors.Errorf("deployments[%s].kubectl.manifests and deployments[%s].kubectl.inlineManifest cannot be used together", index, index)
261264
}
262265
if deployConfig.Kubectl != nil && deployConfig.Helm != nil {
263266
return errors.Errorf("deployments[%s].kubectl and deployments[%s].helm cannot be used together", index, index)

0 commit comments

Comments
 (0)