diff --git a/.gitignore b/.gitignore index 6d18c4f5..b21204c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ gscloud +.DS_Store +build diff --git a/CHANGELOG.md b/CHANGELOG.md index d537a6cb..3980f5cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,13 @@ # Changelog +## v0.2.0-beta (March 11, 2020) + +FEATURES: +* Use standard user-level cache directory https://github.com/gridscale/gscloud/issues/11 + ## v0.1.0-beta (January 8, 2020) - Initial release of gscloud FEATURES: * Support make-config for creating a new configuration file -* Support kubernetes cluster sub-commands: save-kubeconfig and exec-credential for managing authentication for cluster +* Support kubernetes cluster sub-commands: save-kubeconfig and exec-credential for managing a cluster's authentication diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..1832650d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,22 @@ +# Contributing to gscloud + +As an open source project, we encourage and appreciate any kind of contributions like comments, +enhancement requests, bug reports, or code contributions! + +## Development workflow + +* Development is done on the `develop` branch. +* Releases are cut from the `master` branch. +* For anything larger than single commits, please use feature/bugfix branches. + +## Reporting Bugs or Enhancement Requests + +Please submit bugs or enhancement requests through the public bug tracker within the +GitHub project. + +## Submitting Patches + +The gscloud source code is managed using the git distributed source control +management tool . Please submit patches +accordingly. + diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..0cf70a24 --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +PLATFORMS=windows linux darwin +ARCHES=amd64 +BUILDDIR=build +VERSION=$$(cat VERSION) +EXECUTABLE_NAME=gscloud_$(VERSION) + +buildall: clean build zip + +build: + $(foreach platform,$(PLATFORMS), \ + $(foreach arch,$(ARCHES), \ + mkdir -p $(BUILDDIR); GOOS=$(platform) GOARCH=$(arch) go build -o $(BUILDDIR)/$(EXECUTABLE_NAME)_$(platform)_$(arch);)) + @echo "Renaming Windows file" + @if [ -f $(BUILDDIR)/$(EXECUTABLE_NAME)_windows_$(ARCHES) ]; then mv $(BUILDDIR)/$(EXECUTABLE_NAME)_windows_$(ARCHES) $(BUILDDIR)/$(EXECUTABLE_NAME)_windows_$(ARCHES).exe; fi + +zip: + $(foreach file,$(wildcard $(BUILDDIR)/*),\ + zip -j $(file).zip $(file);) + @if [ -f $(BUILDDIR)/$(EXECUTABLE_NAME)_windows_$(ARCHES).exe.zip ]; then mv $(BUILDDIR)/$(EXECUTABLE_NAME)_windows_$(ARCHES).exe.zip $(BUILDDIR)/$(EXECUTABLE_NAME)_windows_$(ARCHES).zip; fi + +clean: + $(foreach platform,$(PLATFORMS), \ + $(foreach arch,$(ARCHES), \ + rm -f $(BUILDDIR)/gscloud_*;)) + +.PHONY: buildall build clean zip diff --git a/README.md b/README.md index 537e3814..b50fb192 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# gscloud: The Command Line Interface for the gridcsale cloud +# gscloud: The Command Line Interface for the gridscale cloud ## Supported Services @@ -20,7 +20,7 @@ Available Commands: Flags: --account string the account used, 'default' if none given - --config string configuration file, default /home/bk/.config/gridscale/config.yaml + --config string configuration file, default /home/bk/.config/gscloud/config.yaml -h, --help help for gscloud Use "gscloud [command] --help" for more information about a command. @@ -69,7 +69,7 @@ users: command: $HOME/gscloud args: - "--config" - - "$HOME/.gscloud/config.yaml" + - "$HOME/.config/gscloud/config.yaml" - "--account" - "test" - "kubernetes" diff --git a/VERSION b/VERSION new file mode 100644 index 00000000..f2a05766 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.2.0-beta diff --git a/cmd/cliconfig.go b/cmd/cliconfig.go index d1b2cb3a..d244e2c6 100644 --- a/cmd/cliconfig.go +++ b/cmd/cliconfig.go @@ -4,8 +4,9 @@ import ( "fmt" "net/http" "os" - "path/filepath" + "github.com/kardianos/osext" + "github.com/kirsle/configdir" "github.com/spf13/viper" ) @@ -20,22 +21,39 @@ type cliConfig struct { } func cliPath() string { - dir, err := filepath.Abs(filepath.Dir(os.Args[0])) + filePath, err := osext.Executable() if err != nil { fmt.Fprintln(os.Stderr, err) } - return filepath.Join(dir, os.Args[0]) + return filePath +} + +// configPath construct platform specific path to the configuration file. +// - on Linux: $XDG_CONFIG_HOME or $HOME/.config +// - on macOS: $HOME/Library/Application Support +// - on Windows: %APPDATA% or "C:\\Users\\%USER%\\AppData\\Roaming" +func cliConfigPath() string { + path := viper.ConfigFileUsed() + if path == "" { + path = configdir.LocalConfig("gscloud") + "/config.yaml" + viper.SetConfigFile(path) + } + return path +} + +func cliCachePath() string { + return configdir.LocalCache("gscloud") } func newCliClient(account string) *gsclient { var ac accountEntry - + cliConf := &cliConfig{} err := viper.Unmarshal(cliConf) if err != nil { fmt.Fprintln(os.Stderr, err) } - + for _, a := range cliConf.Accounts { if account == a.Name { ac = a @@ -52,3 +70,11 @@ func newCliClient(account string) *gsclient { } return newClient(clientConf) } + +func fileExists(filename string) bool { + info, err := os.Stat(filename) + if os.IsNotExist(err) { + return false + } + return !info.IsDir() +} diff --git a/cmd/kubernetes.go b/cmd/kubernetes.go index 81a2eca6..6b0d6f45 100644 --- a/cmd/kubernetes.go +++ b/cmd/kubernetes.go @@ -93,7 +93,7 @@ var saveKubeconfigCmd = &cobra.Command{ Command: cliPath(), Args: []string{ "--config", - cfgFile, + cliConfigPath(), "--account", account, "kubernetes", @@ -102,6 +102,7 @@ var saveKubeconfigCmd = &cobra.Command{ "--cluster", clusterID, }, + Env: []clientcmdapi.ExecEnvVar{}, }, } } else { @@ -253,8 +254,7 @@ func fetchKubeConfigFromProvider(id string) *kubeConfig { } func kubeConfigCachePath() string { - dir, _ := filepath.Abs(filepath.Dir(cfgFile)) - return filepath.Join(dir, "cache", "exec-credential") + return filepath.Join(cliCachePath(), "exec-credential") } func cachedKubeConfigPath(id string) string { @@ -308,11 +308,3 @@ func loadCachedKubeConfig(id string) (*clientauth.ExecCredential, error) { return execCredential, nil } - -func fileExists(filename string) bool { - info, err := os.Stat(filename) - if os.IsNotExist(err) { - return false - } - return !info.IsDir() -} diff --git a/cmd/makeConfig.go b/cmd/makeConfig.go index 36c1cf3d..bf3a2638 100644 --- a/cmd/makeConfig.go +++ b/cmd/makeConfig.go @@ -4,9 +4,9 @@ import ( "fmt" "io/ioutil" "os" + "path/filepath" "github.com/spf13/cobra" - "github.com/spf13/viper" "gopkg.in/yaml.v2" ) @@ -29,25 +29,22 @@ Create a new configuration file at a specified path: gscloud --config ~/myconfig.yaml make-config -`, configPath()), +`, cliConfigPath()), RunE: func(cmd *cobra.Command, args []string) error { - path := viper.ConfigFileUsed() - if path == "" { - path = configPath() + "/config.yaml" - viper.SetConfigFile(path) - } + filePath := cliConfigPath() - err := os.MkdirAll(configPath(), 0755) - if err != nil { - return err - } + if !fileExists(filePath) { + err := os.MkdirAll(filepath.Dir(filePath), os.FileMode(0700)) + if err != nil { + return err + } - err = ioutil.WriteFile(path, emptyConfig(), 0644) - if err != nil { - return err + err = ioutil.WriteFile(filePath, emptyConfig(), 0644) + if err != nil { + return err + } } - - fmt.Println(path) + fmt.Println(filePath) return nil }, } diff --git a/cmd/root.go b/cmd/root.go index 35ce6ba3..5cc50bad 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -4,7 +4,6 @@ import ( "fmt" "os" - "github.com/kirsle/configdir" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -33,7 +32,7 @@ func Execute() { func init() { cobra.OnInitialize(initConfig) - rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", fmt.Sprintf("configuration file, default %s/config.yaml", configPath())) + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", fmt.Sprintf("configuration file, default %s", cliConfigPath())) rootCmd.PersistentFlags().StringVar(&account, "account", "", "the account used, 'default' if none given") rootCmd.AddCommand(kubernetesCmd) @@ -42,14 +41,6 @@ func init() { } -// configPath construct platform specific path to the configuration file. -// - on Linux: $XDG_CONFIG_HOME or $HOME/.config -// - on macOS: $HOME/Library/Application Support -// - on Windows: %APPDATA% or "C:\\Users\\%USER%\\AppData\\Roaming" -func configPath() string { - return configdir.LocalConfig("gridscale") -} - // initConfig reads in config file and ENV variables if set. func initConfig() { if cfgFile != "" { @@ -59,7 +50,7 @@ func initConfig() { // Use default paths. viper.SetConfigName("config") viper.SetConfigType("yaml") - viper.AddConfigPath(configPath()) + viper.AddConfigPath(cliConfigPath()) viper.AddConfigPath(".") } viper.AutomaticEnv() // read in environment variables that match @@ -74,10 +65,11 @@ func initConfig() { os.Exit(1) } } - + if account == "" { account = "default" } + client = newCliClient(account) if client == nil { os.Exit(1) diff --git a/go.mod b/go.mod index 62e1de7b..d6f5fd5f 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.13 require ( github.com/imdario/mergo v0.3.7 // indirect + github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f github.com/mitchellh/go-homedir v1.1.0 github.com/spf13/cobra v0.0.5 diff --git a/go.sum b/go.sum index 7606d2b7..4e1677b5 100644 --- a/go.sum +++ b/go.sum @@ -143,6 +143,8 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= +github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f h1:dKccXx7xA56UNqOcFIbuqFjAWPVtP688j5QMgmo6OHU= github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f/go.mod h1:4rEELDSfUAlBSyUjPG0JnaNGjf13JySHFeRdD/3dLP0= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=