/
argocd.go
139 lines (126 loc) · 3.68 KB
/
argocd.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package magekubernetes
import (
"fmt"
"os"
"strings"
"github.com/magefile/mage/sh"
"gopkg.in/yaml.v3"
)
// ArgoCDAppHelm contains the info for rendering a helm file
type ArgoCDAppHelm struct {
ReleaseName string `yaml:"releaseName"`
ValueFiles []string `yaml:"valueFiles"`
}
// ArgoCDAppSource contains the info where to find the source for rendering
type ArgoCDAppSource struct {
Helm ArgoCDAppHelm `yaml:"helm"`
Path string `yaml:"path"`
RepoRUL string `yaml:"repoURL"`
}
// ArgoCDAppSpec contains the app source
type ArgoCDAppSpec struct {
Source ArgoCDAppSource `yaml:"source"`
Sources []ArgoCDAppSource `yaml:"sources"`
}
// ArgoCDAppMetadata contains the app name
type ArgoCDAppMetadata struct {
Name string `yaml:"name"`
}
// ArgoCDApp contains the spec and metadata of an app
type ArgoCDApp struct {
Spec ArgoCDAppSpec `yaml:"spec"`
Metadata ArgoCDAppMetadata `yaml:"metadata"`
}
func getArgoCDDeployments(repoURL string) ([]ArgoCDApp, error) {
var argoCDAppList []ArgoCDApp
cmdOptions := []string{
"--grpc-web",
"app",
"list",
"-r", repoURL,
"-l", "component!=pallet-config", // use label selector to quickly exclude pallet apps
"-o", "yaml",
}
authOptions, err := getArgoCDAuth()
if err != nil {
return nil, err
}
appYaml, err := sh.Output("argocd", append(cmdOptions, authOptions...)...)
if err != nil {
return nil, err
}
err = yaml.Unmarshal([]byte(appYaml), &argoCDAppList)
if err != nil {
return nil, err
}
return argoCDAppList, nil
}
func getArgoCDDiff(apps []ArgoCDApp) error {
env := map[string]string{"KUBECTL_EXTERNAL_DIFF": "dyff between --omit-header"}
authOptions, err := getArgoCDAuth()
if err != nil {
return err
}
for _, app := range apps {
cmdOptions := []string{
"--loglevel", "error",
"--grpc-web",
"app",
"diff",
app.Metadata.Name,
"--refresh",
"--local", app.Spec.Source.Path,
}
diff, err := sh.OutputWith(env, "argocd", append(cmdOptions, authOptions...)...)
if sh.ExitStatus(err) == 2 {
return err
}
fmt.Println("---- Diff of " + app.Metadata.Name + " ----")
fmt.Println(diff)
}
return nil
}
func getArgoCDAuth() ([]string, error) {
authOptions := []string{}
if token, ok := os.LookupEnv("ARGOCD_API_TOKEN"); ok {
server, ok := os.LookupEnv("ARGOCD_SERVER")
if !ok {
return nil, fmt.Errorf("When using ARGOCD_API_TOKEN, you are also required to set ARGOCD_SERVER")
}
authOptions = append(authOptions, "--auth-token", token, "--server", server)
} else {
err := sh.Run("argocd", "context")
if err != nil {
fmt.Println("Make use '$HOME/.argocd' is mounted to /root/.config/ or use ARGOCD_API_TOKEN and ARGOCD_SERVER environment variable")
return nil, err
}
}
return authOptions, nil
}
func listArgoCDDeployments() error {
repo, err := repoURL()
if err != nil {
return err
}
apps, err := getArgoCDDeployments(repo)
if err != nil {
return err
}
for _, trackedDeployment := range apps {
if trackedDeployment.Spec.Source.Helm.ReleaseName != "" {
fmt.Println("---")
fmt.Println("Found helm deployment with name: " + trackedDeployment.Metadata.Name)
fmt.Println(" path: " + trackedDeployment.Spec.Source.Path)
fmt.Println(" valueFiles: " + strings.Join(trackedDeployment.Spec.Source.Helm.ValueFiles, ", "))
} else if isKustomizeDir(trackedDeployment.Spec.Source.Path) {
fmt.Println("---")
fmt.Println("Found kustomize deployment with name: " + trackedDeployment.Metadata.Name)
fmt.Println(" path: " + trackedDeployment.Spec.Source.Path)
} else {
fmt.Println("---")
fmt.Println("Found plain deployment with name: " + trackedDeployment.Metadata.Name)
fmt.Println(" path: " + trackedDeployment.Spec.Source.Path)
}
}
return nil
}