added getting ENV vars from Vault
This commit is contained in:
		@@ -31,8 +31,10 @@ func init() {
 | 
				
			|||||||
func Backup(cmd *cobra.Command, args []string) {
 | 
					func Backup(cmd *cobra.Command, args []string) {
 | 
				
			||||||
	backyConfOpts := backy.NewOpts(cfgFile, backy.AddCommandLists(cmdLists))
 | 
						backyConfOpts := backy.NewOpts(cfgFile, backy.AddCommandLists(cmdLists))
 | 
				
			||||||
	backyConfOpts.InitConfig()
 | 
						backyConfOpts.InitConfig()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	config := backy.ReadConfig(backyConfOpts)
 | 
						config := backy.ReadConfig(backyConfOpts)
 | 
				
			||||||
	config.RunBackyConfig("")
 | 
					
 | 
				
			||||||
 | 
						config.RunBackyConfig("", backyConfOpts)
 | 
				
			||||||
	for _, host := range config.Hosts {
 | 
						for _, host := range config.Hosts {
 | 
				
			||||||
		if host.SshClient != nil {
 | 
							if host.SshClient != nil {
 | 
				
			||||||
			host.SshClient.Close()
 | 
								host.SshClient.Close()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,15 +16,20 @@ var (
 | 
				
			|||||||
		Run:   version,
 | 
							Run:   version,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	numOnly bool
 | 
						numOnly bool
 | 
				
			||||||
 | 
						vPre    bool
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func version(cmd *cobra.Command, args []string) {
 | 
					func version(cmd *cobra.Command, args []string) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmd.PersistentFlags().BoolVarP(&numOnly, "num", "n", true, "Output the version number only.")
 | 
						cmd.PersistentFlags().BoolVarP(&numOnly, "num", "n", true, "Output the version number only.")
 | 
				
			||||||
	if numOnly {
 | 
						cmd.PersistentFlags().BoolVarP(&vPre, "vpre", "V", false, "Output the version with v prefixed.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if numOnly && !vPre {
 | 
				
			||||||
		fmt.Printf("%s\n", versionStr)
 | 
							fmt.Printf("%s\n", versionStr)
 | 
				
			||||||
 | 
						} else if vPre {
 | 
				
			||||||
 | 
							fmt.Printf("v%s", versionStr)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		fmt.Printf("Version: %s", versionStr)
 | 
							fmt.Printf("Backy version: %s", versionStr)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	os.Exit(0)
 | 
						os.Exit(0)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								go.mod
									
									
									
									
									
								
							@@ -4,6 +4,7 @@ go 1.19
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
	github.com/go-co-op/gocron v1.18.0
 | 
						github.com/go-co-op/gocron v1.18.0
 | 
				
			||||||
 | 
						github.com/hashicorp/vault/api v1.9.0
 | 
				
			||||||
	github.com/joho/godotenv v1.4.0
 | 
						github.com/joho/godotenv v1.4.0
 | 
				
			||||||
	github.com/kevinburke/ssh_config v1.2.0
 | 
						github.com/kevinburke/ssh_config v1.2.0
 | 
				
			||||||
	github.com/mattn/go-isatty v0.0.17
 | 
						github.com/mattn/go-isatty v0.0.17
 | 
				
			||||||
@@ -20,21 +21,32 @@ require (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
 | 
						github.com/cenkalti/backoff/v3 v3.0.0 // indirect
 | 
				
			||||||
	github.com/davecgh/go-spew v1.1.1 // indirect
 | 
						github.com/davecgh/go-spew v1.1.1 // indirect
 | 
				
			||||||
	github.com/fsnotify/fsnotify v1.6.0 // indirect
 | 
						github.com/fsnotify/fsnotify v1.6.0 // indirect
 | 
				
			||||||
	github.com/golang/snappy v0.0.1 // indirect
 | 
						github.com/golang/snappy v0.0.1 // indirect
 | 
				
			||||||
 | 
						github.com/hashicorp/errwrap v1.1.0 // indirect
 | 
				
			||||||
 | 
						github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
 | 
				
			||||||
 | 
						github.com/hashicorp/go-multierror v1.1.1 // indirect
 | 
				
			||||||
 | 
						github.com/hashicorp/go-retryablehttp v0.6.6 // indirect
 | 
				
			||||||
 | 
						github.com/hashicorp/go-rootcerts v1.0.2 // indirect
 | 
				
			||||||
 | 
						github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect
 | 
				
			||||||
 | 
						github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
 | 
				
			||||||
 | 
						github.com/hashicorp/go-sockaddr v1.0.2 // indirect
 | 
				
			||||||
	github.com/hashicorp/hcl v1.0.0 // indirect
 | 
						github.com/hashicorp/hcl v1.0.0 // indirect
 | 
				
			||||||
	github.com/inconshreveable/mousetrap v1.1.0 // indirect
 | 
						github.com/inconshreveable/mousetrap v1.1.0 // indirect
 | 
				
			||||||
	github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible // indirect
 | 
						github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible // indirect
 | 
				
			||||||
	github.com/klauspost/compress v1.13.6 // indirect
 | 
						github.com/klauspost/compress v1.13.6 // indirect
 | 
				
			||||||
	github.com/magiconair/properties v1.8.7 // indirect
 | 
						github.com/magiconair/properties v1.8.7 // indirect
 | 
				
			||||||
	github.com/mattn/go-colorable v0.1.13 // indirect
 | 
						github.com/mattn/go-colorable v0.1.13 // indirect
 | 
				
			||||||
 | 
						github.com/mitchellh/go-homedir v1.1.0 // indirect
 | 
				
			||||||
	github.com/mitchellh/mapstructure v1.5.0 // indirect
 | 
						github.com/mitchellh/mapstructure v1.5.0 // indirect
 | 
				
			||||||
	github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
 | 
						github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
 | 
				
			||||||
	github.com/pelletier/go-toml v1.9.5 // indirect
 | 
						github.com/pelletier/go-toml v1.9.5 // indirect
 | 
				
			||||||
	github.com/pelletier/go-toml/v2 v2.0.6 // indirect
 | 
						github.com/pelletier/go-toml/v2 v2.0.6 // indirect
 | 
				
			||||||
	github.com/pmezard/go-difflib v1.0.0 // indirect
 | 
						github.com/pmezard/go-difflib v1.0.0 // indirect
 | 
				
			||||||
	github.com/robfig/cron/v3 v3.0.1 // indirect
 | 
						github.com/robfig/cron/v3 v3.0.1 // indirect
 | 
				
			||||||
 | 
						github.com/ryanuber/go-glob v1.0.0 // indirect
 | 
				
			||||||
	github.com/spf13/afero v1.9.3 // indirect
 | 
						github.com/spf13/afero v1.9.3 // indirect
 | 
				
			||||||
	github.com/spf13/cast v1.5.0 // indirect
 | 
						github.com/spf13/cast v1.5.0 // indirect
 | 
				
			||||||
	github.com/spf13/jwalterweatherman v1.1.0 // indirect
 | 
						github.com/spf13/jwalterweatherman v1.1.0 // indirect
 | 
				
			||||||
@@ -54,7 +66,9 @@ require (
 | 
				
			|||||||
	golang.org/x/sync v0.1.0 // indirect
 | 
						golang.org/x/sync v0.1.0 // indirect
 | 
				
			||||||
	golang.org/x/sys v0.4.0 // indirect
 | 
						golang.org/x/sys v0.4.0 // indirect
 | 
				
			||||||
	golang.org/x/text v0.6.0 // indirect
 | 
						golang.org/x/text v0.6.0 // indirect
 | 
				
			||||||
 | 
						golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect
 | 
				
			||||||
	gopkg.in/ini.v1 v1.67.0 // indirect
 | 
						gopkg.in/ini.v1 v1.67.0 // indirect
 | 
				
			||||||
 | 
						gopkg.in/square/go-jose.v2 v2.5.1 // indirect
 | 
				
			||||||
	gopkg.in/yaml.v2 v2.4.0 // indirect
 | 
						gopkg.in/yaml.v2 v2.4.0 // indirect
 | 
				
			||||||
	gopkg.in/yaml.v3 v3.0.1 // indirect
 | 
						gopkg.in/yaml.v3 v3.0.1 // indirect
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										47
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								go.sum
									
									
									
									
									
								
							@@ -39,6 +39,10 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
 | 
				
			|||||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 | 
					github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 | 
				
			||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 | 
					github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 | 
				
			||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 | 
					github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 | 
				
			||||||
 | 
					github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
 | 
				
			||||||
 | 
					github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
 | 
				
			||||||
 | 
					github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c=
 | 
				
			||||||
 | 
					github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
 | 
				
			||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 | 
					github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 | 
				
			||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
 | 
					github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
 | 
				
			||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
 | 
					github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
 | 
				
			||||||
@@ -58,6 +62,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
 | 
				
			|||||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
 | 
					github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
 | 
				
			||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 | 
					github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 | 
				
			||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 | 
					github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 | 
				
			||||||
 | 
					github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 | 
				
			||||||
 | 
					github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
 | 
				
			||||||
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
 | 
					github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
 | 
				
			||||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
 | 
					github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
 | 
				
			||||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
 | 
					github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
 | 
				
			||||||
@@ -66,6 +72,7 @@ github.com/go-co-op/gocron v1.18.0/go.mod h1:sD/a0Aadtw5CpflUJ/lpP9Vfdk979Wl1Sg3
 | 
				
			|||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
 | 
					github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
 | 
				
			||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 | 
					github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 | 
				
			||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 | 
					github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 | 
				
			||||||
 | 
					github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw=
 | 
				
			||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 | 
					github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 | 
				
			||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 | 
					github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 | 
				
			||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 | 
					github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 | 
				
			||||||
@@ -124,10 +131,34 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
 | 
				
			|||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 | 
					github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 | 
				
			||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 | 
					github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 | 
				
			||||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
 | 
					github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
 | 
				
			||||||
 | 
					github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
 | 
				
			||||||
 | 
					github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
 | 
				
			||||||
 | 
					github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-retryablehttp v0.6.6 h1:HJunrbHTDDbBb/ay4kxa1n+dLmttUlnP3V9oNE4hmsM=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
 | 
				
			||||||
 | 
					github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
 | 
				
			||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 | 
					github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 | 
				
			||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 | 
					github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 | 
				
			||||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
 | 
					github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
 | 
				
			||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
 | 
					github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
 | 
				
			||||||
 | 
					github.com/hashicorp/vault/api v1.9.0 h1:ab7dI6W8DuCY7yCU8blo0UCYl2oHre/dloCmzMWg9w8=
 | 
				
			||||||
 | 
					github.com/hashicorp/vault/api v1.9.0/go.mod h1:lloELQP4EyhjnCQhF8agKvWIVTmxbpEJj70b98959sM=
 | 
				
			||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 | 
					github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 | 
				
			||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 | 
					github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 | 
				
			||||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 | 
					github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 | 
				
			||||||
@@ -152,13 +183,20 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 | 
				
			|||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 | 
					github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 | 
				
			||||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
 | 
					github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
 | 
				
			||||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
 | 
					github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
 | 
				
			||||||
 | 
					github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
 | 
				
			||||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
 | 
					github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
 | 
				
			||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
 | 
					github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
 | 
				
			||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
 | 
					github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
 | 
				
			||||||
 | 
					github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 | 
				
			||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
 | 
					github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
 | 
				
			||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 | 
					github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 | 
				
			||||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
 | 
					github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
 | 
				
			||||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 | 
					github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 | 
				
			||||||
 | 
					github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
 | 
				
			||||||
 | 
					github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
 | 
				
			||||||
 | 
					github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
 | 
				
			||||||
 | 
					github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
 | 
				
			||||||
 | 
					github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 | 
				
			||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
 | 
					github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
 | 
				
			||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 | 
					github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 | 
				
			||||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
 | 
					github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
 | 
				
			||||||
@@ -174,6 +212,7 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
 | 
				
			|||||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
 | 
					github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
 | 
				
			||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 | 
					github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 | 
				
			||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
					github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
				
			||||||
 | 
					github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
 | 
				
			||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 | 
					github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 | 
				
			||||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
 | 
					github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
 | 
				
			||||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
 | 
					github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
 | 
				
			||||||
@@ -183,6 +222,9 @@ github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
 | 
				
			|||||||
github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
 | 
					github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
 | 
				
			||||||
github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
 | 
					github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
 | 
				
			||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 | 
					github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 | 
				
			||||||
 | 
					github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
 | 
				
			||||||
 | 
					github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
 | 
				
			||||||
 | 
					github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
 | 
				
			||||||
github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
 | 
					github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
 | 
				
			||||||
github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
 | 
					github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
 | 
				
			||||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
 | 
					github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
 | 
				
			||||||
@@ -339,6 +381,7 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
 | 
				
			|||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
				
			||||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
 | 
					golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
 | 
				
			||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
				
			||||||
 | 
					golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
					golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
					golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
@@ -395,6 +438,8 @@ golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 | 
				
			|||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
					golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
				
			||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
					golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
				
			||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
					golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
				
			||||||
 | 
					golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U=
 | 
				
			||||||
 | 
					golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
				
			||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 | 
					golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 | 
				
			||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 | 
					golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 | 
				
			||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
 | 
					golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
 | 
				
			||||||
@@ -542,6 +587,8 @@ gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
 | 
				
			|||||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 | 
					gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 | 
				
			||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
 | 
					gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
 | 
				
			||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
 | 
					gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
 | 
				
			||||||
 | 
					gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w=
 | 
				
			||||||
 | 
					gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
 | 
				
			||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
					gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
				
			||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 | 
					gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 | 
				
			||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 | 
					gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,7 @@ import (
 | 
				
			|||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"os/exec"
 | 
						"os/exec"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
	"text/template"
 | 
						"text/template"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"embed"
 | 
						"embed"
 | 
				
			||||||
@@ -29,7 +30,7 @@ var Sprintf = fmt.Sprintf
 | 
				
			|||||||
// The environment of local commands will be the machine's environment plus any extra
 | 
					// The environment of local commands will be the machine's environment plus any extra
 | 
				
			||||||
// variables specified in the Env file or Environment.
 | 
					// variables specified in the Env file or Environment.
 | 
				
			||||||
// Dir can also be specified for local commands.
 | 
					// Dir can also be specified for local commands.
 | 
				
			||||||
func (command *Command) RunCmd(log *zerolog.Logger, backyConf *BackyConfigFile) ([]string, error) {
 | 
					func (command *Command) RunCmd(log *zerolog.Logger, backyConf *BackyConfigFile, opts *BackyConfigOpts) ([]string, error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		outputArr     []string
 | 
							outputArr     []string
 | 
				
			||||||
@@ -48,7 +49,13 @@ func (command *Command) RunCmd(log *zerolog.Logger, backyConf *BackyConfigFile)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if command.Host != nil {
 | 
						if command.Host != nil {
 | 
				
			||||||
		log.Info().Str("Command", fmt.Sprintf("Running command %s %s on host %s", command.Cmd, ArgsStr, *command.Host)).Send()
 | 
							command.Type = strings.TrimSpace(command.Type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if command.Type != "" {
 | 
				
			||||||
 | 
								log.Info().Str("Command", fmt.Sprintf("Running script %s on host %s", command.Cmd, *command.Host)).Send()
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								log.Info().Str("Command", fmt.Sprintf("Running command %s %s on host %s", command.Cmd, ArgsStr, *command.Host)).Send()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if command.RemoteHost.SshClient == nil {
 | 
							if command.RemoteHost.SshClient == nil {
 | 
				
			||||||
			err := command.RemoteHost.ConnectToSSHHost(log, backyConf)
 | 
								err := command.RemoteHost.ConnectToSSHHost(log, backyConf)
 | 
				
			||||||
@@ -58,12 +65,11 @@ func (command *Command) RunCmd(log *zerolog.Logger, backyConf *BackyConfigFile)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		commandSession, err := command.RemoteHost.SshClient.NewSession()
 | 
							commandSession, err := command.RemoteHost.SshClient.NewSession()
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			log.Err(fmt.Errorf("new ssh session: %w", err)).Send()
 | 
					 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		defer commandSession.Close()
 | 
							defer commandSession.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		injectEnvIntoSSH(envVars, commandSession, log)
 | 
							injectEnvIntoSSH(envVars, commandSession, opts)
 | 
				
			||||||
		cmd := command.Cmd
 | 
							cmd := command.Cmd
 | 
				
			||||||
		for _, a := range command.Args {
 | 
							for _, a := range command.Args {
 | 
				
			||||||
			cmd += " " + a
 | 
								cmd += " " + a
 | 
				
			||||||
@@ -76,6 +82,94 @@ func (command *Command) RunCmd(log *zerolog.Logger, backyConf *BackyConfigFile)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		commandSession.Stdout = cmdOutWriters
 | 
							commandSession.Stdout = cmdOutWriters
 | 
				
			||||||
		commandSession.Stderr = cmdOutWriters
 | 
							commandSession.Stderr = cmdOutWriters
 | 
				
			||||||
 | 
							if command.Type != "" {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if command.Type == "script" {
 | 
				
			||||||
 | 
									script := bytes.NewBufferString(cmd + "\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									commandSession.Stdin = script
 | 
				
			||||||
 | 
									if err := commandSession.Shell(); err != nil {
 | 
				
			||||||
 | 
										return nil, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if err := commandSession.Wait(); err != nil {
 | 
				
			||||||
 | 
										outScanner := bufio.NewScanner(&cmdOutBuf)
 | 
				
			||||||
 | 
										for outScanner.Scan() {
 | 
				
			||||||
 | 
											outMap := make(map[string]interface{})
 | 
				
			||||||
 | 
											outMap["cmd"] = cmd
 | 
				
			||||||
 | 
											outMap["output"] = outScanner.Text()
 | 
				
			||||||
 | 
											if str, ok := outMap["output"].(string); ok {
 | 
				
			||||||
 | 
												outputArr = append(outputArr, str)
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											log.Info().Fields(outMap).Send()
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										return outputArr, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									outScanner := bufio.NewScanner(&cmdOutBuf)
 | 
				
			||||||
 | 
									for outScanner.Scan() {
 | 
				
			||||||
 | 
										outMap := make(map[string]interface{})
 | 
				
			||||||
 | 
										outMap["cmd"] = cmd
 | 
				
			||||||
 | 
										outMap["output"] = outScanner.Text()
 | 
				
			||||||
 | 
										if str, ok := outMap["output"].(string); ok {
 | 
				
			||||||
 | 
											outputArr = append(outputArr, str)
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										log.Info().Fields(outMap).Send()
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return outputArr, nil
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if command.Type == "scriptFile" {
 | 
				
			||||||
 | 
									var buffer bytes.Buffer
 | 
				
			||||||
 | 
									var dirErr error
 | 
				
			||||||
 | 
									command.Cmd, dirErr = resolveDir(command.Cmd)
 | 
				
			||||||
 | 
									if dirErr != nil {
 | 
				
			||||||
 | 
										return nil, dirErr
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									file, err := os.Open(command.Cmd)
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										return nil, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									defer file.Close()
 | 
				
			||||||
 | 
									_, err = io.Copy(&buffer, file)
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										return nil, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									script := &buffer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									commandSession.Stdin = script
 | 
				
			||||||
 | 
									if err := commandSession.Shell(); err != nil {
 | 
				
			||||||
 | 
										return nil, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if err := commandSession.Wait(); err != nil {
 | 
				
			||||||
 | 
										outScanner := bufio.NewScanner(&cmdOutBuf)
 | 
				
			||||||
 | 
										for outScanner.Scan() {
 | 
				
			||||||
 | 
											outMap := make(map[string]interface{})
 | 
				
			||||||
 | 
											outMap["cmd"] = cmd
 | 
				
			||||||
 | 
											outMap["output"] = outScanner.Text()
 | 
				
			||||||
 | 
											if str, ok := outMap["output"].(string); ok {
 | 
				
			||||||
 | 
												outputArr = append(outputArr, str)
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											log.Info().Fields(outMap).Send()
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										return outputArr, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									outScanner := bufio.NewScanner(&cmdOutBuf)
 | 
				
			||||||
 | 
									for outScanner.Scan() {
 | 
				
			||||||
 | 
										outMap := make(map[string]interface{})
 | 
				
			||||||
 | 
										outMap["cmd"] = cmd
 | 
				
			||||||
 | 
										outMap["output"] = outScanner.Text()
 | 
				
			||||||
 | 
										if str, ok := outMap["output"].(string); ok {
 | 
				
			||||||
 | 
											outputArr = append(outputArr, str)
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										log.Info().Fields(outMap).Send()
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return outputArr, nil
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return nil, fmt.Errorf("command type not recognized")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		err = commandSession.Run(cmd)
 | 
							err = commandSession.Run(cmd)
 | 
				
			||||||
		outScanner := bufio.NewScanner(&cmdOutBuf)
 | 
							outScanner := bufio.NewScanner(&cmdOutBuf)
 | 
				
			||||||
		for outScanner.Scan() {
 | 
							for outScanner.Scan() {
 | 
				
			||||||
@@ -93,10 +187,6 @@ func (command *Command) RunCmd(log *zerolog.Logger, backyConf *BackyConfigFile)
 | 
				
			|||||||
			return outputArr, err
 | 
								return outputArr, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		cmdExists := command.checkCmdExists()
 | 
					 | 
				
			||||||
		if !cmdExists {
 | 
					 | 
				
			||||||
			log.Info().Str(command.Cmd, "not found").Send()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var err error
 | 
							var err error
 | 
				
			||||||
		if command.Shell != "" {
 | 
							if command.Shell != "" {
 | 
				
			||||||
@@ -177,10 +267,9 @@ func (command *Command) RunCmd(log *zerolog.Logger, backyConf *BackyConfigFile)
 | 
				
			|||||||
	return outputArr, nil
 | 
						return outputArr, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func cmdListWorker(msgTemps *msgTemplates, jobs <-chan *CmdList, config *BackyConfigFile, results chan<- string) {
 | 
					func cmdListWorker(msgTemps *msgTemplates, jobs <-chan *CmdList, config *BackyConfigFile, results chan<- string, opts *BackyConfigOpts) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for list := range jobs {
 | 
						for list := range jobs {
 | 
				
			||||||
		var currentCmd string
 | 
					 | 
				
			||||||
		fieldsMap := make(map[string]interface{})
 | 
							fieldsMap := make(map[string]interface{})
 | 
				
			||||||
		fieldsMap["list"] = list.Name
 | 
							fieldsMap["list"] = list.Name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -188,13 +277,14 @@ func cmdListWorker(msgTemps *msgTemplates, jobs <-chan *CmdList, config *BackyCo
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		var count int
 | 
							var count int
 | 
				
			||||||
		var cmdsRan []string
 | 
							var cmdsRan []string
 | 
				
			||||||
 | 
							var outStructArr []outStruct
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for _, cmd := range list.Order {
 | 
							for _, cmd := range list.Order {
 | 
				
			||||||
			currentCmd = config.Cmds[cmd].Cmd
 | 
								currentCmd := config.Cmds[cmd].Cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			fieldsMap["cmd"] = config.Cmds[cmd].Cmd
 | 
								fieldsMap["cmd"] = config.Cmds[cmd].Cmd
 | 
				
			||||||
			cmdLog.Fields(fieldsMap).Send()
 | 
					 | 
				
			||||||
			cmdToRun := config.Cmds[cmd]
 | 
								cmdToRun := config.Cmds[cmd]
 | 
				
			||||||
 | 
								cmdLog.Fields(fieldsMap).Send()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			cmdLogger := config.Logger.With().
 | 
								cmdLogger := config.Logger.With().
 | 
				
			||||||
				Str("backy-cmd", cmd).Str("Host", "local machine").
 | 
									Str("backy-cmd", cmd).Str("Host", "local machine").
 | 
				
			||||||
@@ -206,7 +296,17 @@ func cmdListWorker(msgTemps *msgTemplates, jobs <-chan *CmdList, config *BackyCo
 | 
				
			|||||||
					Logger()
 | 
										Logger()
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			outputArr, runOutErr := cmdToRun.RunCmd(&cmdLogger, config)
 | 
								outputArr, runOutErr := cmdToRun.RunCmd(&cmdLogger, config, opts)
 | 
				
			||||||
 | 
								if cmdToRun.Output {
 | 
				
			||||||
 | 
									outputStruct := outStruct{
 | 
				
			||||||
 | 
										CmdName:     cmd,
 | 
				
			||||||
 | 
										CmdExecuted: currentCmd,
 | 
				
			||||||
 | 
										Output:      outputArr,
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									outStructArr = append(outStructArr, outputStruct)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			count++
 | 
								count++
 | 
				
			||||||
			if runOutErr != nil {
 | 
								if runOutErr != nil {
 | 
				
			||||||
				var errMsg bytes.Buffer
 | 
									var errMsg bytes.Buffer
 | 
				
			||||||
@@ -215,10 +315,14 @@ func cmdListWorker(msgTemps *msgTemplates, jobs <-chan *CmdList, config *BackyCo
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
					errStruct["listName"] = list.Name
 | 
										errStruct["listName"] = list.Name
 | 
				
			||||||
					errStruct["Command"] = currentCmd
 | 
										errStruct["Command"] = currentCmd
 | 
				
			||||||
 | 
										errStruct["Cmd"] = cmd
 | 
				
			||||||
 | 
										errStruct["Args"] = config.Cmds[cmd].Args
 | 
				
			||||||
					errStruct["Err"] = runOutErr
 | 
										errStruct["Err"] = runOutErr
 | 
				
			||||||
					errStruct["CmdsRan"] = cmdsRan
 | 
										errStruct["CmdsRan"] = cmdsRan
 | 
				
			||||||
					errStruct["Output"] = outputArr
 | 
										errStruct["Output"] = outputArr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										errStruct["CmdOutput"] = outStructArr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					tmpErr := msgTemps.err.Execute(&errMsg, errStruct)
 | 
										tmpErr := msgTemps.err.Execute(&errMsg, errStruct)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if tmpErr != nil {
 | 
										if tmpErr != nil {
 | 
				
			||||||
@@ -243,9 +347,12 @@ func cmdListWorker(msgTemps *msgTemplates, jobs <-chan *CmdList, config *BackyCo
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
					if list.NotifyConfig != nil {
 | 
										if list.NotifyConfig != nil {
 | 
				
			||||||
						successStruct := make(map[string]interface{})
 | 
											successStruct := make(map[string]interface{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						successStruct["listName"] = list.Name
 | 
											successStruct["listName"] = list.Name
 | 
				
			||||||
						successStruct["CmdsRan"] = cmdsRan
 | 
											successStruct["CmdsRan"] = cmdsRan
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											successStruct["CmdOutput"] = outStructArr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						tmpErr := msgTemps.success.Execute(&successMsg, successStruct)
 | 
											tmpErr := msgTemps.success.Execute(&successMsg, successStruct)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						if tmpErr != nil {
 | 
											if tmpErr != nil {
 | 
				
			||||||
@@ -271,7 +378,7 @@ func cmdListWorker(msgTemps *msgTemplates, jobs <-chan *CmdList, config *BackyCo
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RunBackyConfig runs a command list from the BackyConfigFile.
 | 
					// RunBackyConfig runs a command list from the BackyConfigFile.
 | 
				
			||||||
func (config *BackyConfigFile) RunBackyConfig(cron string) {
 | 
					func (config *BackyConfigFile) RunBackyConfig(cron string, opts *BackyConfigOpts) {
 | 
				
			||||||
	mTemps := &msgTemplates{
 | 
						mTemps := &msgTemplates{
 | 
				
			||||||
		err:     template.Must(template.New("error.txt").ParseFS(templates, "templates/error.txt")),
 | 
							err:     template.Must(template.New("error.txt").ParseFS(templates, "templates/error.txt")),
 | 
				
			||||||
		success: template.Must(template.New("success.txt").ParseFS(templates, "templates/success.txt")),
 | 
							success: template.Must(template.New("success.txt").ParseFS(templates, "templates/success.txt")),
 | 
				
			||||||
@@ -283,7 +390,7 @@ func (config *BackyConfigFile) RunBackyConfig(cron string) {
 | 
				
			|||||||
	// This starts up 3 workers, initially blocked
 | 
						// This starts up 3 workers, initially blocked
 | 
				
			||||||
	// because there are no jobs yet.
 | 
						// because there are no jobs yet.
 | 
				
			||||||
	for w := 1; w <= configListsLen; w++ {
 | 
						for w := 1; w <= configListsLen; w++ {
 | 
				
			||||||
		go cmdListWorker(mTemps, listChan, config, results)
 | 
							go cmdListWorker(mTemps, listChan, config, results, opts)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Here we send 5 `jobs` and then `close` that
 | 
						// Here we send 5 `jobs` and then `close` that
 | 
				
			||||||
@@ -316,7 +423,7 @@ func (config *BackyConfigFile) ExecuteCmds(opts *BackyConfigOpts) {
 | 
				
			|||||||
		cmdLogger := config.Logger.With().
 | 
							cmdLogger := config.Logger.With().
 | 
				
			||||||
			Str("backy-cmd", cmd).
 | 
								Str("backy-cmd", cmd).
 | 
				
			||||||
			Logger()
 | 
								Logger()
 | 
				
			||||||
		_, runErr := cmdToRun.RunCmd(&cmdLogger, config)
 | 
							_, runErr := cmdToRun.RunCmd(&cmdLogger, config, opts)
 | 
				
			||||||
		if runErr != nil {
 | 
							if runErr != nil {
 | 
				
			||||||
			config.Logger.Err(runErr).Send()
 | 
								config.Logger.Err(runErr).Send()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package backy
 | 
					package backy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
@@ -8,12 +9,39 @@ import (
 | 
				
			|||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"git.andrewnw.xyz/CyberShell/backy/pkg/logging"
 | 
						"git.andrewnw.xyz/CyberShell/backy/pkg/logging"
 | 
				
			||||||
	"github.com/joho/godotenv"
 | 
						vault "github.com/hashicorp/vault/api"
 | 
				
			||||||
	"github.com/mattn/go-isatty"
 | 
						"github.com/mattn/go-isatty"
 | 
				
			||||||
	"github.com/rs/zerolog"
 | 
						"github.com/rs/zerolog"
 | 
				
			||||||
	"github.com/spf13/viper"
 | 
						"github.com/spf13/viper"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (opts *BackyConfigOpts) InitConfig() {
 | 
				
			||||||
 | 
						if opts.viper != nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						backyViper := viper.New()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if strings.TrimSpace(opts.ConfigFilePath) != "" {
 | 
				
			||||||
 | 
							err := testFile(opts.ConfigFilePath)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logging.ExitWithMSG(fmt.Sprintf("Could not open config file %s: %v", opts.ConfigFilePath, err), 1, nil)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							backyViper.SetConfigFile(opts.ConfigFilePath)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							backyViper.SetConfigName("backy.yml")           // name of config file (with extension)
 | 
				
			||||||
 | 
							backyViper.SetConfigName("backy.yaml")          // name of config file (with extension)
 | 
				
			||||||
 | 
							backyViper.SetConfigType("yaml")                // REQUIRED if the config file does not have the extension in the name
 | 
				
			||||||
 | 
							backyViper.AddConfigPath(".")                   // optionally look for config in the working directory
 | 
				
			||||||
 | 
							backyViper.AddConfigPath("$HOME/.config/backy") // call multiple times to add many search paths
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err := backyViper.ReadInConfig() // Find and read the config file
 | 
				
			||||||
 | 
						if err != nil {                  // Handle errors reading the config file
 | 
				
			||||||
 | 
							msg := fmt.Sprintf("fatal error reading config file %s: %v", backyViper.ConfigFileUsed(), err)
 | 
				
			||||||
 | 
							logging.ExitWithMSG(msg, 1, nil)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						opts.viper = backyViper
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ReadConfig validates and reads the config file.
 | 
					// ReadConfig validates and reads the config file.
 | 
				
			||||||
func ReadConfig(opts *BackyConfigOpts) *BackyConfigFile {
 | 
					func ReadConfig(opts *BackyConfigOpts) *BackyConfigFile {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -28,10 +56,10 @@ func ReadConfig(opts *BackyConfigOpts) *BackyConfigFile {
 | 
				
			|||||||
	backyConfigFile := NewConfig()
 | 
						backyConfigFile := NewConfig()
 | 
				
			||||||
	backyViper := opts.viper
 | 
						backyViper := opts.viper
 | 
				
			||||||
	opts.loadEnv()
 | 
						opts.loadEnv()
 | 
				
			||||||
	envFileInConfigDir := fmt.Sprintf("%s/.env", path.Dir(backyViper.ConfigFileUsed()))
 | 
						// envFileInConfigDir := fmt.Sprintf("%s/.env", path.Dir(backyViper.ConfigFileUsed()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// load the .env file in config file directory
 | 
						// load the .env file in config file directory
 | 
				
			||||||
	_ = godotenv.Load(envFileInConfigDir)
 | 
						// _ = godotenv.Load(envFileInConfigDir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if backyViper.GetBool(getNestedConfig("logging", "cmd-std-out")) {
 | 
						if backyViper.GetBool(getNestedConfig("logging", "cmd-std-out")) {
 | 
				
			||||||
		os.Setenv("BACKY_STDOUT", "enabled")
 | 
							os.Setenv("BACKY_STDOUT", "enabled")
 | 
				
			||||||
@@ -239,6 +267,11 @@ func ReadConfig(opts *BackyConfigOpts) *BackyConfigFile {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	backyConfigFile.SetupNotify()
 | 
						backyConfigFile.SetupNotify()
 | 
				
			||||||
	opts.ConfigFile = backyConfigFile
 | 
						opts.ConfigFile = backyConfigFile
 | 
				
			||||||
 | 
						if err := opts.setupVault(); err != nil {
 | 
				
			||||||
 | 
							log.Err(err).Send()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						opts.ConfigFile = backyConfigFile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return backyConfigFile
 | 
						return backyConfigFile
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -261,29 +294,101 @@ func getCmdListFromConfig(list string) string {
 | 
				
			|||||||
	return fmt.Sprintf("cmd-configs.%s", list)
 | 
						return fmt.Sprintf("cmd-configs.%s", list)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (opts *BackyConfigOpts) InitConfig() {
 | 
					func (opts *BackyConfigOpts) setupVault() error {
 | 
				
			||||||
	if opts.viper != nil {
 | 
						if !opts.viper.GetBool("vault.enabled") {
 | 
				
			||||||
		return
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	backyViper := viper.New()
 | 
						config := vault.DefaultConfig()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if strings.TrimSpace(opts.ConfigFilePath) != "" {
 | 
						config.Address = opts.viper.GetString("vault.address")
 | 
				
			||||||
		err := testFile(opts.ConfigFilePath)
 | 
						if strings.TrimSpace(config.Address) == "" {
 | 
				
			||||||
		if err != nil {
 | 
							config.Address = os.Getenv("VAULT_ADDR")
 | 
				
			||||||
			logging.ExitWithMSG(fmt.Sprintf("Could not open config file %s: %v", opts.ConfigFilePath, err), 1, nil)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		backyViper.SetConfigFile(opts.ConfigFilePath)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		backyViper.SetConfigName("backy.yml")           // name of config file (with extension)
 | 
					 | 
				
			||||||
		backyViper.SetConfigName("backy.yaml")          // name of config file (with extension)
 | 
					 | 
				
			||||||
		backyViper.SetConfigType("yaml")                // REQUIRED if the config file does not have the extension in the name
 | 
					 | 
				
			||||||
		backyViper.AddConfigPath(".")                   // optionally look for config in the working directory
 | 
					 | 
				
			||||||
		backyViper.AddConfigPath("$HOME/.config/backy") // call multiple times to add many search paths
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err := backyViper.ReadInConfig() // Find and read the config file
 | 
					
 | 
				
			||||||
	if err != nil {                  // Handle errors reading the config file
 | 
						client, err := vault.NewClient(config)
 | 
				
			||||||
		msg := fmt.Sprintf("fatal error reading config file %s: %v", backyViper.ConfigFileUsed(), err)
 | 
						if err != nil {
 | 
				
			||||||
		logging.ExitWithMSG(msg, 1, nil)
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	opts.viper = backyViper
 | 
					
 | 
				
			||||||
 | 
						token := opts.viper.GetString("vault.token")
 | 
				
			||||||
 | 
						if strings.TrimSpace(token) == "" {
 | 
				
			||||||
 | 
							token = os.Getenv("VAULT_TOKEN")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						client.SetToken(token)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmdListCfg := opts.viper.Sub("viper.keys")
 | 
				
			||||||
 | 
						unmarshalErr := cmdListCfg.Unmarshal(&opts.VaultKeys)
 | 
				
			||||||
 | 
						if unmarshalErr != nil {
 | 
				
			||||||
 | 
							panic(fmt.Errorf("error unmarshalling viper.keys into struct: %w", unmarshalErr))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						opts.vaultClient = client
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getVaultSecret(vaultClient *vault.Client, key *VaultKey) (string, error) {
 | 
				
			||||||
 | 
						var (
 | 
				
			||||||
 | 
							secret *vault.KVSecret
 | 
				
			||||||
 | 
							err    error
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if key.ValueType == "KVv2" {
 | 
				
			||||||
 | 
							secret, err = vaultClient.KVv2(key.MountPath).Get(context.Background(), key.Path)
 | 
				
			||||||
 | 
						} else if key.ValueType == "KVv1" {
 | 
				
			||||||
 | 
							secret, err = vaultClient.KVv1(key.MountPath).Get(context.Background(), key.Path)
 | 
				
			||||||
 | 
						} else if key.ValueType != "" {
 | 
				
			||||||
 | 
							return "", fmt.Errorf("type %s for key %s not known. Valid types are KVv1 or KVv2", key.ValueType, key.Name)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return "", fmt.Errorf("type for key %s must be specified. Valid types are KVv1 or KVv2", key.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", fmt.Errorf("unable to read secret: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value, ok := secret.Data[key.Name].(string)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return "", fmt.Errorf("value type assertion failed: %T %#v", secret.Data[key.Name], secret.Data[key.Name])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return value, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func isVaultKey(str string) (string, bool) {
 | 
				
			||||||
 | 
						str = strings.TrimSpace(str)
 | 
				
			||||||
 | 
						return strings.TrimPrefix(str, "vault:"), strings.HasPrefix(str, "vault:")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseVaultKey(str string, keys []*VaultKey) (*VaultKey, error) {
 | 
				
			||||||
 | 
						keyName, isKey := isVaultKey(str)
 | 
				
			||||||
 | 
						if !isKey {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, k := range keys {
 | 
				
			||||||
 | 
							if k.Name == keyName {
 | 
				
			||||||
 | 
								return k, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil, fmt.Errorf("key %s not found in vault keys", keyName)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GetVaultKey(str string, opts *BackyConfigOpts) string {
 | 
				
			||||||
 | 
						key, err := parseVaultKey(str, opts.VaultKeys)
 | 
				
			||||||
 | 
						if key == nil && err == nil {
 | 
				
			||||||
 | 
							return str
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err != nil && key == nil {
 | 
				
			||||||
 | 
							opts.ConfigFile.Logger.Err(err).Send()
 | 
				
			||||||
 | 
							return ""
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value, secretErr := getVaultSecret(opts.vaultClient, key)
 | 
				
			||||||
 | 
						if secretErr != nil {
 | 
				
			||||||
 | 
							opts.ConfigFile.Logger.Err(secretErr).Send()
 | 
				
			||||||
 | 
							return value
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return value
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,8 @@
 | 
				
			|||||||
Command list {{.listName }} failed on running {{.Command}}.
 | 
					Command list {{.listName }} failed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The command run was {{.Cmd}}.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The command executed was {{.Command}} {{ if .Args }} {{- range .Args}} {{.}} {{end}} {{end}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{ if .Err }} The error was {{ .Err }}{{ end }}
 | 
					{{ if .Err }} The error was {{ .Err }}{{ end }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -9,4 +13,10 @@ The following commands ran:
 | 
				
			|||||||
{{- range .CmdsRan}}
 | 
					{{- range .CmdsRan}}
 | 
				
			||||||
    - {{. -}}
 | 
					    - {{. -}}
 | 
				
			||||||
{{end}}
 | 
					{{end}}
 | 
				
			||||||
 | 
					{{ end }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{{ if .CmdOutput }}{{- range .CmdOutput }}Commad output for {{ .CmdName }}:
 | 
				
			||||||
 | 
					{{- range .Output}}
 | 
				
			||||||
 | 
					    {{ . }}
 | 
				
			||||||
 | 
					{{ end }}{{ end }}
 | 
				
			||||||
{{ end }}
 | 
					{{ end }}
 | 
				
			||||||
@@ -1,7 +1,12 @@
 | 
				
			|||||||
Command list {{ .listName }} was completed successfully. 
 | 
					Command list {{ .listName }} completed successfully. 
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
The following commands ran:
 | 
					The following commands ran:
 | 
				
			||||||
{{- range .CmdsRan}}
 | 
					{{- range .CmdsRan}}
 | 
				
			||||||
    - {{. -}}
 | 
					    - {{. -}}
 | 
				
			||||||
{{end}}
 | 
					{{end}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{{ if .CmdOutput }}{{- range .CmdOutput }}Commad output for {{ .CmdName }}:
 | 
				
			||||||
 | 
					{{- range .Output}}
 | 
				
			||||||
 | 
					    {{ . }}
 | 
				
			||||||
 | 
					{{ end }}{{ end }}
 | 
				
			||||||
 | 
					{{ end }}
 | 
				
			||||||
@@ -4,6 +4,7 @@ import (
 | 
				
			|||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"text/template"
 | 
						"text/template"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vaultapi "github.com/hashicorp/vault/api"
 | 
				
			||||||
	"github.com/kevinburke/ssh_config"
 | 
						"github.com/kevinburke/ssh_config"
 | 
				
			||||||
	"github.com/nikoksr/notify"
 | 
						"github.com/nikoksr/notify"
 | 
				
			||||||
	"github.com/rs/zerolog"
 | 
						"github.com/rs/zerolog"
 | 
				
			||||||
@@ -66,6 +67,10 @@ type (
 | 
				
			|||||||
		// command to run
 | 
							// command to run
 | 
				
			||||||
		Cmd string `yaml:"cmd"`
 | 
							Cmd string `yaml:"cmd"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Possible values: script, scriptFile
 | 
				
			||||||
 | 
							// If blank, it is regualar command.
 | 
				
			||||||
 | 
							Type string `yaml:"type"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// host on which to run cmd
 | 
							// host on which to run cmd
 | 
				
			||||||
		Host *string `yaml:"host,omitempty"`
 | 
							Host *string `yaml:"host,omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -91,6 +96,10 @@ type (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		// Environment holds env variables to be used with the command
 | 
							// Environment holds env variables to be used with the command
 | 
				
			||||||
		Environment []string `yaml:"environment,omitempty"`
 | 
							Environment []string `yaml:"environment,omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Output determines if output is requested.
 | 
				
			||||||
 | 
							// Only works if command is in a list.
 | 
				
			||||||
 | 
							Output bool `yaml:"output,omitempty"`
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BackyOptionFunc func(*BackyConfigOpts)
 | 
						BackyOptionFunc func(*BackyConfigOpts)
 | 
				
			||||||
@@ -146,9 +155,33 @@ type (
 | 
				
			|||||||
		// Holds env vars from .env file
 | 
							// Holds env vars from .env file
 | 
				
			||||||
		backyEnv map[string]string
 | 
							backyEnv map[string]string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							vaultClient *vaultapi.Client
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							VaultKeys []*VaultKey `yaml:"keys"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		viper *viper.Viper
 | 
							viper *viper.Viper
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						outStruct struct {
 | 
				
			||||||
 | 
							CmdName     string
 | 
				
			||||||
 | 
							CmdExecuted string
 | 
				
			||||||
 | 
							Output      []string
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						VaultKey struct {
 | 
				
			||||||
 | 
							Name      string `yaml:"name"`
 | 
				
			||||||
 | 
							Path      string `yaml:"path"`
 | 
				
			||||||
 | 
							ValueType string `yaml:"type"`
 | 
				
			||||||
 | 
							MountPath string `yaml:"mountpath"`
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						VaultConfig struct {
 | 
				
			||||||
 | 
							Token   string      `yaml:"token"`
 | 
				
			||||||
 | 
							Address string      `yaml:"address"`
 | 
				
			||||||
 | 
							Enabled string      `yaml:"enabled"`
 | 
				
			||||||
 | 
							Keys    []*VaultKey `yaml:"keys"`
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	NotificationsConfig struct {
 | 
						NotificationsConfig struct {
 | 
				
			||||||
		Config  *viper.Viper
 | 
							Config  *viper.Viper
 | 
				
			||||||
		Enabled bool
 | 
							Enabled bool
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,25 +21,25 @@ import (
 | 
				
			|||||||
	"mvdan.cc/sh/v3/shell"
 | 
						"mvdan.cc/sh/v3/shell"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func injectEnvIntoSSH(envVarsToInject environmentVars, process *ssh.Session, log *zerolog.Logger) {
 | 
					func injectEnvIntoSSH(envVarsToInject environmentVars, process *ssh.Session, opts *BackyConfigOpts) {
 | 
				
			||||||
	if envVarsToInject.file != "" {
 | 
						if envVarsToInject.file != "" {
 | 
				
			||||||
		envPath, envPathErr := resolveDir(envVarsToInject.file)
 | 
							envPath, envPathErr := resolveDir(envVarsToInject.file)
 | 
				
			||||||
		if envPathErr != nil {
 | 
							if envPathErr != nil {
 | 
				
			||||||
			log.Fatal().Str("envFile", envPath).Err(envPathErr).Send()
 | 
								opts.ConfigFile.Logger.Fatal().Str("envFile", envPath).Err(envPathErr).Send()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		file, err := os.Open(envPath)
 | 
							file, err := os.Open(envPath)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			log.Fatal().Str("envFile", envPath).Err(err).Send()
 | 
								opts.ConfigFile.Logger.Fatal().Str("envFile", envPath).Err(err).Send()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		defer file.Close()
 | 
							defer file.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		envMap, err := godotenv.Parse(file)
 | 
							envMap, err := godotenv.Parse(file)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			log.Error().Str("envFile", envPath).Err(err).Send()
 | 
								opts.ConfigFile.Logger.Error().Str("envFile", envPath).Err(err).Send()
 | 
				
			||||||
			goto errEnvFile
 | 
								goto errEnvFile
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		for key, val := range envMap {
 | 
							for key, val := range envMap {
 | 
				
			||||||
			process.Setenv(key, val)
 | 
								process.Setenv(key, GetVaultKey(val, opts))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -49,7 +49,8 @@ errEnvFile:
 | 
				
			|||||||
		// don't append env Vars for Backy
 | 
							// don't append env Vars for Backy
 | 
				
			||||||
		if strings.Contains(envVal, "=") {
 | 
							if strings.Contains(envVal, "=") {
 | 
				
			||||||
			envVarArr := strings.Split(envVal, "=")
 | 
								envVarArr := strings.Split(envVal, "=")
 | 
				
			||||||
			process.Setenv(envVarArr[0], envVarArr[1])
 | 
					
 | 
				
			||||||
 | 
								process.Setenv(envVarArr[0], GetVaultKey(envVarArr[1], opts))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -58,10 +59,11 @@ func injectEnvIntoLocalCMD(envVarsToInject environmentVars, process *exec.Cmd, l
 | 
				
			|||||||
	if envVarsToInject.file != "" {
 | 
						if envVarsToInject.file != "" {
 | 
				
			||||||
		envPath, _ := resolveDir(envVarsToInject.file)
 | 
							envPath, _ := resolveDir(envVarsToInject.file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		file, _ := os.Open(envPath)
 | 
							file, fileErr := os.Open(envPath)
 | 
				
			||||||
		// if err != nil {
 | 
							if fileErr != nil {
 | 
				
			||||||
		// 	log.Fatal().Str("envFile", envPath).Err(err).Send()
 | 
								log.Error().Str("envFile", envPath).Err(fileErr).Send()
 | 
				
			||||||
		// }
 | 
								goto errEnvFile
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		defer file.Close()
 | 
							defer file.Close()
 | 
				
			||||||
		envMap, err := godotenv.Parse(file)
 | 
							envMap, err := godotenv.Parse(file)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@@ -69,6 +71,7 @@ func injectEnvIntoLocalCMD(envVarsToInject environmentVars, process *exec.Cmd, l
 | 
				
			|||||||
			goto errEnvFile
 | 
								goto errEnvFile
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		for key, val := range envMap {
 | 
							for key, val := range envMap {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			process.Env = append(process.Env, fmt.Sprintf("%s=%s", key, val))
 | 
								process.Env = append(process.Env, fmt.Sprintf("%s=%s", key, val))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -83,11 +86,6 @@ errEnvFile:
 | 
				
			|||||||
	process.Env = append(process.Env, os.Environ()...)
 | 
						process.Env = append(process.Env, os.Environ()...)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (cmd *Command) checkCmdExists() bool {
 | 
					 | 
				
			||||||
	_, err := exec.LookPath(cmd.Cmd)
 | 
					 | 
				
			||||||
	return err == nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func contains(s []string, e string) bool {
 | 
					func contains(s []string, e string) bool {
 | 
				
			||||||
	for _, a := range s {
 | 
						for _, a := range s {
 | 
				
			||||||
		if a == e {
 | 
							if a == e {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user