|
1 | 1 | package cmd |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "context" |
5 | 4 | "fmt" |
6 | | - "io" |
7 | | - "io/ioutil" |
8 | 5 | "log" |
9 | | - "math/rand" |
10 | | - "net/http" |
11 | | - "os" |
12 | | - "time" |
13 | 6 |
|
14 | | - "github.com/Optum/dce-cli/internal/terra" |
15 | | - "github.com/shurcooL/githubv4" |
| 7 | + "github.com/Optum/dce-cli/internal/deploy" |
16 | 8 | "github.com/spf13/cobra" |
17 | | - "golang.org/x/oauth2" |
18 | | - |
19 | | - "github.com/mholt/archiver" |
20 | 9 | ) |
21 | 10 |
|
22 | 11 | var deployNamespace string |
@@ -55,172 +44,17 @@ var systemDeployCmd = &cobra.Command{ |
55 | 44 | Run: func(cmd *cobra.Command, args []string) { |
56 | 45 |
|
57 | 46 | log.Println("Creating terraform remote state backend infrastructure") |
58 | | - stateBucket := createRemoteStateBackend() |
| 47 | + stateBucket := deploy.CreateRemoteStateBackend(deployNamespace) |
59 | 48 |
|
60 | 49 | log.Println("Creating DCE infrastructure") |
61 | | - artifactsBucket := createDceInfra(stateBucket) |
| 50 | + artifactsBucket := deploy.CreateDceInfra(deployNamespace, stateBucket) |
62 | 51 | log.Println("Artifacts bucket = ", artifactsBucket) |
63 | 52 |
|
64 | 53 | // Deploy code assets to DCE infra |
| 54 | + deploy.DeployCodeAssets(deployNamespace, artifactsBucket) |
65 | 55 | }, |
66 | 56 | } |
67 | 57 |
|
68 | | -func createDceInfra(stateBucket string) string { |
69 | | - workingDir, originDir := mvToTempDir("dce-") |
70 | | - defer os.RemoveAll(workingDir) |
71 | | - defer os.Chdir(originDir) |
72 | | - |
73 | | - log.Println("Downloading DCE terraform modules") |
74 | | - artifactsFileName := "terraform_artifacts.zip" |
75 | | - downloadGithubReleaseAsset(artifactsFileName) |
76 | | - |
77 | | - // TODO: |
78 | | - // Protect against zip-slip vulnerability? https://snyk.io/research/zip-slip-vulnerability |
79 | | - // |
80 | | - // err := z.Walk("/Users/matt/Desktop/test.zip", func(f archiver.File) error { |
81 | | - // zfh, ok := f.Header.(zip.FileHeader) |
82 | | - // if ok { |
83 | | - // fmt.Println("Filename:", zfh.Name) |
84 | | - // } |
85 | | - // return nil |
86 | | - // }) |
87 | | - |
88 | | - err := archiver.Unarchive(artifactsFileName, ".") |
89 | | - if err != nil { |
90 | | - log.Fatalf("error: %v", err) |
91 | | - } |
92 | | - |
93 | | - os.Remove(artifactsFileName) |
94 | | - files, err := ioutil.ReadDir("./") |
95 | | - if len(files) != 1 || !files[0].IsDir() { |
96 | | - log.Fatalf("Unexpected content in DCE assets archive") |
97 | | - } |
98 | | - os.Chdir(files[0].Name()) |
99 | | - |
100 | | - log.Println("Initializing terraform working directory") |
101 | | - terra.Init([]string{"-backend-config=bucket=" + stateBucket, "-backend-config=key=local-tf-state"}) |
102 | | - |
103 | | - log.Println("Applying DCE infrastructure") |
104 | | - var namesSpace string |
105 | | - if deployNamespace != "" { |
106 | | - namesSpace = deployNamespace |
107 | | - } else { |
108 | | - namesSpace = "dce-" + getRandString(6) |
109 | | - } |
110 | | - terra.Apply(namesSpace) |
111 | | - |
112 | | - log.Println("Retrieving artifacts bucket name from terraform outputs") |
113 | | - artifactsBucket := terra.GetOutput("artifacts_bucket_name") |
114 | | - log.Println(" -->", artifactsBucket) |
115 | | - |
116 | | - return artifactsBucket |
117 | | -} |
118 | | - |
119 | | -func downloadGithubReleaseAsset(assetName string) { |
120 | | - src := oauth2.StaticTokenSource( |
121 | | - &oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")}, |
122 | | - ) |
123 | | - oauthHTTPClient := oauth2.NewClient(context.Background(), src) |
124 | | - |
125 | | - var query struct { |
126 | | - Viewer struct { |
127 | | - Login githubv4.String |
128 | | - CreatedAt githubv4.DateTime |
129 | | - } |
130 | | - Repository struct { |
131 | | - Releases struct { |
132 | | - Nodes []struct { |
133 | | - TagName githubv4.String |
134 | | - ReleaseAssets struct { |
135 | | - Nodes []struct { |
136 | | - ID githubv4.String |
137 | | - DownloadURL githubv4.String |
138 | | - URL string |
139 | | - } |
140 | | - } `graphql:"releaseAssets(last: 1, name: \"terraform_artifacts.zip\")"` |
141 | | - } |
142 | | - } `graphql:"releases(last: 1)"` |
143 | | - } `graphql:"repository(owner: \"Optum\", name: \"Redbox\")"` |
144 | | - } |
145 | | - |
146 | | - ghClient := githubv4.NewClient(oauthHTTPClient) |
147 | | - err := ghClient.Query(context.Background(), &query, nil) |
148 | | - if err != nil { |
149 | | - log.Fatalf("error: %v", err) |
150 | | - } |
151 | | - fmt.Println(" Query Response:", query.Repository.Releases.Nodes[0].ReleaseAssets.Nodes[0].URL) |
152 | | - |
153 | | - req, err := http.NewRequest("GET", query.Repository.Releases.Nodes[0].ReleaseAssets.Nodes[0].URL, nil) |
154 | | - resp, err := http.DefaultClient.Do(req) |
155 | | - if err != nil { |
156 | | - log.Fatalf("error: %v", err) |
157 | | - } |
158 | | - defer resp.Body.Close() |
159 | | - |
160 | | - out, err := os.Create(assetName) |
161 | | - if err != nil { |
162 | | - log.Fatalf("error: %v", err) |
163 | | - } |
164 | | - defer out.Close() |
165 | | - _, err = io.Copy(out, resp.Body) |
166 | | - if err != nil { |
167 | | - log.Fatalf("error: %v", err) |
168 | | - } |
169 | | -} |
170 | | - |
171 | | -func createRemoteStateBackend() string { |
172 | | - workingDir, originDir := mvToTempDir("dce-init-") |
173 | | - defer os.RemoveAll(workingDir) |
174 | | - defer os.Chdir(originDir) |
175 | | - |
176 | | - log.Println("Creating terraform remote backend template (init.tf)") |
177 | | - fileName := workingDir + "/" + "init.tf" |
178 | | - err := ioutil.WriteFile(fileName, []byte(terra.RemoteBackend), 0644) |
179 | | - if err != nil { |
180 | | - log.Fatalf("error: %v", err) |
181 | | - } |
182 | | - |
183 | | - log.Println("Initializing terraform working directory and building remote state infrastructure") |
184 | | - terra.Init([]string{}) |
185 | | - if deployNamespace != "" { |
186 | | - terra.Apply(deployNamespace) |
187 | | - } else { |
188 | | - terra.Apply("dce-default-" + getRandString(8)) |
189 | | - } |
190 | | - |
191 | | - log.Println("Retrieving remote state bucket name from terraform outputs") |
192 | | - stateBucket := terra.GetOutput("bucket") |
193 | | - log.Println(" -->", stateBucket) |
194 | | - |
195 | | - return stateBucket |
196 | | -} |
197 | | - |
198 | | -func mvToTempDir(prefix string) (string, string) { |
199 | | - log.Println("Creating temporary terraform working directory") |
200 | | - destinationDir, err := ioutil.TempDir("", prefix) |
201 | | - if err != nil { |
202 | | - log.Fatalln(err) |
203 | | - } |
204 | | - log.Println(" -->" + destinationDir) |
205 | | - originDir, err := os.Getwd() |
206 | | - if err != nil { |
207 | | - log.Fatalln(err) |
208 | | - } |
209 | | - os.Chdir(destinationDir) |
210 | | - return destinationDir, originDir |
211 | | -} |
212 | | - |
213 | | -// https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-go |
214 | | -func getRandString(n int) string { |
215 | | - rand.Seed(time.Now().UnixNano()) |
216 | | - const letterBytes = "abcdefghijklmnopqrstuvwxyz0123456789" |
217 | | - b := make([]byte, n) |
218 | | - for i := range b { |
219 | | - b[i] = letterBytes[rand.Int63()%int64(len(letterBytes))] |
220 | | - } |
221 | | - return string(b) |
222 | | -} |
223 | | - |
224 | 58 | /* |
225 | 59 | Logs Namespace |
226 | 60 | */ |
|
0 commit comments