Skip to content

Commit 328b4e1

Browse files
committed
Implement kubectl deployment method
1 parent 6d3f3eb commit 328b4e1

3 files changed

Lines changed: 165 additions & 34 deletions

File tree

cmd/up.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,14 +344,14 @@ func (cmd *UpCmd) buildAndDeploy() {
344344
var deployClient deploy.Interface
345345

346346
if deployConfig.Kubectl != nil {
347-
log.StartWait("Deploying " + *deployConfig.Name + " with kubectl")
347+
log.Info("Deploying " + *deployConfig.Name + " with kubectl")
348348

349349
deployClient, err = deployKubectl.New(cmd.kubectl, deployConfig, log.GetInstance())
350350
if err != nil {
351351
log.Fatalf("Error deploying devspace: deployment %s error: %v", *deployConfig.Name, err)
352352
}
353353
} else if deployConfig.Helm != nil {
354-
log.StartWait("Deploying " + *deployConfig.Name + " with helm")
354+
log.Info("Deploying " + *deployConfig.Name + " with helm")
355355

356356
deployClient, err = deployHelm.New(cmd.kubectl, deployConfig, log.GetInstance())
357357
if err != nil {
@@ -366,7 +366,6 @@ func (cmd *UpCmd) buildAndDeploy() {
366366
log.Fatalf("Error deploying %s: %v", *deployConfig.Name, err)
367367
}
368368

369-
log.StopWait()
370369
log.Donef("Successfully deployed %s", *deployConfig.Name)
371370
}
372371

pkg/devspace/deploy/kubectl/kubectl.go

Lines changed: 74 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ package kubectl
22

33
import (
44
"errors"
5-
"path/filepath"
5+
"os/exec"
6+
"strings"
67

78
"k8s.io/client-go/kubernetes"
89

@@ -11,7 +12,6 @@ import (
1112

1213
"github.com/covexo/devspace/pkg/devspace/config/v1"
1314
"github.com/covexo/devspace/pkg/util/log"
14-
"github.com/covexo/devspace/pkg/util/yamlutil"
1515
)
1616

1717
// DeployConfig holds the necessary information for kubectl deployment
@@ -67,55 +67,98 @@ func New(kubectl *kubernetes.Clientset, deployConfig *v1.DeploymentConfig, log l
6767

6868
// Status prints the status of all matched manifests from kubernetes
6969
func (d *DeployConfig) Status() ([][]string, error) {
70-
return nil, nil
70+
// TODO: parse kubectl get output into the required string array
71+
return [][]string{}, nil
7172
}
7273

7374
// Delete deletes all matched manifests from kubernetes
7475
func (d *DeployConfig) Delete() error {
75-
return nil
76+
manifests, err := loadManifests(d.Manifests, d.Log)
77+
if err != nil {
78+
return err
79+
}
80+
81+
joinedManifests, err := joinManifests(manifests)
82+
if err != nil {
83+
return err
84+
}
85+
86+
stringReader := strings.NewReader(joinedManifests)
87+
args := d.getCmdArgs("delete", "--ignore-not-found=true")
88+
89+
cmd := exec.Command(d.CmdPath, args...)
90+
91+
cmd.Stdin = stringReader
92+
cmd.Stdout = d.Log
93+
cmd.Stderr = d.Log
94+
95+
return cmd.Run()
7696
}
7797

7898
// Deploy deploys all specified manifests via kubectl apply and adds to the specified image names the corresponding tags
7999
func (d *DeployConfig) Deploy(generatedConfig *generated.Config, forceDeploy bool) error {
80-
return nil
81-
}
100+
manifests, err := loadManifests(d.Manifests, d.Log)
101+
if err != nil {
102+
return err
103+
}
82104

83-
func (d *DeployConfig) internalDeploy(images []string, tags map[string]string) error {
84-
for _, pattern := range d.Manifests {
85-
files, err := filepath.Glob(pattern)
86-
if err != nil {
87-
return err
88-
}
105+
for _, manifest := range manifests {
106+
replaceManifest(manifest, generatedConfig.ImageTags)
107+
}
89108

90-
for _, file := range files {
91-
err = applyFile(d.Context, file, d.Namespace, images, tags)
92-
if err != nil {
93-
return err
94-
}
95-
}
109+
joinedManifests, err := joinManifests(manifests)
110+
if err != nil {
111+
return err
96112
}
97113

98-
return nil
114+
stringReader := strings.NewReader(joinedManifests)
115+
args := d.getCmdArgs("apply", "--force")
116+
117+
cmd := exec.Command(d.CmdPath, args...)
118+
119+
cmd.Stdin = stringReader
120+
cmd.Stdout = d.Log
121+
cmd.Stderr = d.Log
122+
123+
return cmd.Run()
99124
}
100125

101-
func applyFile(context, file, namespace string, images []string, tags map[string]string) error {
102-
y := make(map[interface{}]interface{})
103-
yamlutil.ReadYamlFromFile(file, y)
126+
func (d *DeployConfig) getCmdArgs(method string, additionalArgs ...string) []string {
127+
args := []string{}
104128

129+
if d.Namespace != "" {
130+
args = append(args, "-n", d.Namespace)
131+
}
132+
133+
if d.Context != "" {
134+
args = append(args, "--context", d.Context)
135+
}
136+
137+
args = append(args, method)
138+
139+
if additionalArgs != nil {
140+
args = append(args, additionalArgs...)
141+
}
142+
143+
args = append(args, "-f", "-")
144+
145+
return args
146+
}
147+
148+
func replaceManifest(manifest Manifest, tags map[string]string) {
105149
match := func(key, value string) bool {
150+
if key == "image" {
151+
if _, ok := tags[value]; ok {
152+
return true
153+
}
154+
}
155+
106156
return false
107157
}
108158

109159
replace := func(value string) string {
110-
return ""
160+
return value + ":" + tags[value]
111161
}
112162

113-
Walk(y, match, replace)
114-
115-
//changedManifest, err := yaml.Marshal(y)
116-
//if err != nil {
117-
// return err
118-
//}
119-
120-
return nil
163+
Walk(manifest, match, replace)
121164
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package kubectl
2+
3+
import (
4+
"io/ioutil"
5+
"path/filepath"
6+
"strings"
7+
8+
"github.com/covexo/devspace/pkg/util/log"
9+
10+
yaml "gopkg.in/yaml.v2"
11+
)
12+
13+
// Manifest is the type that holds the data of a single kubernetes manifest
14+
type Manifest map[interface{}]interface{}
15+
16+
func joinManifests(manifests []Manifest) (string, error) {
17+
retString := ""
18+
19+
for _, manifest := range manifests {
20+
out, err := yaml.Marshal(manifest)
21+
if err != nil {
22+
return "", nil
23+
}
24+
25+
if retString != "" {
26+
retString += "\n---\n"
27+
}
28+
29+
retString += string(out)
30+
}
31+
32+
return retString, nil
33+
}
34+
35+
func loadManifests(globPatterns []string, log log.Logger) ([]Manifest, error) {
36+
manifests := []Manifest{}
37+
38+
for _, pattern := range globPatterns {
39+
files, err := filepath.Glob(pattern)
40+
if err != nil {
41+
return nil, err
42+
}
43+
44+
for _, file := range files {
45+
if isValidFile(file) {
46+
loadedManifests, err := getManifestsFromFile(file)
47+
if err != nil {
48+
return nil, err
49+
}
50+
51+
manifests = append(manifests, loadedManifests...)
52+
} else {
53+
log.Warnf("Manifest %s skipped because it does not have a valid ending (.yml or .yaml expected)", file)
54+
}
55+
}
56+
}
57+
58+
return manifests, nil
59+
}
60+
61+
func isValidFile(filepath string) bool {
62+
return strings.HasSuffix(filepath, ".yml") || strings.HasSuffix(filepath, ".yaml")
63+
}
64+
65+
func getManifestsFromFile(filepath string) ([]Manifest, error) {
66+
data, err := ioutil.ReadFile(filepath)
67+
if err != nil {
68+
return nil, err
69+
}
70+
71+
retManifests := []Manifest{}
72+
manifests := strings.Split(string(data), "\n---")
73+
74+
for _, manifest := range manifests {
75+
manifest = strings.TrimLeft(manifest, "\r\n")
76+
manifest = strings.TrimRight(manifest, "\r\n")
77+
78+
manifestData := Manifest{}
79+
80+
err = yaml.Unmarshal([]byte(manifest), manifestData)
81+
if err != nil {
82+
return nil, err
83+
}
84+
85+
retManifests = append(retManifests, manifestData)
86+
}
87+
88+
return retManifests, nil
89+
}

0 commit comments

Comments
 (0)