forked from plumber-cd/terraform-backend-git
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
157 lines (127 loc) · 4.73 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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package main
import (
"fmt"
"log"
"os"
"os/exec"
"strings"
"github.com/mitchellh/go-homedir"
"github.com/plumber-cd/terraform-backend-git/backend"
"github.com/plumber-cd/terraform-backend-git/server"
"github.com/plumber-cd/terraform-backend-git/storages/git"
"github.com/plumber-cd/terraform-backend-git/types"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
// Version holds the version binary built with - must be injected from build process via -ldflags="-X 'main.Version=vX.Y.Z'"
var Version = "development"
var cfgFile string
// rootCmd main command that just starts the server and keeps listening on port until terminated
var rootCmd = &cobra.Command{
Use: "terraform-backend-git",
Short: "Terraform HTTP backend implementation that uses Git as storage",
// will use known storage types in this repository and start a local HTTP server
Run: func(cmd *cobra.Command, args []string) {
if err := lockPidFile(); err != nil {
log.Fatal(err)
}
server.Start()
},
}
// versionCmd will print the version
var versionCmd = &cobra.Command{
Use: "version",
Short: "Print version",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(Version)
},
}
// stopCmd will stop the server started via rootCmd via it's pid file
var stopCmd = &cobra.Command{
Use: "stop",
Short: "Stop the currently running backend",
Run: func(cmd *cobra.Command, args []string) {
if err := stopPidFile(); err != nil {
log.Fatal(err)
}
},
}
// backendsCmds is a list of backend types available via cmd wrapper
var backendsCmds = []*cobra.Command{
gitBackendCmd,
}
// wrappersCmds is a list of wrapper commands available to run wrapped into a backend wrapper
// i.e. backand wrapper "git" will start an http backend in Git storage mode
// and "terraform" wrapper started from it will use terraform while that backend is running
var wrappersCmds = []*cobra.Command{
terraformWrapperCmd,
}
func initConfig() {
viper.SetConfigType("hcl")
viper.SetConfigName("terraform-backend-git")
if cfgFile != "" {
viper.SetConfigFile(cfgFile)
} else {
home, err := homedir.Dir()
if err != nil {
log.Fatal(err)
}
viper.AddConfigPath(home)
cwd, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
viper.AddConfigPath(cwd)
}
viper.AutomaticEnv()
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
viper.SetEnvPrefix("TF_BACKEND_GIT")
if err := viper.ReadInConfig(); err == nil {
log.Println("Using config file:", viper.ConfigFileUsed())
}
}
func main() {
backend.KnownStorageTypes = map[string]types.StorageClient{
"git": git.NewStorageClient(),
}
// keep the output clean as in wrapper mode it'll mess out with Terraform own output
log.SetFlags(0)
log.SetPrefix("[terraform-backend-git]: ")
cobra.OnInitialize(initConfig)
rootCmd.AddCommand(versionCmd)
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file (default is terraform-backend-git.hcl)")
rootCmd.PersistentFlags().StringP("address", "a", "127.0.0.1:6061", "Specify the listen address")
viper.BindPFlag("address", rootCmd.PersistentFlags().Lookup("address"))
viper.SetDefault("address", "127.0.0.1:6061")
rootCmd.PersistentFlags().BoolP("access-logs", "l", false, "Log HTTP requests to the console")
viper.BindPFlag("accessLogs", rootCmd.PersistentFlags().Lookup("access-logs"))
viper.SetDefault("accessLogs", false)
rootCmd.AddCommand(stopCmd)
gitBackendCmd.PersistentFlags().StringP("repository", "r", "", "Repository to use as storage")
viper.BindPFlag("git.repository", gitBackendCmd.PersistentFlags().Lookup("repository"))
gitBackendCmd.PersistentFlags().StringP("ref", "b", "master", "Ref (branch) to use")
viper.BindPFlag("git.ref", gitBackendCmd.PersistentFlags().Lookup("ref"))
viper.SetDefault("git.ref", "master")
gitBackendCmd.PersistentFlags().StringP("state", "s", "", "Ref (branch) to use")
viper.BindPFlag("git.state", gitBackendCmd.PersistentFlags().Lookup("state"))
terraformWrapperCmd.Flags().StringP("tf", "t", "terraform", "Path to terraform binary")
viper.BindPFlag("wrapper.tf.bin", terraformWrapperCmd.Flags().Lookup("tf"))
viper.SetDefault("wrapper.tf.bin", "terraform")
// for every backend type CMD add a wrapper CMD behind
for _, backendCmd := range backendsCmds {
for _, wrapperCmd := range wrappersCmds {
wrapperCmd.Flags().SetInterspersed(false)
backendCmd.AddCommand(wrapperCmd)
}
rootCmd.AddCommand(backendCmd)
}
if err := rootCmd.Execute(); err != nil {
// If the error was coming from a wrapper, must respect it's exit code
exitErr, ok := err.(*exec.ExitError)
if ok {
os.Exit(exitErr.ExitCode())
}
fmt.Println(err)
os.Exit(1)
}
}