From cba53e7b9e3f51bd7a2a1cb4464f4c5d6af31567 Mon Sep 17 00:00:00 2001 From: Lee Spottiswood Date: Fri, 2 Dec 2022 11:09:21 +0000 Subject: [PATCH] allow IP address to be specified (#162) --- cmd/ecloud/ecloud_instance.go | 8 +- go.mod | 2 +- go.sum | 4 +- internal/pkg/config/config.go.disabled | 165 ------------- internal/pkg/config/config_test.go.disabled | 253 -------------------- 5 files changed, 10 insertions(+), 422 deletions(-) delete mode 100644 internal/pkg/config/config.go.disabled delete mode 100644 internal/pkg/config/config_test.go.disabled diff --git a/cmd/ecloud/ecloud_instance.go b/cmd/ecloud/ecloud_instance.go index 67fe7c9..9143bad 100644 --- a/cmd/ecloud/ecloud_instance.go +++ b/cmd/ecloud/ecloud_instance.go @@ -114,7 +114,7 @@ func ecloudInstanceCreateCmd(f factory.ClientFactory) *cobra.Command { Use: "create", Short: "Creates an instance", Long: "This command creates an instance", - Example: "ans ecloud instance create --vpc vpc-abcdef12 --vcpu 2 --ram 2048 --volume 20 --image \"CentOS 7\"", + Example: "ans ecloud instance create --vpc vpc-abcdef12 --network net-abcdef12 --vcpu 2 --ram 2048 --volume 20 --image \"CentOS 7\"", RunE: ecloudCobraRunEFunc(f, ecloudInstanceCreate), } @@ -135,6 +135,7 @@ func ecloudInstanceCreateCmd(f factory.ClientFactory) *cobra.Command { cmd.Flags().StringSlice("ssh-key-pair", []string{}, "ID of SSH key pair, can be repeated") cmd.Flags().String("host-group", "", "ID of host group to deploy to") cmd.Flags().String("resource-tier", "", "ID of resource tier to deploy to. A default tier is chosen if not specified") + cmd.Flags().String("ip-address", "", "IP address to allocate for DHCP") cmd.Flags().Bool("wait", false, "Specifies that the command should wait until the instance has been completely created") return cmd @@ -155,6 +156,11 @@ func ecloudInstanceCreate(service ecloud.ECloudService, cmd *cobra.Command, args createRequest.SSHKeyPairIDs, _ = cmd.Flags().GetStringSlice("ssh-key-pair") } + if cmd.Flags().Changed("ip-address") { + ipAddress, _ := cmd.Flags().GetString("ip-address") + createRequest.CustomIPAddress = connection.IPAddress(ipAddress) + } + imageFlag, _ := cmd.Flags().GetString("image") if strings.HasPrefix(imageFlag, "img-") { diff --git a/go.mod b/go.mod index 26c0237..52f4e30 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/ans-group/cli go 1.18 require ( - github.com/ans-group/sdk-go v1.16.0 + github.com/ans-group/sdk-go v1.16.1 github.com/blang/semver v3.5.1+incompatible github.com/golang/mock v1.6.0 github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334 diff --git a/go.sum b/go.sum index c581cff..76ad9b7 100644 --- a/go.sum +++ b/go.sum @@ -40,8 +40,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ans-group/go-durationstring v1.2.0 h1:UJIuQATkp0t1rBvZsHRwki33YHV9E+Ulro+3NbMB7MM= github.com/ans-group/go-durationstring v1.2.0/go.mod h1:QGF9Mdpq9058QXaut8r55QWu6lcHX6i/GvF1PZVkV6o= -github.com/ans-group/sdk-go v1.16.0 h1:hHJhKaQzP3Kqa/fmrkgxR4HXLuarAYfMs4gVw52o3JQ= -github.com/ans-group/sdk-go v1.16.0/go.mod h1:Wfbz7OFd8SFIJy5Jun6AsrBnoUv9tp6H1DJhaKU01es= +github.com/ans-group/sdk-go v1.16.1 h1:6yjfc4BC1f16Ln9legoMhjlux+wX6ucRN4AhHhIuV6I= +github.com/ans-group/sdk-go v1.16.1/go.mod h1:Wfbz7OFd8SFIJy5Jun6AsrBnoUv9tp6H1DJhaKU01es= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= diff --git a/internal/pkg/config/config.go.disabled b/internal/pkg/config/config.go.disabled deleted file mode 100644 index 71892bd..0000000 --- a/internal/pkg/config/config.go.disabled +++ /dev/null @@ -1,165 +0,0 @@ -package config - -import ( - "errors" - "fmt" - - "github.com/mitchellh/go-homedir" - "github.com/spf13/afero" - "github.com/spf13/viper" -) - -var defaultConfigFile string -var configName = ".ans" -var initialised bool - -// Init initialises the config package -func Init(configPath string) error { - viper.SetEnvPrefix("ans") - viper.AutomaticEnv() - - if len(configPath) > 0 { - viper.SetConfigFile(configPath) - } else { - // Find home directory - home, err := homedir.Dir() - if err != nil { - return err - } - - // Search config in home directory with name ".ans" (without extension) - viper.AddConfigPath(home) - viper.SetConfigName(configName) - defaultConfigFile = fmt.Sprintf("%s/%s.yml", home, configName) - } - - // If a config file is found, read it in - err := viper.ReadInConfig() - if len(configPath) > 0 && err != nil { - return fmt.Errorf("Failed to read config from file '%s': %s", configPath, err.Error()) - } - - initialised = true - - return nil -} - -// Save saves the config to configured config file (or default) -func Save() error { - if !initialised { - return errors.New("Config not initialised") - } - - configFile := viper.ConfigFileUsed() - if len(configFile) < 1 { - configFile = defaultConfigFile - } - - return viper.WriteConfigAs(configFile) -} - -// SetFs sets the filesystem instance to use -func SetFs(fs afero.Fs) { - viper.SetFs(fs) -} - -// GetCurrentContextName returns the name of the current context -func GetCurrentContextName() string { - return viper.GetString("current_context") -} - -func GetContextNames() []string { - var contextNames []string - contexts := viper.GetStringMap(getContextBaseKey()) - for contextName := range contexts { - contextNames = append(contextNames, contextName) - } - - return contextNames -} - -func getContextKeyOrDefault(contextName string, key string) string { - if len(contextName) > 0 { - return getContextSubKey(contextName, key) - } - - return key -} - -func getCurrentContextKeyIfSetOrDefault(key string) string { - return getContextKeyIfSetOrDefault(GetCurrentContextName(), key) -} - -func getContextKeyIfSetOrDefault(contextName string, key string) string { - if len(contextName) > 0 { - contextSubKey := getContextSubKey(contextName, key) - if viper.IsSet(contextSubKey) { - return contextSubKey - } - } - - return key -} - -func getContextBaseKey() string { - return "contexts" -} - -func getContextKey(name string) string { - return fmt.Sprintf("%s.%s", getContextBaseKey(), name) -} - -func getContextSubKey(name string, key string) string { - return fmt.Sprintf("%s.%s", getContextKey(name), key) -} - -func SetCurrentContext(key string, value any) error { - contextName := GetCurrentContextName() - if len(contextName) < 1 { - return errors.New("current context not set") - } - - Set(contextName, key, value) - return nil -} - -func Set(contextName string, key string, value any) { - viper.Set(getContextKeyOrDefault(contextName, key), value) -} - -func SetDefault(contextName string, key string, value any) { - viper.SetDefault(getContextKeyOrDefault(contextName, key), value) -} - -func SwitchCurrentContext(contextName string) error { - if !ContextExists(contextName) { - return fmt.Errorf("context not defined with name '%s'", contextName) - } - - viper.Set("current_context", contextName) - return nil -} - -func ContextExists(contextName string) bool { - return viper.IsSet(getContextKey(contextName)) -} - -func Reset() { - viper.Reset() -} - -func GetString(key string) string { - return viper.GetString(getCurrentContextKeyIfSetOrDefault(key)) -} - -func GetInt(key string) int { - return viper.GetInt(getCurrentContextKeyIfSetOrDefault(key)) -} - -func GetBool(key string) bool { - return viper.GetBool(getCurrentContextKeyIfSetOrDefault(key)) -} - -func GetStringMapString(key string) map[string]string { - return viper.GetStringMapString(getCurrentContextKeyIfSetOrDefault(key)) -} diff --git a/internal/pkg/config/config_test.go.disabled b/internal/pkg/config/config_test.go.disabled deleted file mode 100644 index 29a7b70..0000000 --- a/internal/pkg/config/config_test.go.disabled +++ /dev/null @@ -1,253 +0,0 @@ -package config - -import ( - "testing" - - "github.com/spf13/afero" - "github.com/stretchr/testify/assert" -) - -var defaultConfig = `contexts: - testcontext1: - somekey: somevalue - testcontext2: - somekey: somevalue -current_context: testcontext1 -` - -func TestInit(t *testing.T) { - t.Run("ReadsConfigFile", func(t *testing.T) { - defer Reset() - fs := afero.NewMemMapFs() - SetFs(fs) - - afero.WriteFile(fs, "/tmp/testconfig.yml", []byte(`testconfig: - somekey: somevalue -`), 0644) - - Init("/tmp/testconfig.yml") - someKey := GetString("testconfig.somekey") - - assert.Equal(t, "somevalue", someKey) - }) - - t.Run("ReturnsErrorConfigNotFound", func(t *testing.T) { - defer Reset() - fs := afero.NewMemMapFs() - SetFs(fs) - - err := Init("/tmp/testconfig.yml") - - assert.NotNil(t, err) - }) -} - -func TestSave(t *testing.T) { - t.Run("SavesToDefinedConfig", func(t *testing.T) { - defer Reset() - fs := afero.NewMemMapFs() - SetFs(fs) - - afero.WriteFile(fs, "/tmp/testconfig.yml", []byte(`contexts: - somecontext: - somekey: somevalue -`), 0644) - - Init("/tmp/testconfig.yml") - Set("somecontext", "somekey", "newvalue") - Save() - - content, _ := afero.ReadFile(fs, "/tmp/testconfig.yml") - - expected := `contexts: - somecontext: - somekey: newvalue -` - - assert.Equal(t, expected, string(content)) - }) - - t.Run("SavesToDefaultConfig", func(t *testing.T) { - defer Reset() - fs := afero.NewMemMapFs() - SetFs(fs) - - Init("") - defaultConfigFile = "/tmp/defaultconfig.yml" - Set("somecontext", "somekey", "newvalue") - Save() - - content, _ := afero.ReadFile(fs, defaultConfigFile) - - expected := `contexts: - somecontext: - somekey: newvalue -` - - assert.Equal(t, expected, string(content)) - }) - - t.Run("ReturnsErrorWhenNotInitialised", func(t *testing.T) { - defer Reset() - initialised = false - err := Save() - assert.NotNil(t, err) - }) -} - -func TestGetCurrentContextName(t *testing.T) { - defer Reset() - fs := afero.NewMemMapFs() - SetFs(fs) - - afero.WriteFile(fs, "/tmp/testconfig.yml", []byte("current_context: testcontext"), 0644) - - Init("/tmp/testconfig.yml") - - currentContext := GetCurrentContextName() - - assert.Equal(t, "testcontext", currentContext) -} - -func TestGetContextNames(t *testing.T) { - defer Reset() - fs := afero.NewMemMapFs() - SetFs(fs) - - afero.WriteFile(fs, "/tmp/testconfig.yml", []byte(`contexts: - testcontext1: - somekey: somevalue - testcontext2: - somekey: somevalue -`), 0644) - - Init("/tmp/testconfig.yml") - - contexts := GetContextNames() - - assert.Contains(t, contexts, "testcontext1") - assert.Contains(t, contexts, "testcontext2") -} - -func TestSetCurrentContext(t *testing.T) { - t.Run("SetsCurrentContextValue", func(t *testing.T) { - defer Reset() - fs := afero.NewMemMapFs() - SetFs(fs) - - afero.WriteFile(fs, "/tmp/testconfig.yml", []byte(defaultConfig), 0644) - - Init("/tmp/testconfig.yml") - - SetCurrentContext("somekey", "somenewvalue") - value := GetString("somekey") - - assert.Equal(t, "somenewvalue", value) - }) - - t.Run("CurrentContextNotSetReturnsError", func(t *testing.T) { - defer Reset() - err := SetCurrentContext("somekey", "somenewvalue") - - assert.NotNil(t, err) - }) -} - -func TestSet(t *testing.T) { - t.Run("SetsContextValue", func(t *testing.T) { - defer Reset() - fs := afero.NewMemMapFs() - SetFs(fs) - - afero.WriteFile(fs, "/tmp/testconfig.yml", []byte(defaultConfig), 0644) - - Init("/tmp/testconfig.yml") - - Set("testcontext1", "somekey", "somenewvalue") - value := GetString("somekey") - - assert.Equal(t, "somenewvalue", value) - }) - - t.Run("SetsDefaultValue", func(t *testing.T) { - defer Reset() - fs := afero.NewMemMapFs() - SetFs(fs) - - afero.WriteFile(fs, "/tmp/testconfig.yml", []byte(defaultConfig), 0644) - - Init("/tmp/testconfig.yml") - - Set("", "somekey", "somenewvalue") - value := GetString("somekey") - - Set("", "current_context", "") - defaultValue := GetString("somekey") - - assert.Equal(t, "somevalue", value) - assert.Equal(t, "somenewvalue", defaultValue) - }) -} - -func TestSwitchCurrentContext(t *testing.T) { - defer Reset() - fs := afero.NewMemMapFs() - SetFs(fs) - - afero.WriteFile(fs, "/tmp/testconfig.yml", []byte(defaultConfig), 0644) - - Init("/tmp/testconfig.yml") - - SwitchCurrentContext("testcontext2") - currentContext := GetCurrentContextName() - - assert.Equal(t, "testcontext2", currentContext) -} - -func TestGet(t *testing.T) { - t.Run("GetsContextValueWhenExists", func(t *testing.T) { - defer Reset() - fs := afero.NewMemMapFs() - SetFs(fs) - - var config = `contexts: - testcontext1: - somekey: somevalue1 - testcontext2: - somekey: somevalue2 -current_context: testcontext1 -somekey: someothervalue -` - - afero.WriteFile(fs, "/tmp/testconfig.yml", []byte(config), 0644) - - Init("/tmp/testconfig.yml") - - value := GetString("somekey") - - assert.Equal(t, "somevalue1", value) - }) - - t.Run("GetsDefaultValueWhenNotExistInContext", func(t *testing.T) { - defer Reset() - fs := afero.NewMemMapFs() - SetFs(fs) - - var config = `contexts: - testcontext1: - somekey: somevalue1 - testcontext2: - somekey: somevalue2 -current_context: testcontext1 -someotherkey: someothervalue -` - - afero.WriteFile(fs, "/tmp/testconfig.yml", []byte(config), 0644) - - Init("/tmp/testconfig.yml") - - value := GetString("someotherkey") - - assert.Equal(t, "someothervalue", value) - }) -}