-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
127 lines (109 loc) · 2.66 KB
/
main.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
package main
import (
"context"
"fmt"
"log"
"os"
"sync"
"github.com/digitalocean/godo"
"github.com/evan-forbes/devnet/config"
"github.com/spf13/cobra"
)
func main() {
rootCmd := cobra.Command{
Use: "devnet",
Aliases: []string{"devnet"},
}
rootCmd.AddCommand(
InitCmd(),
)
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
func InitCmd() *cobra.Command {
return &cobra.Command{
Use: "init",
Aliases: []string{"init", "i"},
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
// get the digital ocean token from the env vars
doat := os.Getenv("DIGITALOCEAN_ACCESS_TOKEN")
// create the digital ocean client
client := godo.NewFromToken(doat)
// load the config from the working dir
conf, err := config.LoadConfig(args[0])
if err != nil {
return err
}
// connect each existing do droplet to the configered ones
conf, err = conf.Match(context.TODO(), client)
if err != nil {
return err
}
// fetch the ssh password if any
sshPass := os.Getenv("SSH_PASS")
switch sshPass {
case "nil":
sshPass = ""
case "":
fmt.Println(
"password to ssh key (press enter for no password or alternatively export as SSH_PASS). export as 'nil' to ignore future requests",
)
fmt.Scanf(
"%s",
&sshPass,
)
default:
}
// establish ssh connections to each droplet
manager, err := NewSSHManager(conf.Droplets, sshPass)
if err != nil {
return err
}
defer manager.CloseAll()
// save a json representation of the public IPs to each payload dir
err = conf.WriteIPsJson()
if err != nil {
return err
}
// save a bash script to export all public IPs as env vars
err = conf.WriteIPsBash()
if err != nil {
return err
}
// async deliver the payloads via scp
var wg sync.WaitGroup
for name, conn := range manager.Conns {
wg.Add(1)
go func(n string, c Connection) {
defer wg.Done()
err = c.DeliverPayload()
if err != nil {
fmt.Println(err)
}
fmt.Println("delivered payload for: name", n)
}(name, conn)
}
wg.Wait()
// run initial commands and forward their Stdouts and Stderrs to a local file
for name, conn := range manager.Conns {
wg.Add(1)
go func(n string, c Connection) {
defer wg.Done()
for _, command := range c.drop.InitCommands {
err = c.Run(command)
if err != nil {
log.Println(fmt.Errorf("failure to run command %s on %s: %w", command, n, err))
continue
}
fmt.Printf("ran command %s on %s\n", command, n)
}
}(name, conn)
}
wg.Wait()
return nil
},
}
}