Skip to content
This repository was archived by the owner on Jan 21, 2020. It is now read-only.

Commit 251ff68

Browse files
author
David Chung
authored
CLI extensions - playbooks (#468)
Signed-off-by: David Chung <[email protected]>
1 parent c88ca75 commit 251ff68

File tree

20 files changed

+541
-53
lines changed

20 files changed

+541
-53
lines changed

cmd/cli/main/main.go

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import (
77
"os"
88

99
"github.com/docker/infrakit/cmd/cli/base"
10+
"github.com/docker/infrakit/cmd/cli/playbook"
1011
"github.com/docker/infrakit/pkg/cli"
1112
cli_local "github.com/docker/infrakit/pkg/cli/local"
13+
cli_remote "github.com/docker/infrakit/pkg/cli/remote"
1214
"github.com/docker/infrakit/pkg/discovery"
1315
discovery_local "github.com/docker/infrakit/pkg/discovery/local"
1416
"github.com/docker/infrakit/pkg/discovery/remote"
@@ -94,18 +96,37 @@ func main() {
9496
cmd.AddCommand(c)
9597
})
9698

99+
mods := []*cobra.Command{}
97100
// additional modules
98-
modules, err := cli_local.NewModules(cli_local.Dir())
99-
if err != nil {
100-
log.Crit("error executing", "err", err)
101-
os.Exit(1)
101+
if os.Getenv(cli.CliDirEnvVar) != "" {
102+
modules, err := cli_local.NewModules(cli_local.Dir())
103+
if err != nil {
104+
log.Crit("error executing", "err", err)
105+
os.Exit(1)
106+
}
107+
localModules, err := modules.List()
108+
log.Debug("modules", "local", localModules)
109+
if err != nil {
110+
log.Crit("error executing", "err", err)
111+
os.Exit(1)
112+
}
113+
mods = append(mods, localModules...)
102114
}
103115

104-
mods, err := modules.List()
105-
log.Debug("modules", "mods", mods)
116+
// any remote modules?
117+
pmod, err := playbook.Load()
106118
if err != nil {
107-
log.Crit("error executing", "err", err)
108-
os.Exit(1)
119+
log.Warn("playbooks failed to load", "err", err)
120+
} else {
121+
if playbooks, err := cli_remote.NewModules(pmod, os.Stdin); err != nil {
122+
log.Warn("error loading playbooks", "err", err)
123+
} else {
124+
if more, err := playbooks.List(); err != nil {
125+
log.Warn("cannot list playbooks", "err", err)
126+
} else {
127+
mods = append(mods, more...)
128+
}
129+
}
109130
}
110131

111132
for _, mod := range mods {

cmd/cli/playbook/playbook.go

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
package playbook
2+
3+
import (
4+
"fmt"
5+
"io/ioutil"
6+
"os"
7+
"os/user"
8+
"path/filepath"
9+
10+
"github.com/docker/infrakit/cmd/cli/base"
11+
"github.com/docker/infrakit/pkg/cli/remote"
12+
"github.com/docker/infrakit/pkg/discovery"
13+
logutil "github.com/docker/infrakit/pkg/log"
14+
"github.com/docker/infrakit/pkg/template"
15+
"github.com/spf13/cobra"
16+
)
17+
18+
var log = logutil.New("module", "cli/playbook")
19+
20+
const (
21+
// PlaybooksFileEnvVar is the location of the playbooks file
22+
PlaybooksFileEnvVar = "INFRAKIT_PLAYBOOKS_FILE"
23+
)
24+
25+
func init() {
26+
base.Register(Command)
27+
}
28+
29+
func getHome() string {
30+
if usr, err := user.Current(); err == nil {
31+
return usr.HomeDir
32+
}
33+
return os.Getenv("HOME")
34+
}
35+
36+
func defaultPlaybooksFile() string {
37+
if playbooksFile := os.Getenv(PlaybooksFileEnvVar); playbooksFile != "" {
38+
return playbooksFile
39+
}
40+
return filepath.Join(getHome(), ".infrakit/playbooks")
41+
}
42+
43+
// Load loads the playbook
44+
func Load() (remote.Modules, error) {
45+
return loadPlaybooks()
46+
}
47+
48+
func loadPlaybooks() (remote.Modules, error) {
49+
modules := remote.Modules{}
50+
buff, err := ioutil.ReadFile(defaultPlaybooksFile())
51+
if err != nil {
52+
if !os.IsExist(err) {
53+
return modules, nil
54+
}
55+
return nil, err
56+
}
57+
58+
if len(buff) > 0 {
59+
err = remote.Decode(buff, &modules)
60+
}
61+
return modules, err
62+
}
63+
64+
// Command is the entrypoint
65+
func Command(plugins func() discovery.Plugins) *cobra.Command {
66+
67+
///////////////////////////////////////////////////////////////////////////////////
68+
// playbook
69+
cmd := &cobra.Command{
70+
Use: "playbook",
71+
Short: "Manage playbooks",
72+
}
73+
quiet := cmd.PersistentFlags().BoolP("quiet", "q", false, "Print rows without column headers")
74+
75+
add := &cobra.Command{
76+
Use: "add <name> <url>",
77+
Short: "Add a playbook",
78+
RunE: func(cmd *cobra.Command, args []string) error {
79+
80+
if len(args) != 2 {
81+
cmd.Usage()
82+
os.Exit(1)
83+
}
84+
85+
name := args[0]
86+
url := args[1]
87+
88+
modules, err := loadPlaybooks()
89+
if err != nil {
90+
return err
91+
}
92+
93+
// try fetch
94+
test, err := template.NewTemplate(url, template.Options{})
95+
if err != nil {
96+
return err
97+
}
98+
99+
_, err = test.Render(nil)
100+
if err != nil {
101+
return err
102+
}
103+
104+
if _, has := modules[remote.Op(name)]; has {
105+
return fmt.Errorf("%s already exists", name)
106+
}
107+
108+
modules[remote.Op(name)] = remote.SourceURL(url)
109+
110+
encoded, err := remote.Encode(modules)
111+
if err != nil {
112+
return err
113+
}
114+
115+
return ioutil.WriteFile(defaultPlaybooksFile(), encoded, 0755)
116+
},
117+
}
118+
remove := &cobra.Command{
119+
Use: "rm <name>",
120+
Short: "Remove a playbook",
121+
RunE: func(cmd *cobra.Command, args []string) error {
122+
123+
if len(args) != 1 {
124+
cmd.Usage()
125+
os.Exit(1)
126+
}
127+
128+
name := args[0]
129+
130+
modules, err := loadPlaybooks()
131+
if err != nil {
132+
return err
133+
}
134+
135+
if _, has := modules[remote.Op(name)]; !has {
136+
return fmt.Errorf("%s does not exists", name)
137+
}
138+
139+
delete(modules, remote.Op(name))
140+
141+
encoded, err := remote.Encode(modules)
142+
if err != nil {
143+
return err
144+
}
145+
146+
return ioutil.WriteFile(defaultPlaybooksFile(), encoded, 0755)
147+
},
148+
}
149+
150+
rawOutputFlags, rawOutput := base.RawOutput()
151+
list := &cobra.Command{
152+
Use: "ls",
153+
Short: "List playbooks",
154+
RunE: func(cmd *cobra.Command, args []string) error {
155+
156+
if len(args) != 0 {
157+
cmd.Usage()
158+
os.Exit(1)
159+
}
160+
161+
modules, err := loadPlaybooks()
162+
if err != nil {
163+
fmt.Println("***")
164+
return err
165+
}
166+
rendered, err := rawOutput(os.Stdout, modules)
167+
if err != nil {
168+
return err
169+
}
170+
if rendered {
171+
return nil
172+
}
173+
174+
if !*quiet {
175+
fmt.Printf("%-30s\t%-30s\n", "PLAYBOOK", "URL")
176+
}
177+
178+
for op, url := range modules {
179+
fmt.Printf("%-30v\t%-30v\n", op, url)
180+
}
181+
return nil
182+
},
183+
}
184+
list.Flags().AddFlagSet(rawOutputFlags)
185+
186+
cmd.AddCommand(add, remove, list)
187+
188+
return cmd
189+
}

cmd/cli/template/template.go

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import (
44
"fmt"
55
"io/ioutil"
66
"os"
7+
"strings"
78

89
"github.com/docker/infrakit/cmd/cli/base"
910
"github.com/docker/infrakit/pkg/discovery"
1011
logutil "github.com/docker/infrakit/pkg/log"
12+
"github.com/ghodss/yaml"
1113
"github.com/spf13/cobra"
1214
)
1315

@@ -46,12 +48,49 @@ func Command(plugins func() discovery.Plugins) *cobra.Command {
4648
if err != nil {
4749
return err
4850
}
51+
4952
fmt.Print(view)
5053
return nil
51-
5254
},
5355
}
5456
cmd.Flags().AddFlagSet(tflags)
5557

58+
format := &cobra.Command{
59+
Use: "format json|yaml",
60+
Short: "Converts stdin to different format",
61+
RunE: func(cmd *cobra.Command, args []string) error {
62+
63+
if len(args) != 1 {
64+
cmd.Usage()
65+
os.Exit(1)
66+
}
67+
68+
in, err := ioutil.ReadAll(os.Stdin)
69+
if err != nil {
70+
return err
71+
}
72+
73+
buff := []byte(in)
74+
switch strings.ToLower(args[0]) {
75+
76+
case "json":
77+
buff, err = yaml.YAMLToJSON(buff)
78+
case "yaml":
79+
buff, err = yaml.JSONToYAML(buff)
80+
default:
81+
err = fmt.Errorf("unknown format %s", args[0])
82+
}
83+
84+
if err != nil {
85+
return err
86+
}
87+
88+
fmt.Print(string(buff))
89+
return nil
90+
91+
},
92+
}
93+
cmd.AddCommand(format)
94+
5695
return cmd
5796
}

cmd/cli/util/util.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func muxCommand(plugins func() discovery.Plugins) *cobra.Command {
2222
Short: "API mux service",
2323
}
2424

25-
listen := cmd.Flags().StringP("listen", "l", ":8080", "Listening port")
25+
listen := cmd.Flags().StringP("listen", "l", ":4358", "Listening port")
2626
autoStop := cmd.Flags().BoolP("auto-stop", "a", false, "True to stop when no plugins are running")
2727
interval := cmd.Flags().DurationP("scan", "s", 1*time.Minute, "Scan interval to check for plugins")
2828

examples/cli/gcp/start-plugin.ikc

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,24 @@
22

33
{{/* =% sh %= */}}
44

5-
{{ $useDocker := flag "docker" "bool" ">0 use docker container" | prompt "Run as Docker container?" "bool" }}
6-
5+
{{ $defaultCred := cat (env "HOME") "/.config/gcloud/application_default_credentials.json" | nospace }}
6+
{{ $useDocker := flag "docker" "bool" ">0 use docker container" | prompt "Run as Docker container?" "bool" "yes" }}
7+
{{ $credentials := flag "credential-path" "string" "Path to credentials.json" | prompt "Credentials JSON path?" "string" $defaultCred }}
78
{{ $zone := flag "zone" "string" "GCP zone" | prompt "What's the zone?" "string" }}
89
{{ $project := flag "project" "string" "Project name" | prompt "What's the name of the project?" "string" }}
910

1011
{{ $instanceImage := "infrakit/gcp:dev" }}
1112

1213
{{ $infrakit := (cat (env "HOME") "/.infrakit/" | nospace) }}
1314
{{ $dockerMounts := (cat "-v /var/run/docker.sock:/var/run/docker.sock -v" (cat $infrakit ":/infrakit/" | nospace)) }}
15+
{{ $gcpCredentials := (cat $credentials ":/infrakit/platforms/gcp/credentials.json" | nospace) }}
1416
{{ $dockerEnvs := "-e INFRAKIT_HOME=/infrakit -e INFRAKIT_PLUGINS_DIR=/infrakit/plugins" }}
1517

1618

1719
{{ if $useDocker }}
1820
# Starting docker container for instance plugin
19-
docker run -d --rm --name instance-plugin \
20-
{{$dockerMounts}} {{$dockerEnvs}} {{$instanceImage}} infrakit-instance-gcp \
21+
docker run -d --name instance-plugin \
22+
{{$dockerMounts}} {{$dockerEnvs}} -v {{$gcpCredentials}} {{$instanceImage}} infrakit-instance-gcp \
2123
--namespace-tags {{cat "infrakit.scope=" $project | nospace}} \
2224
--zone {{ $zone }} --log 5 --project {{ $project }}
2325

@@ -30,6 +32,6 @@ infrakit-instance-gcp \
3032
> {{env "INFRAKIT_HOME"}}/logs/instance-gcp.log 2>&1 &
3133

3234
echo "Tailing log"
33-
tail -f {{env "INFRAKIT_HOME"}}/logs/instance-gcp.log
35+
tail -f {{env "INFRAKIT_HOME"}}/logs/*.log
3436

3537
{{ end }}

0 commit comments

Comments
 (0)